亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

通過(guò)Python入門區(qū)塊鏈

CloudDeveloper / 2000人閱讀

摘要:通過(guò)入門區(qū)塊鏈本文翻譯自的文章原文地址區(qū)塊鏈可能是繼互聯(lián)網(wǎng)之后最重大和最具突破性的技術(shù)。先不管對(duì)比特幣和其他加密貨幣價(jià)格的瘋狂行情,本文旨在幫助讀者入門區(qū)塊鏈技術(shù)。

通過(guò)Python入門區(qū)塊鏈
本文翻譯自 Adil Moujahid 的文章 A Practical Introduction to Blockchain with Python

原文地址:http://adilmoujahid.com/posts/2018/03/intro-blockchain-bitcoin-python/

區(qū)塊鏈可能是繼互聯(lián)網(wǎng)之后最重大和最具突破性的技術(shù)。它是比特幣和其他加密貨幣背后的核心技術(shù),在近幾年可謂賺足了人們的眼球。

本質(zhì)上講,區(qū)塊鏈?zhǔn)且环N不需第三方權(quán)威機(jī)構(gòu),直接在兩者之間點(diǎn)對(duì)點(diǎn)交易的分布式數(shù)據(jù)庫(kù)。這種簡(jiǎn)單卻強(qiáng)大的理念對(duì)銀行、政府和市場(chǎng)等各種各樣的機(jī)構(gòu)產(chǎn)生了巨大的影響。任何以中央數(shù)據(jù)庫(kù)作為技術(shù)壁壘的公司和組織都可能被區(qū)塊鏈技術(shù)顛覆。

先不管對(duì)比特幣和其他加密貨幣價(jià)格的瘋狂行情,本文旨在幫助讀者入門區(qū)塊鏈技術(shù)。第一、二節(jié)講解了一些區(qū)塊鏈的核心概念,第三節(jié)展示了如何通過(guò)Python實(shí)現(xiàn)區(qū)塊鏈。我們也將實(shí)現(xiàn)兩個(gè)web網(wǎng)站方便用戶與我們的區(qū)塊鏈交互。

本文通過(guò)比特幣作為例子來(lái)解釋主流的區(qū)塊鏈技術(shù),大部分概念在其他區(qū)塊鏈應(yīng)用場(chǎng)景和加密貨幣中同樣適用。

下圖使我們將在第三節(jié)實(shí)現(xiàn)的web應(yīng)用:

1. 區(qū)塊鏈快速入門

所有的一切開(kāi)始于2008年,一個(gè)自稱中本聰?shù)哪涿娜嘶蛘邎F(tuán)體發(fā)表了一篇白皮書。這篇名為『比特幣:一種點(diǎn)對(duì)點(diǎn)的電子現(xiàn)金系統(tǒng)』的白皮書為后來(lái)成為區(qū)塊鏈的技術(shù)打下了基礎(chǔ)。在白皮書中,重本從描述了如何建立一個(gè)點(diǎn)對(duì)點(diǎn)的電子貨幣系統(tǒng),可以直接從個(gè)體支付給另一個(gè)個(gè)體,而不需要中央權(quán)威機(jī)構(gòu)的介入。該系統(tǒng)解決了電子貨幣的一個(gè)重要問(wèn)題——雙重支付。

1.1 什么是雙重支付?

假設(shè)Alice想要付1美元給Bob。如果Alice和Bob使用物理貨幣,那么Alice在支付給Bob1美元之后,將不再擁有那1美元貨幣。如果Alice和Bob使用數(shù)字貨幣,那么問(wèn)題就變復(fù)雜了。數(shù)字貨幣很容易被復(fù)制,比如說(shuō),如果Alice通過(guò)電子郵件發(fā)給Bob一個(gè)價(jià)值1美元的數(shù)字文件,Bob并不知道Alien是否已經(jīng)刪掉她自己的文件。如果Alice沒(méi)有刪掉,并且又用同樣的方式發(fā)給了Carol。這就是雙重支付問(wèn)題。

一種雙重支付的解決方案是通過(guò)一個(gè)獨(dú)立于Aliec,Bob和其他網(wǎng)絡(luò)中的參與者的可信第三方機(jī)構(gòu)(比如說(shuō)銀行)。主要職責(zé)是維護(hù)一個(gè)用于記錄和驗(yàn)證網(wǎng)絡(luò)中所有的交易的中央賬本。這個(gè)解決方案的缺點(diǎn)是需要一個(gè)可信的中心化第三方機(jī)構(gòu)。

1.2 比特幣:一個(gè)雙重支付問(wèn)題的去中心化解決方案

為了解決雙重支付問(wèn)題,中本聰提出了一種公開(kāi)賬本,換言之,比特幣中的區(qū)塊鏈技術(shù)用于記錄網(wǎng)絡(luò)中所有的交易,有如下幾個(gè)特征:

