這篇文章主要介紹“區(qū)塊鏈的概念以及用Python的實現(xiàn)方法”,在日常操作中,相信很多人在區(qū)塊鏈的概念以及用Python的實現(xiàn)方法問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”區(qū)塊鏈的概念以及用Python的實現(xiàn)方法”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!
創(chuàng)新互聯(lián)是一家專業(yè)提供大安市企業(yè)網(wǎng)站建設(shè),專注與成都做網(wǎng)站、成都網(wǎng)站設(shè)計、H5高端網(wǎng)站建設(shè)、小程序制作等業(yè)務(wù)。10年已為大安市眾多企業(yè)、政府機構(gòu)等服務(wù)。創(chuàng)新互聯(lián)專業(yè)的建站公司優(yōu)惠進行中。
區(qū)塊鏈幾乎是數(shù)日間成為人盡皆知的名詞,這個名詞也勾起了我強烈的興趣,但是通過在網(wǎng)上搜羅資料,多方閱讀,發(fā)現(xiàn)很多介紹區(qū)塊鏈的文獻要么模棱兩可,要么作者本身的理解也很有限,導致很多關(guān)鍵的問題敘述不清。本人花了一些時間總結(jié)歸納,希望可以給讀者一個比較全面清晰的認識。
區(qū)塊鏈的官方定義是:一個分布式賬本,一種通過去中心化、去信任的方式集體維護一個可靠數(shù)據(jù)庫的技術(shù)方案。那么對于圈外人該如何理解呢?以下我會詳細描述一個區(qū)塊鏈的產(chǎn)生過程和實現(xiàn)意義,從而給大家構(gòu)建出一個清晰的區(qū)塊鏈概念。我們先講原理、再說特點、然后論用途、最后回歸代碼,這樣你就會有一種恍然大悟的感覺。
我們以btc為例:“區(qū)塊鏈”,顧名思義,就是由一個個區(qū)塊依次連接起來組成的鏈條,可以類比為一條無限長度的直線鐵鏈,每個鐵環(huán)就是一個區(qū)塊。那么區(qū)塊的內(nèi)容應(yīng)該是什么呢?區(qū)塊狹義上是有兩種的,一個是普通區(qū)塊,一個就是創(chuàng)世區(qū)塊。創(chuàng)世區(qū)塊就是一項區(qū)塊鏈項目中的第一個區(qū)塊,由于個人水平有限,對創(chuàng)世區(qū)塊沒有做過詳細研究,但是根據(jù)我的了解,創(chuàng)世區(qū)塊應(yīng)該是具備與普通區(qū)塊相似結(jié)構(gòu)的,但會肯定會加入一些創(chuàng)始人想說的東西,并且在有些項目中可能會多一條記錄,就是coin的發(fā)行量,例如swtc的6000億數(shù)目就是寫在創(chuàng)世區(qū)塊之中的,一旦發(fā)行,無法修改。
那么,一個普通區(qū)塊中到底有什么?
1.index:就是從0-n依次產(chǎn)生的數(shù)字,可以稱之為鏈高度。
2.hash:一個長度為256位隨機數(shù),是這個區(qū)塊的唯一編號。
3.previous hash:上一個區(qū)塊的hash,一個普通區(qū)塊有且僅有一個previous hash,這就是區(qū)塊鏈之所以稱為鏈的原因,就是這么一環(huán)套一環(huán)鏈接而成的。
4.tempstamp:用于記錄該區(qū)塊誕生的時間。
5.difficulty:直觀體現(xiàn)創(chuàng)造該區(qū)塊的難度。
6.nonce:隨機數(shù),用于產(chǎn)生下一個區(qū)塊。
上述的都存在區(qū)塊頭中。
7.data:存儲的交易記錄。只有這個存在區(qū)塊體中。
Ok,上述提到了一個區(qū)塊需要具備的最基本的幾條要素,可能你現(xiàn)在還處于一臉懵逼的狀態(tài):這些東西到底是怎么工作的呢?下面我將一步步分析區(qū)塊鏈的工作過程,不過,這里要先問兩個問題:為什么要產(chǎn)生新的區(qū)塊?怎么產(chǎn)生新的區(qū)塊?
之前說了,一個區(qū)塊記錄的就是一份賬單,賬單中存儲著若干條交易記錄,是買賣雙方具體活動的最有力的證明,例如我們在淘寶上的購買記錄,就是我們的消費賬單。人們每天的消費記錄是不斷增長的,不可能永遠放在一個區(qū)塊里,那么跟現(xiàn)在的中心化存儲機制還有什么區(qū)別?所以,隨著買賣記錄的不斷增加,就需要不斷產(chǎn)生新的區(qū)塊來存儲這些數(shù)據(jù)。
我相信,最近除了區(qū)塊鏈這個名詞如雷貫耳以外,“挖礦”應(yīng)該也沒少聽吧。挖礦實際上就是由那些礦工來生成新的區(qū)塊的過程。在btc項目中,btc礦工挖礦成功(其實就是成功的創(chuàng)建了一個區(qū)塊)就可以獲得一定數(shù)量的被btc獎勵,所以btc數(shù)量是在一定范圍內(nèi)慢慢增加的。在一般允許挖礦的區(qū)塊鏈項目(也存在限制coin數(shù)量不允許挖礦的區(qū)塊鏈項目)中,礦工的數(shù)量一般會大于6個,一般超過6個礦工認可的新區(qū)塊就可以加入到區(qū)塊鏈中。到此為止,有人會說:哇!btc這么值錢,挖礦不是很爽?其實不然,如果區(qū)塊無限制的快速增加,會引起很大的問題,根據(jù)中本聰?shù)脑O(shè)定,目前全網(wǎng)每10分鐘只能產(chǎn)生一個新區(qū)塊。而且這10分鐘不是靠自己掐表算的,生成新的區(qū)塊是需要大量的運算的,這10分鐘是人家預先設(shè)計好的,讓計算量大到全網(wǎng)10分鐘一般只能產(chǎn)生一個。
好了,至此,區(qū)塊鏈的基本概念已經(jīng)介紹的差不多了,下面言歸正傳,講下區(qū)塊的工作流程:
1.如果A要和B達成一筆交易,比如A轉(zhuǎn)給B一個btc,B給A打10w的RMB。A首先將自己的btc來源信息、交易人等發(fā)送給B,同時還要拷貝一份發(fā)到全網(wǎng)。什么?這樣還有隱私可言嗎?當然,聰明的中本聰當然不會犯這么低級的錯誤。在區(qū)塊鏈中,每個交易個體(也可以理解為每個網(wǎng)絡(luò)節(jié)點)都會有一對公鑰和私鑰,公鑰相當于一個“收款地址”,而私鑰是一個表明自己身份的256位的數(shù)字,目前一般是用sha265來生成的,這樣,別人并不知道交易的雙方是誰。發(fā)送報文時,發(fā)送方用一個哈希函數(shù)從報文文本中生成報文摘要,然后用自己的私鑰對摘要進行加密,加密后的摘要將作為報文的數(shù)字簽名和報文一起發(fā)送給接收方,接收方首先用與發(fā)送方一樣的哈希函數(shù)從接收到的原始報文中計算出報文摘要,接著再用發(fā)送方的公鑰來對報文附加的數(shù)字簽名進行解密,如果這兩個摘要相同、那么接收方就能確認該數(shù)字簽名是發(fā)送方的。
2.那么此時,這筆交易是否就完成了呢?如果這就算完成了,那跟A直接用包裹裝10w現(xiàn)金快遞給B有什么區(qū)別呢?此時,全網(wǎng)的礦工都會得到這個交易記錄,那么全網(wǎng)的礦工都會為了若干獎勵開始創(chuàng)建區(qū)塊的工作,礦工會利用hash函數(shù)生成一個256位的唯一編號賦予這個區(qū)塊,但是這個編號并不是簡簡單單隨便生成的。編號是根據(jù)區(qū)塊的具體內(nèi)容如交易內(nèi)容、nonce等唯一確定的,換句話說,兩塊內(nèi)容相同的區(qū)塊所對應(yīng)的編號一定是唯一的??墒悄銜枺哼@又怎么了?并不難啊。錯!中本聰為了控制區(qū)塊的生成時間,使區(qū)塊的生成速率滿足全網(wǎng)的每10分鐘一個的標準,制定了嚴格的區(qū)塊生成校驗規(guī)則,也就是說,能不能生成一個成功的區(qū)塊要看你的編號是否符合這個規(guī)則。例如:生成編號中的前n位必須為‘0’。
由于區(qū)塊的交易內(nèi)容是無法修改的,因此礦工們只能通過修改nonce去不斷嘗試這個函數(shù),直到生成了一個成功的區(qū)塊為止。如果當區(qū)塊平均生成時間變快或者變慢,那么系統(tǒng)會對區(qū)塊校驗規(guī)則進行相應(yīng)的調(diào)整,從而使平均的生成時間能夠控制在規(guī)定范圍。
如果一個礦工完成了一個區(qū)塊,會立刻告知其他礦工,如果其他礦工此時沒有完成新的區(qū)塊生成,則會停下手頭的工作,對區(qū)塊進行驗證,需要確認的信息主要有如下幾點:
1).區(qū)塊的編號有效;這個只要將區(qū)塊放入哈希函數(shù)中,看產(chǎn)生的編號是否和該區(qū)塊中的編號一致即可。
2).區(qū)塊的前一個區(qū)塊有效;之前提過,區(qū)塊是一個串聯(lián)的,每一個普通區(qū)塊都會記載前一個區(qū)塊的編號,這需要其他礦工對比當前的區(qū)塊鏈的最后一個區(qū)塊,看是否相同。
3).交易清單有效;就是說要驗證A到底有沒有這一個btc可以給B。在區(qū)塊鏈的交易信息中,會記錄交易中所有btc的前世今生,區(qū)塊鏈可以做到追本溯源,因此每一個btc在哪里,為什么在這里都可以一目了然,所以這點也沒問題。
當驗證完一個全新的區(qū)塊后,全網(wǎng)就會認為這個區(qū)塊有效,會將它添加到現(xiàn)有的區(qū)塊鏈末端,同時結(jié)束針對該區(qū)塊的挖礦工作,投入到下一個挖礦周期中。
3.但是不難想象,這樣的機制是存在沖突的隱患的,就是這么巧,兩個礦工同時制作了一個正確的區(qū)塊,那么此時不必二選一,可以將原來線性的區(qū)塊鏈改成樹狀:
但是這樣會導致未來在A、B后都會增加相應(yīng)的區(qū)塊,那么誰長誰將作為主鏈延伸下去,另一個也許會漸漸被遺忘,除非哪天它變得更長。
好啦,這就是區(qū)塊鏈最基本的知識,接下來應(yīng)該談?wù)剝?yōu)缺點了。
世界上沒有一樣東西可以稱為完美無瑕的,要知道區(qū)塊鏈一樣,雖然它被扣上了可以顛覆未來的帽子,但是仍然存在它的局限性:
1.時效性。很容易發(fā)現(xiàn),區(qū)塊鏈中存在很多的驗證、傳遞環(huán)節(jié),這就會導致其時效性較差。
2、能耗,這點也是顯而易見的,區(qū)塊鏈需要大量無用計算來控制區(qū)塊的生成時間。所以區(qū)塊鏈不適用于高時效的網(wǎng)絡(luò)中。
至于區(qū)塊鏈的優(yōu)點,諸如安全、去中心化等等在網(wǎng)絡(luò)上已經(jīng)描述的非常清楚,這里就不再贅述。接下來我用一段python代碼來簡單實現(xiàn)一個挖礦的流程。
首先創(chuàng)建一個表示區(qū)塊鏈的類:
class BlockChain: def __init__(self, initialHash): # init block chain self.chain = [] # init pitman self.pitmen = [] for i in range(6): self.pitmen.append(Pitman) # collect mine results self.results = [] # generate GenesisBlock self.new_block(initialHash)
初始化函數(shù)中的chain表示當前的區(qū)塊鏈,我會在其中存儲區(qū)塊對象;pitmen表示為這個區(qū)塊鏈服務(wù)的礦工們,這個列表中也會存有礦工對象;results則會存儲每個階段產(chǎn)生的區(qū)塊;new_block方法是創(chuàng)建區(qū)塊的方法,如果當前生成的區(qū)塊為第一個區(qū)塊,則產(chǎn)生創(chuàng)世區(qū)塊。
下面看看區(qū)塊鏈類型的方法:
@property def last_block(self): if len(self.chain): return self.chain[-1] else: return None
last_block會返回當前區(qū)塊鏈的最后一個區(qū)塊對象。
def get_trans(self): return json.dumps({ 'sender': ''.join(random.sample(string.ascii_letters + string.digits, 8)), 'recipient': ''.join(random.sample(string.ascii_letters + string.digits, 8)), 'amount': random.randrange(1, 10000) })
get_trans方法則用來隨機生成一份交易信息。
def new_block(self, initialHash=None): if initialHash: # generate Genesis Block block = Block() block.index = 0 block.nonce = random.randrange(0, 99999) block.previousHash = '0' block.difficulty = 0 block.transactionData = self.get_trans() guess = f'{block.previousHash}{block.nonce}{block.transactionData}'.encode() block.hash = hashlib.sha256(guess).hexdigest() block.time = time() self.chain.append(block) else: for i in range(len(self.pitmen)): pm = MyThread(target=self.pitmen[i].mine, args=(self.pitmen[i], len(self.chain), self.last_block.get_block()['Hash'], self.get_trans())) pm.start() pm.join() self.results.append(pm.get_result()) # show all blocks print("All blocks generated by pitmen:") for result in self.results: print(result[0].get_block()) # get new block firstblock = self.results[0][0] mintime = Decimal(self.results[0][1]) for i in range(1, len(self.results)): if Decimal(self.results[i][1]) < mintime: firstblock = self.results[i][0] else: continue self.chain.append(firstblock) self.results = []
這是生成區(qū)塊的核心部分,這個方法主要分成兩個部分:根據(jù)傳參區(qū)分是否是創(chuàng)世區(qū)塊,如果需要的是創(chuàng)世區(qū)塊,那就由該類型自動生成一個區(qū)塊占據(jù)區(qū)塊鏈的頭一個位置。如果需要生成的是普通區(qū)塊,那么則會將一些基本信息分發(fā)給礦工們進行挖礦操作。我在這里設(shè)置了6個礦工,為了公平起見,這里也開了個多線程盡量讓礦工們同時收到消息從而可以同時進行挖礦操作。按理說,最先挖礦成功的礦工會將消息發(fā)給其他礦工,其他礦工會立刻停止進行校驗,但由于時間有限,這一步校驗環(huán)節(jié)我沒有實現(xiàn)。在這里,我允許所有礦工都完成工作,并提交成果和相應(yīng)的工作時間,生成耗時最短的區(qū)塊講作為正確的區(qū)塊添加到區(qū)塊鏈上。本質(zhì)上也是依照了“快者優(yōu)先”的區(qū)塊鏈生成原則。
class Block: def __init__(self): self.index = None self.time = None self.difficulty = None self.nonce = None self.hash = None self.previousHash = None self.transactionData = None def get_block(self): return { 'Index': self.index, 'Time': self.time, 'Difficulty': self.difficulty, 'Hash': self.hash, 'Nonce': self.nonce, 'PreviousHash': self.previousHash, 'TransactionData': self.transactionData }
我用了一個相對簡單的類型表示區(qū)塊,在這里區(qū)塊就是一個非常簡單的數(shù)據(jù)結(jié)構(gòu),這里的所有字段在上述中已經(jīng)有了詳細的說明,因此不再贅述。
那么我們再看看礦工,畢竟礦工才是區(qū)塊鏈的生產(chǎn)者和推動者,地位最為核心。礦工類中我設(shè)計了兩個方法,一個mine方法,也就是挖礦的意思,用來生成新的區(qū)塊,并會返回該區(qū)塊生成的用時長短。
def mine(self, index, previousHash, transactionData): beginTime = time() block = Block() block.index = index block.previousHash = previousHash block.transactionData = transactionData block.difficulty, block.hash, block.nonce = self.generate_hash(previousHash, transactionData) block.time = time() endTime = time() return block, endTime - beginTime
另一個方法是hash生成的方法,生成原則我自己意淫了一個,大家莫怪,因為本人計算機的實在不給力,區(qū)塊的成功標準很簡單,就是用sha256生成的編碼最后結(jié)尾是0就滿足要求,如果改成00,那會半天看不到結(jié)果。
下面我們看下這套實例的運行結(jié)果,我設(shè)置了一個長度為6的區(qū)塊鏈,由于第一個區(qū)塊是創(chuàng)世區(qū)塊,所以真正開始創(chuàng)建的區(qū)塊是從第二個開始的,大家注意index。
這是6個礦工完成的第一區(qū)塊:
All blocks generated by pitmen: {'Index': 1, 'Time': 1516268156.5971138, 'Difficulty': 2, 'Hash': '01f505a276e3f55a868d9ee18f70bcff75429e1de70f5ab59471a3551cc67a30', 'Nonce': 91554, 'PreviousHash': '7532402844a1c130833a27600298d09a007d6124603cf44be9c05fcd5428c34a', 'TransactionData': '{"sender": "OY8z0Rrx", "recipient": "iSGFJsEm", "amount": 8723}'} {'Index': 1, 'Time': 1516268156.5971138, 'Difficulty': 5, 'Hash': 'c3ba406bad0d87f816f629830a15e2997638bfa230484c224e5470eaa24d8790', 'Nonce': 62372, 'PreviousHash': '7532402844a1c130833a27600298d09a007d6124603cf44be9c05fcd5428c34a', 'TransactionData': '{"sender": "9o8UMDLe", "recipient": "qTOQu7kv", "amount": 2746}'} {'Index': 1, 'Time': 1516268156.5981123, 'Difficulty': 5, 'Hash': '8ff243885e9017296aa2ef1a611ef5b3927ddce818cb7255a04ff3228c982c60', 'Nonce': 67644, 'PreviousHash': '7532402844a1c130833a27600298d09a007d6124603cf44be9c05fcd5428c34a', 'TransactionData': '{"sender": "kIqy1c8C", "recipient": "WSdK0EXh", "amount": 9329}'} {'Index': 1, 'Time': 1516268156.5981123, 'Difficulty': 3, 'Hash': 'ff9716bf9379e2ab7a8640419e7c7b7c7329a5e6e1bbf83a1249f49d070ca8b0', 'Nonce': 37336, 'PreviousHash': '7532402844a1c130833a27600298d09a007d6124603cf44be9c05fcd5428c34a', 'TransactionData': '{"sender": "vBwU0luH", "recipient": "d7o6cRCj", "amount": 5628}'} {'Index': 1, 'Time': 1516268156.5981123, 'Difficulty': 3, 'Hash': '3410c70c31f9bacbfcbd74d63f25f69f27d36075e2d44bddaa60bd72fa042e60', 'Nonce': 34617, 'PreviousHash': '7532402844a1c130833a27600298d09a007d6124603cf44be9c05fcd5428c34a', 'TransactionData': '{"sender": "yzcNpBnh", "recipient": "vbIr7SKo", "amount": 6387}'} {'Index': 1, 'Time': 1516268156.5981123, 'Difficulty': 27, 'Hash': '91e3dc3ef1a151557a1edd837528410b916362bcfb77dbb14dc54c8929f5a0d0', 'Nonce': 49121, 'PreviousHash': '7532402844a1c130833a27600298d09a007d6124603cf44be9c05fcd5428c34a', 'TransactionData': '{"sender": "p1MguhVz", "recipient": "gVSom4D3", "amount": 7356}'}
很明顯前兩個是最快的,為了簡單,我在最快的里面隨便選取一個,意思到了就行。大家可以看到,難度值,根據(jù)上文所說,這是反應(yīng)一個區(qū)塊生成的難易程度的,難度高的,在我這里會表示這個礦工為了得到這個區(qū)塊進行了多少次嘗試。看到這里也許你會問:為什么難度最大的時間并沒有明顯長呢?也就是用時并沒有按照難度的增加而增加。我猜想應(yīng)該是因為我的示例算法簡單,因此結(jié)果也不是十分精確,如果計算量達到一定的規(guī)模,應(yīng)該會有明顯的差距。(如果有高人知道,可以回復我,在此謝過?。┑谌降诹鶄€的區(qū)塊創(chuàng)建結(jié)果格式是與之一樣的,就不刷屏了。
{'Index': 0, 'Time': 1516268156.5971138, 'Difficulty': 0, 'Hash': '7532402844a1c130833a27600298d09a007d6124603cf44be9c05fcd5428c34a', 'Nonce': 87688, 'PreviousHash': '0', 'TransactionData': '{"sender": "OuVCmHbs", "recipient": "kFxbwSLc", "amount": 503}'} {'Index': 1, 'Time': 1516268156.5971138, 'Difficulty': 2, 'Hash': '01f505a276e3f55a868d9ee18f70bcff75429e1de70f5ab59471a3551cc67a30', 'Nonce': 91554, 'PreviousHash': '7532402844a1c130833a27600298d09a007d6124603cf44be9c05fcd5428c34a', 'TransactionData': '{"sender": "OY8z0Rrx", "recipient": "iSGFJsEm", "amount": 8723}'} {'Index': 2, 'Time': 1516268156.5991132, 'Difficulty': 4, 'Hash': '098544436793881e8041c0c903c96c0055e16396113d73c63bc55e7ba78ec130', 'Nonce': 12875, 'PreviousHash': '01f505a276e3f55a868d9ee18f70bcff75429e1de70f5ab59471a3551cc67a30', 'TransactionData': '{"sender": "HJZSX1hk", "recipient": "j82k51yY", "amount": 3521}'} {'Index': 3, 'Time': 1516268156.6001143, 'Difficulty': 27, 'Hash': '7c10243223caf39bc5a6067de8d93f6ea46bad62c4a0fbcc0aa4e086585d8200', 'Nonce': 18663, 'PreviousHash': '098544436793881e8041c0c903c96c0055e16396113d73c63bc55e7ba78ec130', 'TransactionData': '{"sender": "cJrGxN5R", "recipient": "wkZI8QCv", "amount": 1224}'} {'Index': 4, 'Time': 1516268156.601114, 'Difficulty': 3, 'Hash': '60a099d3fe53e031800669fcc1d9b5ab6df1f80a40354135310a799892f1c3d0', 'Nonce': 51446, 'PreviousHash': '7c10243223caf39bc5a6067de8d93f6ea46bad62c4a0fbcc0aa4e086585d8200', 'TransactionData': '{"sender": "nCNJoy52", "recipient": "kYBT9f65", "amount": 3603}'} {'Index': 5, 'Time': 1516268156.605163, 'Difficulty': 2, 'Hash': '765f69163cf95584721015e3ce819c1980ce33752f8a4dea553d3bedd39f8920', 'Nonce': 31804, 'PreviousHash': '60a099d3fe53e031800669fcc1d9b5ab6df1f80a40354135310a799892f1c3d0', 'TransactionData': '{"sender": "FqOkiTEu", "recipient": "y9EDcSYA", "amount": 4185}'}
這就是由這6個礦工依次創(chuàng)建的六個區(qū)塊,根據(jù)hash值環(huán)環(huán)相扣。
到底我想說的基本就結(jié)束了,最后我想說區(qū)塊鏈是個神奇的技術(shù),從聽到它就深深的吸引著我,期望未來區(qū)塊鏈可以真的帶來巨大的變革。要知道,隨著AI的興起,區(qū)塊鏈的問世,屬于程序員的數(shù)字時代會進一步升華,互聯(lián)網(wǎng)時代只是一個開始!謝謝閱讀,本人水平有限,如果您發(fā)現(xiàn)問題或我理解偏差的地方可以及時指出,再次表示感謝。文章末尾會附上完整代碼。
import hashlib import random import string import json import threading from decimal import Decimal from time import time class MyThread(threading.Thread): def __init__(self, target, args=()): super(MyThread, self).__init__() self.func = target self.args = args def run(self): self.result = self.func(*self.args) def get_result(self): try: return self.result except Exception: return None class BlockChain: def __init__(self, initialHash): # init block chain self.chain = [] # init pitman self.pitmen = [] for i in range(6): self.pitmen.append(Pitman) # collect mine results self.results = [] # generate GenesisBlock self.new_block(initialHash) @property def last_block(self): if len(self.chain): return self.chain[-1] else: return None def get_trans(self): return json.dumps({ 'sender': ''.join(random.sample(string.ascii_letters + string.digits, 8)), 'recipient': ''.join(random.sample(string.ascii_letters + string.digits, 8)), 'amount': random.randrange(1, 10000) }) def new_block(self, initialHash=None): if initialHash: # generate Genesis Block block = Block() block.index = 0 block.nonce = random.randrange(0, 99999) block.previousHash = '0' block.difficulty = 0 block.transactionData = self.get_trans() guess = f'{block.previousHash}{block.nonce}{block.transactionData}'.encode() block.hash = hashlib.sha256(guess).hexdigest() block.time = time() self.chain.append(block) else: for i in range(len(self.pitmen)): pm = MyThread(target=self.pitmen[i].mine, args=(self.pitmen[i], len(self.chain), self.last_block.get_block()['Hash'], self.get_trans())) pm.start() pm.join() self.results.append(pm.get_result()) # show all blocks print("All blocks generated by pitmen:") for result in self.results: print(result[0].get_block()) # get new block firstblock = self.results[0][0] mintime = Decimal(self.results[0][1]) for i in range(1, len(self.results)): if Decimal(self.results[i][1]) < mintime: firstblock = self.results[i][0] else: continue self.chain.append(firstblock) self.results = [] def show_chain(self): print('This is mine first block chain!') for block in self.chain: print(block.get_block()) class Block: def __init__(self): self.index = None self.time = None self.difficulty = None self.nonce = None self.hash = None self.previousHash = None self.transactionData = None def get_block(self): return { 'Index': self.index, 'Time': self.time, 'Difficulty': self.difficulty, 'Hash': self.hash, 'Nonce': self.nonce, 'PreviousHash': self.previousHash, 'TransactionData': self.transactionData } class Pitman: def mine(self, index, previousHash, transactionData): beginTime = time() block = Block() block.index = index block.previousHash = previousHash block.transactionData = transactionData block.difficulty, block.hash, block.nonce = self.generate_hash(previousHash, transactionData) block.time = time() endTime = time() return block, endTime - beginTime @staticmethod def generate_hash(previousHash, transactionData): difficulty = 0 nonce = random.randrange(0, 99999) guess = f'{previousHash}{nonce}{transactionData}'.encode() myhash = hashlib.sha256(guess).hexdigest() while myhash[-1] != '0': difficulty += 1 nonce += difficulty guess = f'{previousHash}{nonce}{transactionData}'.encode() myhash = hashlib.sha256(guess).hexdigest() return difficulty, myhash, nonce if __name__ == '__main__': chain = BlockChain(1) length = 5 for i in range(length): chain.new_block() chain.show_chain()
到此,關(guān)于“區(qū)塊鏈的概念以及用Python的實現(xiàn)方法”的學習就結(jié)束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續(xù)學習更多相關(guān)知識,請繼續(xù)關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編會繼續(xù)努力為大家?guī)砀鄬嵱玫奈恼拢?/p>
網(wǎng)站題目:區(qū)塊鏈的概念以及用Python的實現(xiàn)方法
文章地址:http://weahome.cn/article/jsdice.html