目錄
用python構(gòu)建區(qū)塊鏈(1)---基本結(jié)構(gòu)
用python構(gòu)建區(qū)塊鏈(2)---工作量證明共識(shí)算法(pow)
背景
比特幣從誕生到現(xiàn)在已經(jīng)10年了,最近一段時(shí)間因?yàn)楣ぷ髟蚪佑|到了區(qū)塊鏈相關(guān)的技術(shù),為了揭開其背后的神秘面紗,我們就從頭開始構(gòu)建一個(gè)簡單的區(qū)塊鏈尸饺。在行動(dòng)之前我們先看一下比特幣的整體結(jié)構(gòu).
比特幣內(nèi)部結(jié)構(gòu)
可以看到比特幣主要有四個(gè)部分
- previous hash(前一個(gè)區(qū)塊的hash)
- merkle root(默克爾樹根節(jié)點(diǎn),內(nèi)部存儲(chǔ)交易數(shù)據(jù))
- timestamp(當(dāng)前區(qū)塊生成的時(shí)間)
- nonce(曠工計(jì)算hash值次數(shù))
我們實(shí)現(xiàn)的區(qū)塊鏈數(shù)據(jù)結(jié)構(gòu)(簡單實(shí)現(xiàn)并不完整)
- index 當(dāng)前第幾個(gè)區(qū)塊
- timestamp 該區(qū)塊創(chuàng)建時(shí)的時(shí)間戳
- data 交易信息
- previousHash 前一個(gè)區(qū)塊的hash
- hash 當(dāng)前區(qū)塊的hash
注意點(diǎn)
- 第一個(gè)區(qū)塊叫做創(chuàng)世區(qū)塊(genesis block),區(qū)塊鏈創(chuàng)建的時(shí)候默認(rèn)生產(chǎn)的
- 這里用的是單純的鏈表,不是用默克爾樹存儲(chǔ)
coding
from hashlib import sha256
//區(qū)塊schema
class Block:
def __init__(self,index,timestamp,data,previousHash=""):
self.index = index
self.timestamp = timestamp
self.data = data
self.previousHash = previousHash
self.hash = self.calculateHash()
//計(jì)算當(dāng)前區(qū)塊的hash值
def calculateHash(self):
plainData = str(self.index)+str(self.timestamp)+str(self.data)
return sha256(plainData.encode('utf-8')).hexdigest()
def __str__(self):
return str(self.__dict__)
//區(qū)塊鏈schema
class BlockChain:
//初始化的時(shí)候 創(chuàng)建 創(chuàng)世區(qū)塊
def __init__(self):
self.chain = [self.createGenesisBlock()]
//構(gòu)建創(chuàng)世區(qū)塊
def createGenesisBlock(self):
return Block(0,"01/01/2018","genesis block","0")
//獲取最后一個(gè)區(qū)塊
def getLatestBlock(self):
return self.chain[len(self.chain)-1]
//往區(qū)塊鏈里面添加區(qū)塊
def addBlock(self,newBlock):
newBlock.previousHash = self.getLatestBlock().hash
newBlock.hash = newBlock.calculateHash()
self.chain.append(newBlock)
def __str__(self):
return str(self.__dict__)
//校驗(yàn)區(qū)塊鏈?zhǔn)遣皇怯行У?有沒有人被篡改
def chainIsValid(self):
for index in range(1,len(self.chain)):
currentBlock = self.chain[index]
previousBlock = self.chain[index-1]
if (currentBlock.hash != currentBlock.calculateHash()):
return False
if previousBlock.hash != currentBlock.previousHash:
return False
return True
myCoin = BlockChain()
myCoin.addBlock(Block(1,"02/01/2018","{amount:4}"))
myCoin.addBlock(Block(2,"03/01/2018","{amount:5}"))
#print block info 打印區(qū)塊鏈信息
print("print block info ####:")
for block in myCoin.chain:
print(block)
#check blockchain is valid 檢查區(qū)塊鏈?zhǔn)遣皇怯行У?print("before tamper block,blockchain is valid ###")
print(myCoin.chainIsValid())
#tamper the blockinfo 篡改區(qū)塊2的數(shù)據(jù)
myCoin.chain[1].data = "{amount:1002}"
print("after tamper block,blockchain is valid ###")
print(myCoin.chainIsValid())
輸出結(jié)果
print block info ####:
{'index': 0, 'timestamp': '01/01/2018', 'data': 'genesis block', 'previousHash': '0', 'hash': 'd8d21e5ba33780d5eb77d09d3b407ceb8ade4e5545ef951de1997b209d91e264'}
{'index': 1, 'timestamp': '02/01/2018', 'data': '{amount:4}', 'previousHash': 'd8d21e5ba33780d5eb77d09d3b407ceb8ade4e5545ef951de1997b209d91e264', 'hash': '15426e32db30f4b26aa719ba5e573f372f41e27e4728eb9e9ab0bea8eae63a9d'}
{'index': 2, 'timestamp': '03/01/2018', 'data': '{amount:5}', 'previousHash': '15426e32db30f4b26aa719ba5e573f372f41e27e4728eb9e9ab0bea8eae63a9d', 'hash': '75119e897f21c769acee6e32abcefc5e88e250a1f35cc95946379436050ac2f0'}
before tamper block,blockchain is valid ###
True
after tamper block,blockchain is valid ###
False