分布性:賬本復(fù)制存儲(chǔ)在大量的計(jì)算機(jī)中,而不是一個(gè)中央數(shù)據(jù)庫(kù)。任何聯(lián)網(wǎng)的且運(yùn)行比特幣軟件的計(jì)算機(jī)都會(huì)下載一份區(qū)塊鏈的完整拷貝。

加密性:密碼學(xué)用來(lái)保證付款方擁有他發(fā)送的比特幣,并且決定交易如何添加到區(qū)塊鏈上。

不可篡改性:區(qū)塊鏈僅僅能在添加元素的時(shí)候被修改,也就是說(shuō),交易只能添加到區(qū)塊鏈,而不能刪除或篡改。

工作量證明機(jī)制:網(wǎng)絡(luò)中一種特殊的參與者叫做礦工,他們通過(guò)計(jì)算尋找密碼學(xué)難題,解開(kāi)難題的礦工可以將新的交易塊添加到區(qū)塊鏈中。

發(fā)送比特幣需要如下幾步操作:

第一步(只需一次):創(chuàng)建比特幣錢包。對(duì)于發(fā)送和接受比特幣的人來(lái)說(shuō),他們都需要?jiǎng)?chuàng)建一個(gè)比特幣錢包。比特幣錢包保存了兩部分信息:私鑰和公鑰。私鑰是一個(gè)密碼,允許擁有者發(fā)送比特幣給另一位用戶,或者把比特幣作為支付手段來(lái)使用。 公鑰是一串用來(lái)接受比特幣的字符串,同時(shí)也被稱作比特幣錢包地址(不完全正確,但一般來(lái)說(shuō)我們認(rèn)為公鑰和錢包地址是相同的)。請(qǐng)注意錢包不存儲(chǔ)比特幣本身,比特幣余額的信息被存儲(chǔ)在區(qū)塊鏈上。

第二步:創(chuàng)建比特幣交易。如果Alice想發(fā)送1美元給Bob,Alice需要使用私鑰打開(kāi)她的比特幣錢包,創(chuàng)建一個(gè)包含金額的交易(該場(chǎng)景中,使用Bob的公鑰地址)

第三步:向比特幣網(wǎng)絡(luò)廣播該交易事件。一旦Alice創(chuàng)建了比特幣交易,他需要向整個(gè)比特幣網(wǎng)絡(luò)廣播這個(gè)交易。

第四步:確認(rèn)交易。監(jiān)聽(tīng)比特幣網(wǎng)絡(luò)的某個(gè)礦工使用Alice的公鑰對(duì)交易進(jìn)行驗(yàn)證,確認(rèn)她的錢包中有足夠的比特幣(該場(chǎng)景中,最少1個(gè)比特幣),并且向區(qū)塊鏈中添加包含交易詳情的新紀(jì)錄。

第五步:向所有礦工廣播區(qū)塊鏈的修改。一旦交易被確認(rèn),該礦工應(yīng)該向所有的礦工廣播區(qū)塊鏈的修改,以保證其他礦工的區(qū)塊鏈內(nèi)容及時(shí)同步。

2. 深入理解區(qū)塊鏈

本節(jié)旨在深入探討驅(qū)動(dòng)區(qū)塊鏈的核心步驟——新建區(qū)塊的技術(shù)細(xì)節(jié),將從公開(kāi)密鑰加密,哈希函數(shù),挖礦和區(qū)塊鏈安全幾個(gè)方便展開(kāi)。

2.1 公開(kāi)密鑰加密

公開(kāi)密鑰加密,或者說(shuō)非對(duì)稱加密,是指一種使用一對(duì)鑰匙的加密系統(tǒng),公鑰可能被廣泛的三波,私鑰只有擁有者本人知道。它實(shí)現(xiàn)了兩個(gè)功能:認(rèn)證,公鑰可以驗(yàn)證持有者通過(guò)私鑰加密的信息;加密,只有私鑰擁有者可以解開(kāi)通過(guò)公鑰加密的信息。

RSA和橢圓曲線數(shù)字簽名算法(ECDSA)是最廣泛應(yīng)用的兩種公開(kāi)密鑰加密算法。

對(duì)比特幣來(lái)說(shuō),ECDSA算法被用于生成比特幣錢包。比特幣通常使用多個(gè)鑰匙和地址,但簡(jiǎn)單起見(jiàn),本文中假設(shè)每個(gè)比特幣錢包只使用一堆公鑰和私鑰,并且比特幣錢包地址就是公鑰。如果你對(duì)比特幣錢包的完整技術(shù)感興趣,我推薦這篇文章。

發(fā)送和接受比特幣時(shí),用戶首先創(chuàng)建一個(gè)包含公鑰和私鑰的錢包。如果Alice想要給Bob發(fā)送一些比特幣,她在創(chuàng)建交易的時(shí)候需要將她和Bob雙方的公鑰,以及比特幣金額輸入進(jìn)去。然后使用自己的私鑰簽署這筆交易。區(qū)塊鏈上的某臺(tái)計(jì)算機(jī)可以通過(guò)Alice的公鑰去驗(yàn)證這筆交易是不是Alice本人發(fā)出的,然后將交易添加到區(qū)塊上,之后該區(qū)塊會(huì)被添加到區(qū)塊鏈當(dāng)中。

