前面的文章讲到了比特币里的矿工都在做什么(比特币里的矿工到底在干嘛?区块链伪技术简介(一)),今天我们通过一个简单的例子,来给大家直观的感受一下矿工的所谓“工作”,除了费电以外,具体是在干嘛。
我们先来看一下区块链的一个简化模型。
区块链的四个基础特征分别是:不可篡改,不可复制的唯一性,智能合约,去中心化。这里面不可篡改、不可复制的唯一性都与区块链结构中的哈希(Hash)算法紧密关联。
我们知道,哈希算法的特点就是,如果内容稍加改动,则得出的哈希值就会具有极大的差异。因此,在上图的链式结构中,如果我们改动了区块1中的数据,那么由于其哈希值是从数据中得来的,所以哈希值必然发生变化,而这个区块的哈希值变化了,它后面的区块就都要改。而如果这条链特别长了,那么修改的成本也就很高,接近不可能。
那么我们就写段Python代码来实现一下上图这个区块。
首先我们写一个区块类,代码如下:
class Block:
blockNo = 0
data = None
next = None
hash = None
nonce = 0
previous_hash = 0x0
timestamp = datetime.datetime.now()
def __init__(self, data):
self.data = data
def hash(self):
h = hashlib.sha256()
h.update(
str(self.nonce).encode('utf-8')
str(self.data).encode('utf-8')
str(self.previous_hash).encode('utf-8')
str(self.timestamp).encode('utf-8')
str(self.blockNo).encode('utf-8')
)
return h.hexdigest()
def __str__(self):
return "Block Hash: " str(self.hash()) "\nBlockNo: " str(self.blockNo) "\nBlock Data: " str(
self.data) "\nHashes: " str(self.nonce) "\n--------------"
我们可以看到,其哈希值产生于数据,前一区块哈希值,随机数,当前时间和区块号,这里面任何一个数据发生变化,哈希值就会变化。这个类里最主要的就是这个哈希生成算法,其它的都很简单。
接下来我们再写一个区块链的链表类,代码如下:
class Blockchain:
diff = 20
maxNonce = 2 ** 32
target = 2 ** (256 - diff)
block = Block("Genesis")
dummy = head = block
def add(self, block):
block.previous_hash = self.block.hash()
block.blockNo = self.block.blockNo 1
self.block.next = block
self.block = self.block.next
def mine(self, block):
for n in range(self.maxNonce):
print(n)
# if (random.randint(1, 10) <2):
# self.add(block)
# print(block)
# break
if int(block.hash(), 16) <= self.target:
self.add(block)
print(block)
break
else:
block.nonce = 1
这里面主要有两个函数,一个是将新区块加到链上的函数add,另一个是挖矿函数mine,这个函数就是矿工主要在做的所谓“工作”,它决定了新的区块是如何产生的。
我们看到,在一个循环里,实际挖矿的时候也可能是while(true),如果发现了一个区块达到了某个限定条件,在上面的代码中,执行的代码是int(block.hash(), 16) <= self.target,这个就比较难达到。注释掉的代码是random.randint(1, 10) <2,这个条件相对就好达到,在比特币等空气币里,条件要比这个难一些,而且难度是可调的,以保证大约十分钟左右生成一个新的区块。
通过以上的代码,我们就实现了一个简单的区块链,也让大家看到了矿工的所谓“工作”,就是想办法达到一个或难或易的算法条件。
最后我们写段代码执行一下这个简单的区块,代码如下:
blockchain = Blockchain()
for n in range(5):
blockchain.mine(Block("Block " str(n 1)))
while blockchain.head != None:
print(blockchain.head)
blockchain.head = blockchain.head.next
结果如下:
喜欢本文的话,欢迎关注活在信息时代哦:)