概念
對于單向散列函數,輸出是不可知的。但在假設輸出結果是随機平均分布的情況下,可以預先計算出特定範圍的結果的可能性,推導要計算出滿足特定條件的結果所花費的工作量。
在比特币的區塊鍊實作中,POW是一種保護區塊鍊網絡,維持通貨穩定的手段。因為對比特币來說,一個非常重要的原則是維持每10分鐘生成一個區塊。新的通貨隻會從新區塊的第一個交易(coinbase transaction)産生。如此,維持區塊的生成頻率就是維持通貨的穩定。
比特币區塊頭部會有一個字段Target和一個字段nonce(最後一個字段)。簡單來說,POW就是通過改變nonce字段,使得區塊頭部的散列值在數值上小于Target字段。通過設定特殊的Target值,使得調整nonce以得出滿足條件的散列值這一過程的平均時間為10分鐘。而隻有區塊頭部散列值在數值上小于Target的區塊,才會被視為是有效的區塊。
target
關于target的格式,前2位16進制數為指數(exponent),後6位16進制數是系數(coefficient)。
計算出實際的Target的公式為:
Target = coefficient * 2 ^ (8 * (exponent - 3))
retargeting
每10分鐘建立一個區塊是比特币的核心原則,保證通貨發行的穩定性。随着礦機的性能的提高,Target也需要周期性的調整以維持該原則,保證比特币的穩定。
比特币的每個節點會每隔2016個區塊重新調整一次target,以維持每10分鐘生成一個區塊的原則。
調整公式為:
新Target = 舊Target * (前2016個區塊所花費的時間 / 20160 分)
實作
#! /usr/bin/env python
# example of proof-of-work algorithm
import hashlib
import time
max_nonce = ** # 4 billion
def proof_of_work(header, difficulty_bits):
# calculate the difficulty target
target = ** ( - difficulty_bits)
for nonce in xrange(max_nonce):
hash_result = hashlib.sha256(str(header) + str(nonce)).hexdigest()
# check if this is a valid result, below the target
if long(hash_result, ) < target:
print "Success with nonce %d" % nonce
print "Hash is %s" % hash_result
return (hash_result, nonce)
print "Failed after %d (max_nonce) tries" % nonce
return nonce
if __name__ == '__main__':
nonce =
hash_result = ''
# difficulty from 0 to 31 bits
for difficulty_bits in xrange():
difficulty = ** difficulty_bits
print "Difficulty: %ld (%d bits)" % (difficulty, difficulty_bits)
print "Starting search..."
# checkpoint the current time
start_time = time.time()
# make a new block which includes the hash from the previous block
# we fake a block of transactions - just a string
new_block = 'test block with transactions' + hash_result
# find a valid nonce for the new block
(hash_result, nonce) = proof_of_work(new_block, difficulty_bits)
# checkpoint how long it took to find a result
end_time = time.time()
elapsed_time = end_time - start_time
print "Elapsed Time: %.4f seconds" % elapsed_time
if elapsed_time > :
# estimate the hashes per second
hash_power = float(long(nonce)/elapsed_time)
print "Hashing Power: %ld hashes per second" % hash_power