2.2. 哈希函數(shù)和挖礦

所有比特幣交易被存放在成為區(qū)塊的文件中。比特幣每十分鐘向區(qū)塊鏈中添加一個(gè)包含新增交易記錄的新區(qū)塊。一旦新區(qū)快被添加進(jìn)區(qū)塊鏈,它將不可修改和刪除。在區(qū)塊鏈網(wǎng)絡(luò)中,一種被稱為礦工(他們的計(jì)算機(jī)連接著區(qū)塊鏈)的特殊群體負(fù)責(zé)創(chuàng)建新的交易區(qū)塊。礦工必須使用發(fā)送者的公鑰驗(yàn)證每一筆交易,確認(rèn)發(fā)送者擁有足夠的余額支付完成該交易,并且將交易添加到區(qū)塊中。礦工可以完全自主選擇將哪些交易添加到區(qū)塊中,因此發(fā)送者需要提交一些交易費(fèi)來(lái)激勵(lì)礦工將它們的交易添加到區(qū)塊中。

對(duì)于每一個(gè)被區(qū)塊鏈接受的區(qū)塊,都需要被挖礦。挖一個(gè)區(qū)塊的時(shí)候,礦工需要尋找一個(gè)極難的加密難題的答案。如果一個(gè)被挖礦的區(qū)塊被區(qū)塊鏈接受,礦工將獲得一定的比特幣作為除了交易費(fèi)的額外獎(jiǎng)勵(lì)。挖礦程序也被稱為工作量證明機(jī)制,它是保障區(qū)塊鏈可靠和安全的主要機(jī)制(稍后再討論區(qū)塊鏈的安全性)。

哈希和區(qū)塊鏈加密難題

為了理解區(qū)塊鏈加密難題,需要先理解哈希函數(shù)。哈希函數(shù)可以將任意范圍的數(shù)據(jù)映射到指定的數(shù)據(jù)范圍。哈希函數(shù)返回的結(jié)果成為哈希值。哈希函數(shù)通常被用于通過(guò)重復(fù)檢查來(lái)加速數(shù)據(jù)庫(kù)查找,并且在密碼學(xué)中也有廣泛的應(yīng)用。加密哈希函數(shù)幫助人們輕松地驗(yàn)證某些輸入數(shù)據(jù)是否映射到了給定的哈希值,但如果不知道輸入數(shù)據(jù),那么通過(guò)哈希值來(lái)構(gòu)造輸入數(shù)據(jù)是極其困難的。[2]

比特幣使用SHA-256作為加密哈希函數(shù)。SHA-256應(yīng)用于區(qū)塊數(shù)據(jù)(比特幣交易)與一種名為nonce(譯者注:實(shí)際上是一個(gè)隨機(jī)數(shù))的數(shù)字的組合。通過(guò)改變區(qū)塊數(shù)據(jù)和nonce,可以得到完全不同的哈希值。對(duì)于一個(gè)被認(rèn)為是有效或者說(shuō)是被挖礦的區(qū)塊,區(qū)塊和nonce的哈希值需要滿足一個(gè)特定的條件。比如說(shuō),哈希值前面的四位數(shù)等于"0000"。我們可以通過(guò)規(guī)定更加復(fù)雜的條件來(lái)提高挖礦的難度,比如說(shuō)我們可以要求哈希值的開(kāi)頭包含更多個(gè)0。

礦工面臨的加密難題需要尋找一個(gè)nonce值,使得哈希值滿足挖礦成功條件。我們可以通過(guò)下面的應(yīng)用來(lái)模擬區(qū)塊挖礦。當(dāng)在Data欄輸入內(nèi)容或者改變nonce值時(shí),哈希值會(huì)隨之改變。當(dāng)點(diǎn)擊"挖礦"按鈕,應(yīng)用從0開(kāi)始枚舉nonce的值,并檢查哈希值的前四位數(shù)是否等于"0000"。如果前四位數(shù)不等于"0000",那么nonce值加一并重復(fù)相同的操作直到nonce值滿足條件。如果區(qū)塊完成挖礦,那么背景色會(huì)變成綠色。

為了保證體驗(yàn),請(qǐng)到原文鏈接中相應(yīng)位置進(jìn)行模擬。
2.3. 從區(qū)塊到區(qū)塊鏈

如前一節(jié)所述,交易被分組存放在區(qū)塊中,區(qū)塊被附加在區(qū)塊鏈中。為了把區(qū)塊串成鏈,每個(gè)新區(qū)塊都存儲(chǔ)著它前一個(gè)區(qū)塊的哈希值。創(chuàng)建新區(qū)塊時(shí),礦工選擇一些交易,添加前一個(gè)區(qū)塊的哈希值,并且對(duì)區(qū)塊進(jìn)行挖礦。

