python区块链框架_20分钟,我用Python实现区块链架构!
文章目錄區塊鏈到底多神奇
一起動手創建一個極簡的區塊鏈
為“瘦小的”區塊鏈“增肥”
添加POW共識算法
開采新的區塊測試
零基礎Python實現區塊鏈架構視頻觀看地址
區塊鏈到底多神奇
這是篇技術文,我們會用Python一步步搭建一個完整的區塊鏈。不過,在此之前,咱們還是先說說你什么你該學習如何從零搭建一個區塊鏈
我們可以把區塊鏈看做一個公共數據庫,其中新數據存儲在一個稱為區塊的容器中,然后被添加到一條不可更改的鏈上(也就是區塊鏈),同時,鏈上保存著之前的數據記錄。這些數據是比特幣或其他加密貨幣之前的交易信息,被分門別類地添加到鏈上
區塊鏈的誕生,引發了以比特幣和萊特幣為首的加密貨幣的崛起。由于加密貨幣的去中心化屬性。對于那些本來就不信任銀行系統的人來說,簡直是帶來了新世界。此外,區塊鏈還給分布式計算帶來了革新,出現了很多諸如以太坊這樣的新平臺,也引入了智能合約的概念
俗話說實踐出真知。接下來,我將用不超過50行的 Python 代碼創建一個簡單的區塊鏈,并給它取了一個名字 SmartCoin。以此幫助大家理解區塊鏈。
一起動手創建一個極簡的區塊鏈
首先,我們先對區塊鏈進行定義。在區塊鏈中,每個區塊上都有一個時間戳,有時還會有一個索引。在SmartCoin中,我們兩個都有。同時,為了保證整個區塊鏈的完整性,每一個區塊都有一個唯一的哈希值,用于自我標識。比如比特幣,每一個區塊的哈希值是由區塊的索引、時間戳、數據以及前一個區塊的哈希,經過加密后得到的。其中,數據可以選取任意值。下面來看看定義區塊的代碼:
區塊鏈到底多神奇
import hashlib as hasher
class Block:
def __init__(self, index, timestamp, data, previous_hash):
self.index = index
self.timestamp = timestamp
self.data = data
self.previous_hash = previous_hash
self.hash = self.hash_block()
def hash_block(self):
sha = hasher.sha256()
sha.update(str(self.index) +
str(self.timestamp) +
str(self.data) +
str(self.previous_hash))
return sha.hexdigest()
完成了!區塊鏈的基本框架就這樣搭建出來了。考慮到我們要做的是「區塊鏈」,因此,我們還需要往鏈上加區塊。我之前提到過,其中每一個區塊需要包含鏈上前一個區塊的哈希值。你可能會問,區塊鏈的第一個區塊是怎么出現的呢??當然,作為第一個區塊(也叫創世區塊),自然很特殊。在多數情況下,它是手動地被添加到鏈上,或者通過獨特的邏輯將它添加到鏈上。
下面,我們就簡單一點,通過創建一個函數,讓它返回一個創世區塊。這個區塊的索引為0,此外,它所包含的數據以及前一個區塊的哈希值都是一個任意的值。創建創世區塊的函數代碼如下:
import datetime as date
def create_genesis_block():
# Manually construct ablock with
# index zero andarbitrary previous hash
return Block(0, date.datetime.now(), "GenesisBlock", "0")
這樣,創世區塊已經創建好了,我們還需要一個函數來生成鏈上更多的區塊。該函數將鏈上前一個區塊作為參數,為后面的區塊生成數據,并返回具有帶有數據的新區塊。當生成的新區塊包含了前一個區塊的哈希值,區塊鏈的完整性就會隨著每個區塊的增加而增加這樣的操作雖然看起來有點復雜,但如果不這么做,其他人就會很容易篡改鏈上的數據,甚至把整條鏈都給換了。所以,鏈上區塊的哈希值就充當了密碼證明,確保區塊一旦被添加到區塊鏈上,就不能被替換或者刪除。下面是這個函數的代碼:
def next_block(last_block):
this_index =last_block.index + 1
this_timestamp =date.datetime.now()
this_data = "Hey! I'm block " +str(this_index)
this_hash = last_block.hash
returnBlock(this_index, this_timestamp, this_data, this_hash)
到這里,一個簡單的區塊鏈就基本完成了!今天的的例子中我們通過Python列表來創建區塊鏈,其中最重要的部分是創世區塊(當然,還需要其他區塊)。因為我們要創建的SmartCoin是一個比較簡單的區塊鏈,所以我會通過循環的方式,只添加20個新的后續區塊。具體實現如下:
# Create the blockchain and add the genesis block
blockchain = [create_genesis_block()]
previous_block = blockchain[0]
# How many blocks should we add to the chain
#after the genesis block
num_of_blocks_to_add= 20
# Addblocks to the chain
for iin range(0, num_of_blocks_to_add):
block_to_add= next_block(previous_block)
blockchain.append(block_to_add)
previous_block = block_to_add
# Telleveryone about it!
print "Block #{} has been added to theblockchain!".format(block_to_add.index)
print "Hash:{}\n".format(block_to_add.hash)
上面講到的區塊鏈是非常簡潔的,區塊的創造也相對簡單。但是如果要使SmartCoin成為一個真正的加密貨幣,我們需要控制每次產出的區塊數量和幣的數量。
為“瘦小的”區塊鏈“增肥”
SmartCoin上的數據從交易中產生,每個區塊上的數據均由一系列交易組成。我們將交易定義為:每筆交易均為一個JSON對象,這個JSON對象包括幣的發送者、接受者和交易數量。
注意:下文我們會談到為什么交易是以JSON格式保存的。
{
"from":"71238uqirbfh894-random-public-key-a-alkjdflakjfewn204ij",
"to":"93j4ivnqiopvh43-random-public-key-b-qjrgvnoeirbnferinfo",
"amount": 3
}
在了解了什么是交易之后,我們需要一個方法,將交易添加到之前的區塊鏈網絡節點中(這些節點由普通的電腦組成),為此,我們將創造一個簡單的HTTP服務器,便于交易用戶將交易信息上報節點。一個節點能夠接收一個帶有交易信息的POST請求來作為請求主體。這就是為什么交易是JSON格式的原因。我們需要將它們傳送到服務器的請求主體中。
首先需要安裝一個網絡服務器框架:
from flask import Flask
from flask import request
node = Flask(__name__)
# Store the transactions that
# this node has in a list
this_nodes_transactions = []
@node.route('/txion',methods=['POST'])
def transaction():
if request.method == 'POST':
# On each new POST request,
# we extract the transaction data
new_txion = request.get_json()
# Then we add the transaction to our list
this_nodes_transactions.append(new_txion)
# Because the transaction was successfully
# submitted, we log it to our console
print "New transaction"
print "FROM:{}".format(new_txion['from'])
print "TO:{}".format(new_txion['to'])
print "AMOUNT:{}\n".format(new_txion['amount'])
# Then we let the client know it worked out
return "Transaction submissionsuccessful\n"
node.run()
這樣我們就完成了對用戶間互相發送SmartCoin信息的保存。這就是為什么大家將區塊鏈稱為公共賬本和分布式賬本的原因:所有交易存儲在網絡內的每個節點之中,重要的是,對所有用戶是可見的。
添加POW共識算法
但是,問題來了,我們從哪里獲取SmartCoin呢?(目前)哪兒都不行!實際上SmartCoin是不存在的。我們需要挖掘新的SmartCoin區塊把它創造出來,一個新的區塊被挖出后,一個SmartCoin就會產生出來,作為獎勵給與挖礦者。礦工將SmartCoin轉給其他人之后,幣就開始流通了。
我們不希望挖出SmartCoin的過程過于簡單,因為會產生太多的SmartCoin,而且會變得越來越不值錢。同時,我們也不希望這個過程特別難,因為這樣的話,SmartCoin的數量不足,這會導致幣價過高,同時流通緩慢。我們通過工作量證明算法控制挖礦的難度。工作證明算法本質上是生成一種難以創建但易于驗證的算法。就像字面意思一樣,它就是證明一個節點(計算機)完成了多少工作量。
在SmartCoin中,我們要創建的是一個簡單的PoW算法。要創建一個新的區塊,礦工的電腦需要增加一個數字。當該數字可被9(“SmartCoin”中的字母數)和最后一個區塊的證明編號整除時,一個新的SmartCoin區塊就會被開采出來,礦工也會得到一個SmartCoin作為獎勵
# ...blockchain
# ...Block class definition
miner_address ="q3nf394hjg-random-miner-address-34nf3i4nflkn3oi"
def proof_of_work(last_proof):
# Create a variable that wewill use to find
# our next proof of work
incrementor = last_proof + 1
# Keep incrementing the incrementor until
# it's equal to a number divisible by 9
# and the proof of work of the previous
# block in the chain
while not (incrementor % 9 == 0 andincrementor % last_proof == 0):
incrementor += 1
# Once that number is found,
# we can return it as a proof
# of our work
return incrementor
@node.route('/mine', methods =['GET'])
def mine():
# Get the last proof of work
last_block = blockchain[len(blockchain) - 1]
last_proof = last_block.data['proof-of-work']
# Find the proof of work for
# the current block being mined
# Note: The program will hang here until a new
#????? proof of work is found
proof = proof_of_work(last_proof)
# Once we find a valid proof of work,
# we know we can mine a blockso
# we reward the miner by addinga transaction
this_nodes_transactions.append(
{ "from":"network", "to": miner_address, "amount": 1 }
)
# Now we can gather the dataneeded
# to create the new block
new_block_data = {
"proof-of-work":proof,
"transactions":list(this_nodes_transactions)
}
new_block_index = last_block.index + 1
new_block_timestamp = this_timestamp =date.datetime.now()
last_block_hash = last_block.hash
# Empty transaction list
this_nodes_transactions[:] = []
# Now create the
# new block!
mined_block = Block(
new_block_index,
new_block_timestamp,
new_block_data,
last_block_hash
)
blockchain.append(mined_block)
# Let the client know we mined a block
return json.dumps({
"index":new_block_index,
"timestamp":str(new_block_timestamp),
"data": new_block_data,
"hash": last_block_hash
}) + "\n"
現在,我們可以控制在一個特定時間段內可開采的區塊數量,到這里,我們就可以自由掌握一定時間內多少個區塊可以被開發出來了。但是就像前面所說的,這一切操作只是在一個節點上進行的。但區塊鏈應該是去中心的,我們怎么保證這條鏈在其他節點上也是一樣的呢?我們可以讓每個節點對外廣播自己鏈的版本,其他節點既可以接收廣播,又可以自己對外廣播同樣的內容。此后,每個節點需要去對其他節點所發出的信息進行驗證,驗證通過后,網絡上的所有節點則可以達成一致。這稱為一致性算法。
在這個例子中,我們所采用的一致性算法相當簡單:如果一個節點的鏈與其他節點的鏈不同(即有爭議時),那么網絡上最長的鏈會保留而較短的鏈將會被刪除,如果所有節點都達成一致,那么則進行下一步:
@node.route('/blocks',methods=['GET'])
def get_blocks():
chain_to_send = blockchain
# Convert our blocks into dictionaries
# so we can send them as json objects later
for block in chain_to_send:
block_index = str(block.index)
block_timestamp =str(block.timestamp)
block_data = str(block.data)
block_hash = block.hash
block = {
"index": block_index,
"timestamp": block_timestamp,
"data": block_data,
"hash": block_hash
}
# Send our chain to whomever requested it
chain_to_send = json.dumps(chain_to_send)
return chain_to_send
def find_new_chains():
# Get the blockchains of every
# other node
other_chains = []
for node_url in peer_nodes:
# Get their chains using a GETrequest
block = requests.get(node_url +"/blocks").content
# Convert the JSON object to aPython dictionary
block = json.loads(block)
# Add it to our list
other_chains.append(block)
return other_chains
def consensus():
# Get the blocks from other nodes
other_chains =find_new_chains()
# If our chain isn't longest,
# then we store the longest chain
longest_chain = blockchain
for chain in other_chains:
if len(longest_chain) < len(chain):
longest_chain = chain
# If the longest chain wasn't ours,
# then we set our chain to the longest
blockchain = longest_chain
開采新的區塊測試
在這一步中,我們會運行完整的SmartCoin服務器代碼,到這里我們離大功告成就只差一步了。運行完SmartCoin的代碼后,在終端里運行以下命令(假設你用的是cURL)。創建一個交易
curl"localhost:5000/txion" \
-H "Content-Type:application/json" \
-d '{"from": "akjflw","to":"fjlakdj", "amount": 3}'
2.開采新的區塊
curl localhost:5000/mine
3.查看結果。我們通過客戶端窗口看這個
{
"index": 2,
"data": {
"transactions": [
{
"to": "fjlakdj",
"amount": 3,
"from": "akjflw"
},
{
"to":"q3nf394hjg-random-miner-address-34nf3i4nflkn3oi",
"amount": 1,
"from": "network"
}
],
"proof-of-work": 36
},
"hash": "151edd3ef6af2e7eb8272245cb8ea91b4ecfc3e60af22d8518ef0bba8b4a6b18",
"timestamp": "2017-07-2311:23:10.140996"
}
大功告成! 我們自己創建了一條完整的區塊鏈!現在 SmartCoin可以在多臺節點上運行,SmartCoin也可以被開采了。
零基礎Python實現區塊鏈架構視頻觀看地址
視頻觀看地址:https://study.163.com/course/introduction/1005810016.htm
總結
以上是生活随笔為你收集整理的python区块链框架_20分钟,我用Python实现区块链架构!的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java stringutils_Jav
- 下一篇: Linux格式化sd卡博客,linux设