任何區(qū)塊中任何數(shù)據(jù)上的改變都會(huì)影響該區(qū)塊的哈希值,進(jìn)而導(dǎo)致該區(qū)塊失效。這賦予了區(qū)塊鏈不可篡改的特性。

你可以通過(guò)如下軟件模擬包含三個(gè)區(qū)塊的區(qū)塊鏈。當(dāng)你在Data欄輸入內(nèi)容或者概念nonce值時(shí),可以發(fā)現(xiàn)該區(qū)塊的哈希值和下一個(gè)區(qū)塊的前導(dǎo)值(前導(dǎo)哈希值)隨之改變??梢酝ㄟ^(guò)點(diǎn)擊每個(gè)獨(dú)立區(qū)塊的"挖礦"按鈕模擬挖礦過(guò)程。三個(gè)區(qū)塊挖礦完成后,嘗試改變區(qū)塊1或區(qū)塊2的內(nèi)容,會(huì)發(fā)現(xiàn)該操作導(dǎo)致該區(qū)塊之后的區(qū)塊失效。

為了保證體驗(yàn),請(qǐng)到原文鏈接中相應(yīng)位置進(jìn)行模擬。

上面的兩個(gè)挖礦模擬器都是由Anders Brownworth的BlockChain Demo改編而來(lái)的。

2.4. 向區(qū)塊鏈添加區(qū)塊

比特幣網(wǎng)絡(luò)中的所有礦工互相競(jìng)爭(zhēng),率先找到可以添加到區(qū)塊鏈的合法區(qū)塊的礦工將獲得獎(jiǎng)勵(lì)。找到可以驗(yàn)證區(qū)塊的nonce值是極其困難的,但由于比特幣網(wǎng)絡(luò)中有大量的礦工,尋找到該值并驗(yàn)證區(qū)塊的可能性是非常高的。第一個(gè)礦工提交一個(gè)有效區(qū)塊到區(qū)塊鏈,會(huì)得到一定的比特幣作為獎(jiǎng)勵(lì)。但如果兩個(gè)或更多礦工同時(shí)提交了他們的區(qū)塊該如何處理呢?

解決沖突

如果兩個(gè)礦工幾乎在同一時(shí)間驗(yàn)證了區(qū)塊,那么區(qū)塊鏈便產(chǎn)生了分叉,需要等待下一個(gè)區(qū)塊去解決沖突。一些礦工會(huì)選擇在第一條分叉上挖礦,另一些礦工選擇在第二條分叉上挖礦。第一個(gè)找到新區(qū)塊的礦工將解決該沖突。如果新區(qū)塊在第一條分叉上,那么第二條分叉便失效了,前一個(gè)區(qū)塊的獎(jiǎng)勵(lì)由將區(qū)塊提交到第一個(gè)分叉上的礦工獲得,第二個(gè)分叉上的交易沒(méi)有被提交到區(qū)塊鏈中,將回到交易池等待被提交到之后的區(qū)塊中。簡(jiǎn)言之,如果區(qū)塊鏈中產(chǎn)生分叉,最長(zhǎng)的分叉將被保留下來(lái)。

2.5. 區(qū)塊鏈和雙重支付

本節(jié)將探討區(qū)塊鏈雙重支付攻擊的最常見(jiàn)方法,和用戶需要采取的一些使自己免于傷害的措施。

Race 攻擊

攻擊者在極短的時(shí)間內(nèi)使用同一個(gè)貨幣發(fā)送給兩個(gè)不同的地址。為了防范這種攻擊,推薦等待至少1個(gè)區(qū)塊確認(rèn)后,再接受對(duì)方的支付。

Finney 攻擊

攻擊者預(yù)先挖好一個(gè)包含某條交易的區(qū)塊,釋放該區(qū)塊之前,在第二次交易中使用相同的貨幣。在該場(chǎng)景中,第二次交易將不會(huì)生效。為了防范這種攻擊,推薦等待至少6個(gè)區(qū)塊確認(rèn)后,再接受對(duì)方的支付。

多數(shù)人攻擊(也稱為51%攻擊)

在該攻擊中,攻擊者掌握了比特幣網(wǎng)絡(luò)中51%的算力。攻擊者首先把構(gòu)造好的交易廣播到整個(gè)網(wǎng)絡(luò),然后對(duì)包含雙重支付貨幣交易的私有區(qū)塊鏈進(jìn)行挖礦。由于掌握了多數(shù)的算力,他可以保證在某個(gè)點(diǎn)上比正確的區(qū)塊鏈擁有更長(zhǎng)的鏈,這將取代正確的區(qū)塊鏈,并取消原來(lái)的交易。這種攻擊極其不可能發(fā)生,因?yàn)槌杀竞芨摺?/p> 3. 通過(guò)Python實(shí)現(xiàn)的區(qū)塊鏈

本節(jié)我們講使用Python實(shí)現(xiàn)一個(gè)簡(jiǎn)單的區(qū)塊鏈和區(qū)塊鏈客戶端。我們的區(qū)塊鏈將有如下特征:

支持向區(qū)塊鏈網(wǎng)絡(luò)中添加多個(gè)節(jié)點(diǎn)

工作量證明機(jī)制(PoW)

節(jié)點(diǎn)之間簡(jiǎn)單的沖突處理

基于RSA加密的交易

區(qū)塊鏈客戶端將有如下特性:

通過(guò)公鑰和私鑰生成錢包(基于RSA算法)

基于RSA加密生成交易

我們將實(shí)現(xiàn)兩個(gè)儀表盤:

礦工使用的"區(qū)塊鏈后臺(tái)"

用戶用來(lái)生成錢包和發(fā)送比特幣的"區(qū)塊鏈客戶端"

區(qū)塊鏈實(shí)現(xiàn)主要基于這個(gè)Github項(xiàng)目。我對(duì)源碼進(jìn)行了一些修改,添加了RSA加密算法交易。錢包生成和交易加密基于Jupyter notebook.這兩個(gè)儀表盤通過(guò)HTML/CSS/JS實(shí)現(xiàn)。

你可以從https://github.com/adilmoujahid/blockchain-python-tutorial下載完整源碼。

3.1. 區(qū)塊鏈客戶端實(shí)現(xiàn)

通過(guò)終端進(jìn)入blockchain_client文件夾中的blockchain客戶端,輸入python blockchain_client.py。在瀏覽器中打開(kāi)http://localhost:8080將看到如下儀表盤。

儀表盤的導(dǎo)航欄中有三個(gè)標(biāo)簽頁(yè):

生成錢包:通過(guò)RSA加密算法生成錢包(公鑰私鑰對(duì))

發(fā)起交易:生成交易,并且將它們發(fā)送給區(qū)塊鏈節(jié)點(diǎn)

查看交易:查看區(qū)塊鏈中的交易

為了發(fā)起或查看交易,需要至少運(yùn)行一個(gè)區(qū)塊鏈節(jié)點(diǎn)(下一節(jié)將講解此內(nèi)容)

接下來(lái)將解釋一些blockchain_client.py中的關(guān)鍵代碼。

我們定義了含有sender_address, sender_private_key, recipient_address, value這4個(gè)屬性的Transaction類。用戶發(fā)起一筆交易時(shí)需要填寫這4個(gè)內(nèi)容。

to_dict()方法以Python字典格式返回交易信息(無(wú)需發(fā)送者密鑰)。sign_transaction()方法取出交易信息(無(wú)需發(fā)送者密鑰),并使用發(fā)送者的私鑰簽署該交易信息。

class Transaction:

    def __init__(self, sender_address, sender_private_key, recipient_address, value):
        self.sender_address = sender_address
        self.sender_private_key = sender_private_key
        self.recipient_address = recipient_address
        self.value = value

    def __getattr__(self, attr):
        return self.data[attr]

    def to_dict(self):
        return OrderedDict({"sender_address": self.sender_address,
                            "recipient_address": self.recipient_address,
                            "value": self.value})

    def sign_transaction(self):
        """
        Sign transaction with private key
        """
        private_key = RSA.importKey(binascii.unhexlify(self.sender_private_key))
        signer = PKCS1_v1_5.new(private_key)
        h = SHA.new(str(self.to_dict()).encode("utf8"))
        return binascii.hexlify(signer.sign(h)).decode("ascii")

下面這行代碼會(huì)初始化一個(gè)Python Flask應(yīng)用,我們將用它創(chuàng)建API,使客戶端與區(qū)塊鏈進(jìn)行交互。

app = Flask(__name__)

下面我們定義了三個(gè)返回html頁(yè)面的Flask路由,每個(gè)標(biāo)簽頁(yè)都有個(gè)一個(gè)html頁(yè)面與之對(duì)應(yīng)。

@app.route("/")
def index():
  return render_template("./index.html")

@app.route("/make/transaction")
def make_transaction():
    return render_template("./make_transaction.html")

@app.route("/view/transactions")
def view_transaction():
    return render_template("./view_transactions.html")

下面我們定義了一個(gè)生成錢包(公鑰私鑰對(duì))的API。

@app.route("/wallet/new", methods=["GET"])
def new_wallet():
  random_gen = Crypto.Random.new().read
  private_key = RSA.generate(1024, random_gen)
  public_key = private_key.publickey()
  response = {
    "private_key": binascii.hexlify(private_key.exportKey(format="DER")).decode("ascii"),
    "public_key": binascii.hexlify(public_key.exportKey(format="DER")).decode("ascii")
  }

  return jsonify(response), 200

下面我們定義了一個(gè)入?yún)?b>sender_address, sender_private_key, recipient_address, value的API,它會(huì)返回交易(無(wú)需私鑰)和簽名。

@app.route("/generate/transaction", methods=["POST"])
def generate_transaction():

  sender_address = request.form["sender_address"]
  sender_private_key = request.form["sender_private_key"]
  recipient_address = request.form["recipient_address"]
  value = request.form["amount"]

  transaction = Transaction(sender_address, sender_private_key, recipient_address, value)

  response = {"transaction": transaction.to_dict(), "signature": transaction.sign_transaction()}

  return jsonify(response), 200

3.2. 區(qū)塊鏈實(shí)現(xiàn)

通過(guò)終端進(jìn)入blockchain文件夾,輸入python blockchain.py或者python blockchain.py -p 。如果你不想指定端口號(hào),那么默認(rèn)的端口號(hào)是5000。在瀏覽器中打開(kāi)http://localhost:可以看到區(qū)塊鏈后臺(tái)儀表盤。

儀表盤的導(dǎo)航欄中有兩個(gè)標(biāo)簽頁(yè):

挖礦:查看交易和區(qū)塊鏈數(shù)據(jù),對(duì)新的交易區(qū)塊進(jìn)行挖礦。

配置:配置不同區(qū)塊鏈節(jié)點(diǎn)之間的鏈接。

接下來(lái)將解釋一些blockchain.py中的關(guān)鍵代碼。

我們定義Blockchain類,包含如下屬性:

transactions: 將被添加到下一個(gè)區(qū)塊的所有交易的集合。

chain: 實(shí)際的區(qū)塊鏈,以區(qū)塊類型數(shù)組的形式存放。

nodes: 節(jié)點(diǎn)url的集合。區(qū)塊鏈通過(guò)這些節(jié)點(diǎn)檢索區(qū)塊鏈數(shù)據(jù),更新節(jié)點(diǎn)上尚未同步的區(qū)塊鏈數(shù)據(jù)。

node_id: 用于標(biāo)識(shí)區(qū)塊鏈節(jié)點(diǎn)的隨機(jī)字符串。

Blockchain類實(shí)現(xiàn)了如下方法:

register_node(node_url): 向節(jié)點(diǎn)列表添加新的區(qū)塊鏈節(jié)點(diǎn)。

verify_transaction_signature(sender_address, signature, transaction): 使用公鑰(發(fā)送者地址)驗(yàn)證提供的簽名。

submit_transaction(sender_address, recipient_address, value, signature): 如果簽名驗(yàn)證通過(guò),向交易列表中添加交易。

create_block(nonce, previous_hash): 向區(qū)塊鏈添加新的區(qū)塊。

hash(block): 為區(qū)塊創(chuàng)建SHA_256哈希值。

proof_of_work(): 工作量證明算法。尋找滿足挖礦條件的nonce值。

valid_proof(transaction, last_hash, nonce, difficulty=MININGDIFFICULTY): 檢查哈希值是否滿足挖礦條件。這個(gè)方法在proof_of_work方法中使用。

valid_chain(chain): 檢查區(qū)塊鏈?zhǔn)欠窈戏ā?/p>

resolve_conflicts(): 通過(guò)保留最長(zhǎng)分叉解決區(qū)塊鏈節(jié)點(diǎn)之間的沖突。

class Blockchain:

    def __init__(self):

        self.transactions = []
        self.chain = []
        self.nodes = set()
        #Generate random number to be used as node_id
        self.node_id = str(uuid4()).replace("-", "")
        #Create genesis block
        self.create_block(0, "00")

    def register_node(self, node_url):
        """
        Add a new node to the list of nodes
        """
        ...

    def verify_transaction_signature(self, sender_address, signature, transaction):
        """
        Check that the provided signature corresponds to transaction
        signed by the public key (sender_address)
        """
        ...

    def submit_transaction(self, sender_address, recipient_address, value, signature):
        """
        Add a transaction to transactions array if the signature verified
        """
        ...

    def create_block(self, nonce, previous_hash):
        """
        Add a block of transactions to the blockchain
        """
        ...

    def hash(self, block):
        """
        Create a SHA-256 hash of a block
        """
        ...

    def proof_of_work(self):
        """
        Proof of work algorithm
        """
        ...

    def valid_proof(self, transactions, last_hash, nonce, difficulty=MINING_DIFFICULTY):
        """
        Check if a hash value satisfies the mining conditions. This function is used within the proof_of_work function.
        """
        ...

    def valid_chain(self, chain):
        """
        check if a bockchain is valid
        """
        ...

    def resolve_conflicts(self):
        """
        Resolve conflicts between blockchain"s nodes
        by replacing our chain with the longest one in the network.
        """
        ...

下面這行代碼初始化一個(gè)Python Flask應(yīng)用,我們將用它創(chuàng)建API,使客戶端與區(qū)塊鏈進(jìn)行交互。

app = Flask(__name__)
CORS(app)

接下來(lái),初始化一個(gè)Blockchain實(shí)例。

blockchain = Blockchain()

下面我們?yōu)閰^(qū)塊鏈后臺(tái)儀表盤定義了兩個(gè)返回html頁(yè)面的Flask路由。

@app.route("/")
def index():
    return render_template("./index.html")

@app.route("/configure")
def configure():
    return render_template("./configure.html")

下面我們定義了一些Flask API來(lái)管理交易和挖礦。

"/transactions/new": 這個(gè)API對(duì)應(yīng)在簽名驗(yàn)證正確后,添加包含sender_address,"recipient_address", amountsignature參數(shù)的交易到新的區(qū)塊中。

/transaction/get: 這個(gè)API返回所有將被添加到下一個(gè)區(qū)塊的交易。

/chain: 這個(gè)API返回所有的區(qū)塊鏈數(shù)據(jù)。

/mine: 這個(gè)API運(yùn)行工作量證明算法,并且添加新的交易區(qū)塊到區(qū)塊鏈上。

@app.route("/transactions/new", methods=["POST"])
def new_transaction():
    values = request.form

    # Check that the required fields are in the POST"ed data
    required = ["sender_address", "recipient_address", "amount", "signature"]
    if not all(k in values for k in required):
        return "Missing values", 400
    # Create a new Transaction
    transaction_result = blockchain.submit_transaction(values["sender_address"], values["recipient_address"], values["amount"], values["signature"])

    if transaction_result == False:
        response = {"message": "Invalid Transaction!"}
        return jsonify(response), 406
    else:
        response = {"message": "Transaction will be added to Block "+ str(transaction_result)}
        return jsonify(response), 201

@app.route("/transactions/get", methods=["GET"])
def get_transactions():
    #Get transactions from transactions pool
    transactions = blockchain.transactions

    response = {"transactions": transactions}
    return jsonify(response), 200

@app.route("/chain", methods=["GET"])
def full_chain():
    response = {
        "chain": blockchain.chain,
        "length": len(blockchain.chain),
    }
    return jsonify(response), 200

@app.route("/mine", methods=["GET"])
def mine():
    # We run the proof of work algorithm to get the next proof...
    last_block = blockchain.chain[-1]
    nonce = blockchain.proof_of_work()

    # We must receive a reward for finding the proof.
    blockchain.submit_transaction(sender_address=MINING_SENDER, recipient_address=blockchain.node_id, value=MINING_REWARD, signature="")

    # Forge the new Block by adding it to the chain
    previous_hash = blockchain.hash(last_block)
    block = blockchain.create_block(nonce, previous_hash)

    response = {
        "message": "New Block Forged",
        "block_number": block["block_number"],
        "transactions": block["transactions"],
        "nonce": block["nonce"],
        "previous_hash": block["previous_hash"],
    }
    return jsonify(response), 200

下面我們定義Flash API來(lái)管理區(qū)塊鏈節(jié)點(diǎn):

"/nodes/register": 這個(gè)API的入?yún)⑹枪?jié)點(diǎn)url列表,然后將它們更新到列表中每一個(gè)節(jié)點(diǎn)中。

"/nodes/resolve": 這個(gè)API通過(guò)保留最長(zhǎng)分叉解決區(qū)塊鏈節(jié)點(diǎn)之間的沖突。

"/nodes/get": 這個(gè)API返回所有的節(jié)點(diǎn)列表。

@app.route("/nodes/register", methods=["POST"])
def register_nodes():
    values = request.form
    nodes = values.get("nodes").replace(" ", "").split(",")

    if nodes is None:
        return "Error: Please supply a valid list of nodes", 400

    for node in nodes:
        blockchain.register_node(node)

    response = {
        "message": "New nodes have been added",
        "total_nodes": [node for node in blockchain.nodes],
    }
    return jsonify(response), 201


@app.route("/nodes/resolve", methods=["GET"])
def consensus():
    replaced = blockchain.resolve_conflicts()

    if replaced:
        response = {
            "message": "Our chain was replaced",
            "new_chain": blockchain.chain
        }
    else:
        response = {
            "message": "Our chain is authoritative",
            "chain": blockchain.chain
        }
    return jsonify(response), 200


@app.route("/nodes/get", methods=["GET"])
def get_nodes():

    nodes = list(blockchain.nodes)
    response = {"nodes": nodes}
    return jsonify(response), 200

總結(jié)

本文探討了區(qū)塊鏈底層的核心概念和如何通過(guò)Python實(shí)現(xiàn)一個(gè)區(qū)塊鏈系統(tǒng)。簡(jiǎn)單起見(jiàn),本文并沒(méi)有覆蓋一些技術(shù)細(xì)節(jié),比如說(shuō):錢包地址和默克爾樹(shù)。如果你想深入了解這些細(xì)節(jié),我推薦閱讀比特幣白皮書原文,和bitcoin wiki,以及Andreas Antonopoulos的精彩著作: Mastering Bitcoin: Programming the Open Blockchain

參考文獻(xiàn)

Wikipedia - Public-key cryptography

Wikipedia - Hash function

Bitcoin Stackexchange - What happens to a transaction once generated?

Bitcoin Wiki - Majority attack

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/44708.html

相關(guān)文章

  • 通過(guò)Python入門區(qū)塊

    摘要:通過(guò)入門區(qū)塊鏈本文翻譯自的文章原文地址區(qū)塊鏈可能是繼互聯(lián)網(wǎng)之后最重大和最具突破性的技術(shù)。先不管對(duì)比特幣和其他加密貨幣價(jià)格的瘋狂行情,本文旨在幫助讀者入門區(qū)塊鏈技術(shù)。 通過(guò)Python入門區(qū)塊鏈 本文翻譯自 Adil Moujahid 的文章 A Practical Introduction to Blockchain with Python原文地址:http://adilmoujahi...

    andong777 評(píng)論0 收藏0
  • SegmentFault 技術(shù)周刊 Vol.41 - 深入學(xué)習(xí)區(qū)塊

    摘要:和比特幣協(xié)議有所不同的是,以太坊的設(shè)計(jì)十分靈活,極具適應(yīng)性。超級(jí)賬本區(qū)塊鏈的商業(yè)應(yīng)用超級(jí)賬本超級(jí)賬本是基金會(huì)下的眾多項(xiàng)目中的一個(gè)。證書頒發(fā)機(jī)構(gòu)負(fù)責(zé)簽發(fā)撤 showImg(https://segmentfault.com/img/bV2ge9?w=900&h=385); 從比特幣開(kāi)始 一個(gè)故事告訴你比特幣的原理及運(yùn)作機(jī)制 這篇文章的定位會(huì)比較科普,盡量用類比的方法將比特幣的基本原理講出來(lái)...

    qianfeng 評(píng)論0 收藏0
  • 通過(guò)7個(gè)Python函數(shù)來(lái)解釋區(qū)塊

    摘要:所以不用多說(shuō),讓我們看看我們的個(gè)函數(shù)區(qū)塊鏈的核心是函數(shù)。讀取前一個(gè)區(qū)塊的信息,并將其用于將其鏈接到新區(qū)塊。這也是區(qū)塊鏈理念的核心。以太坊開(kāi)發(fā)教程,主要是針對(duì)和程序員進(jìn)行區(qū)塊鏈以太坊開(kāi)發(fā)的詳解。 我想對(duì)于那里的很多人來(lái)說(shuō),區(qū)塊鏈就是這種現(xiàn)象,很難不讓你頭腦發(fā)熱。我開(kāi)始觀看視頻和閱讀文章,但對(duì)我個(gè)人而言,直到我編寫自己的簡(jiǎn)單區(qū)塊鏈,我才真正理解它是什么以及它的潛在應(yīng)用價(jià)值。 我對(duì)區(qū)塊鏈的看...

    wangzy2019 評(píng)論0 收藏0
  • 通過(guò)7個(gè)Python函數(shù)來(lái)解釋區(qū)塊

    摘要:所以不用多說(shuō),讓我們看看我們的個(gè)函數(shù)區(qū)塊鏈的核心是函數(shù)。讀取前一個(gè)區(qū)塊的信息,并將其用于將其鏈接到新區(qū)塊。這也是區(qū)塊鏈理念的核心。以太坊開(kāi)發(fā)教程,主要是針對(duì)和程序員進(jìn)行區(qū)塊鏈以太坊開(kāi)發(fā)的詳解。 我想對(duì)于那里的很多人來(lái)說(shuō),區(qū)塊鏈就是這種現(xiàn)象,很難不讓你頭腦發(fā)熱。我開(kāi)始觀看視頻和閱讀文章,但對(duì)我個(gè)人而言,直到我編寫自己的簡(jiǎn)單區(qū)塊鏈,我才真正理解它是什么以及它的潛在應(yīng)用價(jià)值。 我對(duì)區(qū)塊鏈的看...

    MrZONT 評(píng)論0 收藏0
  • 區(qū)塊開(kāi)發(fā)中使用的最流行的編程語(yǔ)言

    摘要:我們目前正處于一個(gè)新興的區(qū)塊鏈開(kāi)發(fā)行業(yè)中。,一種在以太坊開(kāi)發(fā)人員中流行的新的簡(jiǎn)單編程語(yǔ)言,因?yàn)樗怯糜陂_(kāi)發(fā)以太坊智能合約的語(yǔ)言。它是全球至少萬(wàn)開(kāi)發(fā)人員使用的世界上最流行的編程語(yǔ)言之一。以太坊,主要是針對(duì)工程師使用進(jìn)行區(qū)塊鏈以太坊開(kāi)發(fā)的詳解。 我們目前正處于一個(gè)新興的區(qū)塊鏈開(kāi)發(fā)行業(yè)中。區(qū)塊鏈技術(shù)處于初期階段,然而這種顛覆性技術(shù)已經(jīng)成功地風(fēng)靡全球,并且最近經(jīng)歷了一場(chǎng)與眾不同的繁榮。由于許多...

    2shou 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<