99999久久久久久亚洲,欧美人与禽猛交狂配,高清日韩av在线影院,一个人在线高清免费观看,啦啦啦在线视频免费观看www

熱線電話:13121318867

登錄
首頁精彩閱讀太簡單!只學十分鐘,Python菜鳥也能開發(fā)一個區(qū)塊鏈客戶端
太簡單!只學十分鐘,Python菜鳥也能開發(fā)一個區(qū)塊鏈客戶端
2018-07-25
收藏

太簡單!只學十分鐘,Python菜鳥也能開發(fā)一個區(qū)塊鏈客戶端

區(qū)塊鏈技術以其去中心化特性成為又一具有顛覆性特征的技術。Python作為一種面向?qū)ο蟮慕忉屝陀嬎銠C程序設計語言,因其具有豐富和強大的庫,常被稱為“膠水語言”,簡單、易上手,是區(qū)塊鏈技術愛好者快速學習區(qū)塊鏈的首選之一。

本文作者Adil Moujahid 是世界IT服務企業(yè)排名前十、日本IT服務企業(yè)排名榜首的NTT DATA集團的數(shù)據(jù)科學家,對Python在區(qū)塊鏈方向的應用有著十分深入的研究。

在這篇文章中,Adil Moujahid 由雙重支付問題引出去中心化支付方案,介紹公鑰密碼學、Hash函數(shù)、挖礦等區(qū)塊鏈核心概念,并詳細闡述如何產(chǎn)生一個新區(qū)快、如何將新區(qū)快添加到區(qū)塊鏈等問題,最后,利用Python實現(xiàn)基本的區(qū)塊鏈和區(qū)塊鏈客戶端。

在了解區(qū)塊鏈的核心概念之后,讓Adil Moujahid 手把手,教你用Python實現(xiàn)區(qū)塊鏈和區(qū)塊鏈客戶端的實操吧!干貨滿滿!

可以說,區(qū)塊鏈是自互聯(lián)網(wǎng)誕生以來最重要和最具顛覆性的技術之一。作為比特幣和其他加密貨幣背后的核心技術,區(qū)塊鏈在過去幾年獲得了廣泛關注。

區(qū)塊鏈是一個分布式數(shù)據(jù)庫,允許雙方之間直接進行交易,而無需第三方權限,對銀行、政府和市場等機構具有很大影響。

任何依賴中心化數(shù)據(jù)庫作為核心競爭優(yōu)勢的企業(yè)或組織都可能被區(qū)塊鏈技術所顛覆。

本文分三部分,前兩部分介紹區(qū)塊鏈的核心概念;第三部分介紹如何利用Python實現(xiàn)區(qū)塊鏈以及2個區(qū)塊鏈Web應用程序,以便終端用戶輕松與區(qū)塊鏈進行鏈上交互,效果圖如下。

極簡的區(qū)塊鏈速成教程

2008年中本聰發(fā)布標題為“比特幣:點對點電子現(xiàn)金系統(tǒng)” 的比特幣白皮書,奠定了區(qū)塊鏈的基礎。

在最初的比特幣白皮書中,中本聰描述了如何建立一個點對點電子現(xiàn)金系統(tǒng),允許不通過中心化機構實現(xiàn)在線支付,直接從一方發(fā)送到另一方。該系統(tǒng)解決了數(shù)字貨幣中一個稱為雙重支付的重要問題。

什么是雙重支付?

假設Alice想要支付Bob 1美元。如果Alice和Bob使用實物現(xiàn)金,那么Alice在執(zhí)行交易后將不再擁有1美元;如果Alice和Bob使用數(shù)字貨幣,那么問題會變得更加復雜。

數(shù)字貨幣以數(shù)字形式存在,可以輕松進行復制。例如,如果Alice通過電子郵件向Bob發(fā)送價值1美元的數(shù)字文件,則Bob無法確定Alice是否刪除了她的文件副本,如果Alice仍然擁有1美元數(shù)字文件,那么她可以選擇將相同的文件發(fā)送給Carol。這個問題就叫做雙重支付。

解決雙重支付問題的一種方法是在Alice、Bob和網(wǎng)絡中其他參與者之間建立可信任的第三方(例如銀行),該第三方負責管理中心化分類賬,而分類賬跟蹤并驗證網(wǎng)絡中的所有交易。該解決方案的缺點是,為了使系統(tǒng)運行,它需要信任中心化的第三方。

比特幣:雙重支付問題的去中心化方案

為了解決雙重支付問題,中本聰提出了一個公共分類賬,即通過比特幣的區(qū)塊鏈來跟蹤網(wǎng)絡中的所有交易。比特幣的區(qū)塊鏈具有以下特征

分布式:分類帳在多臺計算機上復制,而不是存儲在中央服務器上。任何具有互聯(lián)網(wǎng)連接的計算機都可以下載區(qū)塊鏈的完整副本。

加密:用于確認發(fā)送人持有她想要發(fā)送的比特幣,并決定如何將交易添加到區(qū)塊鏈中。

不可變:交易只能添加到區(qū)塊鏈中,但不能刪除或修改。

工作量證明(PoW):網(wǎng)絡中一種特殊類型的參與者稱為礦工,他們競爭搜索加密難題的解決方案,該解決方案允許他們向比特幣的區(qū)塊鏈添加一個交易區(qū)塊,此過程稱為工作量證明,它能確保系統(tǒng)安全。

發(fā)送比特幣資金流程如下:

  1. 創(chuàng)建一個比特幣錢包。用于發(fā)送或接收比特幣,比特幣錢包存儲2條信息:私鑰和公鑰。私鑰是一個秘密號碼,允許所有者將比特幣發(fā)送給另一個用戶,或者消費比特幣。公鑰是接收比特幣所需的數(shù)字。錢包本身不存儲比特幣,有關比特幣余額的信息存儲在比特幣的區(qū)塊鏈中。

  2. 創(chuàng)建比特幣交易。如果Alice想要向Bob發(fā)送1個比特幣,Alice需要使用她的私鑰連接到她的比特幣錢包,并創(chuàng)建一個包含她想要發(fā)送的比特幣數(shù)量和地址的交易。

  3. 將交易廣播到比特幣網(wǎng)絡。一旦Alice創(chuàng)建比特幣交易,她需要將此交易廣播到整個比特幣網(wǎng)絡。

  4. 確認交易。收聽到比特幣網(wǎng)絡的礦工使用Alice的公鑰驗證交易,確認Alice的錢包中有足夠的比特幣,并向比特幣區(qū)塊鏈添加一條包含交易詳細信息的新紀錄。

  5. 將區(qū)塊鏈的變更廣播給所有礦工。 一旦交易得到確認,該礦工應向所有礦工廣播區(qū)塊鏈變更,以確保他們的區(qū)塊鏈副本全部同步。

區(qū)塊鏈技術深度研究

為深入研究區(qū)塊鏈技術構建模塊,作者系統(tǒng)介紹了公鑰密碼學,Hash函數(shù)和區(qū)塊鏈挖掘及安全性等。

公鑰密碼學

公鑰密碼學或非對稱加密學是任何使用密鑰對的加密系統(tǒng):包括可以廣泛傳播的公鑰,以及只有所有者知道的私鑰。 這實現(xiàn)了兩個基本功能:

  • 身份驗證:公鑰驗證發(fā)送消息的配對私鑰的持有者

  • 加密:只有配對的私鑰持有者可以解密用公鑰加密的消息。

RSA和ECDSA(橢圓曲線數(shù)字簽名算法)是最流行的公鑰加密算法,ECDSA算法用于生成比特幣錢包。

為了發(fā)送或接收BTC,用戶首先生成包含一對私鑰和公鑰的錢包。

如果Alice想要向Bob發(fā)送一定數(shù)量的BTC,她會創(chuàng)建一個交易,在該交易中輸入她和Bob的公鑰以及她想要發(fā)送的BTC數(shù)量,然后使用她的私鑰簽署交易。

區(qū)塊鏈上的計算機使用Alice的公鑰來驗證交易是否可信,并將交易寫入即將添加到區(qū)塊鏈的區(qū)塊中。

Hash函數(shù)和挖掘

所有比特幣交易都存儲在稱為區(qū)塊的文件中。比特幣每10分鐘增加一個新的交易區(qū)塊,將新區(qū)塊添加到區(qū)塊鏈后,它將不可變、無法刪除和修改。

網(wǎng)絡中一組特殊的參與者稱為礦工(連接到區(qū)塊鏈的計算機),負責創(chuàng)建新的交易區(qū)塊。礦工必須使用發(fā)件人的公鑰對每筆交易進行身份驗證,確認發(fā)件人有足夠的余額用于所請求的交易,并將交易添加到塊中。

礦工可以完全自由選擇區(qū)塊中的交易,因此發(fā)件人需要包含交易費以激勵礦工將他們的交易添加到區(qū)塊中。

對于區(qū)塊鏈接受的區(qū)塊,需要進行“挖掘”。為了挖掘區(qū)塊,礦工需要找到一種非常罕見的加密難題解決方案。如果區(qū)塊鏈接受了采礦區(qū)塊,則礦工將獲得比特幣獎勵,這是對交易費用的額外獎勵。挖掘過程也稱為工作量證明(PoW),它是使區(qū)塊鏈無信任和安全的主要機制。

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

哈希函數(shù)是任何可以用來將任意大小的數(shù)據(jù)映射到固定大小的數(shù)據(jù)的函數(shù)。哈希函數(shù)返回的值稱為Hash值。哈希函數(shù)通常用于通過檢測重復的記錄來加速數(shù)據(jù)庫查找,它們在密碼學中也被廣泛使用。

哈希函數(shù)允許我們輕松地驗證某些輸入數(shù)據(jù)映射到給定的散列值,但是如果輸入數(shù)據(jù)是未知的,那么通過存儲的散列值來重構它是很困難的。

比特幣使用稱為SHA-256的加密哈希函數(shù)。SHA-256應用于區(qū)塊數(shù)據(jù)(比特幣交易)和名為Nonce的數(shù)字組合。通過更改區(qū)塊數(shù)據(jù)或Nonce,我們得到完全不同的Hash值。

對于被認為有效或“已挖掘”的區(qū)塊,區(qū)塊和Nonce的Hash值需要滿足特定條件。例如,Hash值的四個前導數(shù)字需要等于“0000”。 我們可以通過使條件更復雜來增加挖礦的復雜性,例如我們可以增加Hash值開頭0的數(shù)量。

礦工需要解決的密碼難題是找到一個Nonce值,使Hash值滿足挖掘條件。

使用下面的應用程序來模擬區(qū)塊挖掘。

當你在“Data”文本框中輸入或更改Nonce值時,你會注意到Hash值的變化。 當你單擊“Mine”按鈕時,應用程序從Nonce等于零開始,計算Hash值并檢查Hash值的前四位是否等于“0000”。

如果前四位數(shù)不等于“0000”,則將Nonce增加1并重復整個過程,直到找到滿足條件的Nonce值。如果區(qū)塊已開采,背景顏色變?yōu)榫G色。

從區(qū)塊到區(qū)塊鏈

交易按區(qū)塊分組,區(qū)塊被附加到區(qū)塊鏈。

為了創(chuàng)建一條由區(qū)塊組成的鏈,每個新塊使用前一個塊的Hash值作為其數(shù)據(jù)的一部分。為了創(chuàng)建新塊,礦工選擇一組交易,添加前一個塊的Hash值開始區(qū)塊挖掘工作。

對任何區(qū)塊數(shù)據(jù)進行的任何更改都將影響其后所有區(qū)塊的Hash值,并且它們將變?yōu)闊o效,這就是區(qū)塊鏈的不變性。

使用下面的應用程序模擬包含3個區(qū)塊的區(qū)塊鏈。

當你在“Data”文本框中輸入或更改Nonce值時,你可以注意到當前區(qū)塊Hash值以及下一區(qū)塊的“Prev”值(上一個Hash值)的變化。

你可以通過單擊每個塊的“Mine”按鈕來模擬挖礦過程。挖掘出3個區(qū)塊之后,嘗試更改塊1或2中的數(shù)據(jù),你將注意到之后的所有區(qū)塊都變?yōu)闊o效。

將區(qū)塊添加到區(qū)塊鏈

比特幣網(wǎng)絡中的所有礦工互相競爭,以找到一個有效的區(qū)塊,該區(qū)塊將被添加到區(qū)塊鏈并從網(wǎng)絡獲得獎勵。

雖然找到驗證區(qū)塊Nonce幾率很低,但由于礦工的數(shù)量很多,網(wǎng)絡中礦工驗證區(qū)塊的概率非常高。第一個提交有效區(qū)塊的礦工將他的區(qū)塊添加到區(qū)塊鏈中并獲得比特幣的獎勵。

如果兩個礦工或更多的礦工同時提交,會發(fā)生什么呢?

解決沖突

如果2名礦工幾乎同時解決一個區(qū)塊,那么我們將在網(wǎng)絡中有2個不同的區(qū)塊鏈,我們需要等待下一個區(qū)塊來解決沖突。 一些礦工選擇在區(qū)塊鏈1頂部挖掘,其他礦工選擇在區(qū)塊鏈2頂部挖掘。

當有礦工找到一個新的區(qū)塊之后,沖突就被解決了。

如果新區(qū)塊在區(qū)塊鏈1的頂部被挖掘出來,則區(qū)塊鏈2變?yōu)闊o效,前一區(qū)塊的獎勵通過區(qū)塊鏈1獎勵給礦工,區(qū)塊鏈2部分和未添加到區(qū)塊鏈中的交易將被退回到交易池并添加到下一個塊。

簡而言之,如果區(qū)塊鏈存在沖突,那么最長的鏈就會獲勝。

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

接下來,詳細介紹對區(qū)塊鏈進行雙重支付攻擊的常見形式,以及用戶為防止受到損害應采取的措施。

  • 種族攻擊:攻擊者將相同的硬幣快速發(fā)送到兩個不同的地址。為防止此類攻擊,建議在接受付款前等待至少一次區(qū)塊確認。

  • 芬尼攻擊:攻擊者使用交易預先挖掘區(qū)塊,并在釋放區(qū)塊之前在第二個交易中花費相同的幣。 在這種情況下,將不驗證第二個交易。為防止此類攻擊,建議在接受付款前等待至少6次區(qū)塊確認。

  • 51%攻擊:在這類攻擊中,攻擊者擁有網(wǎng)絡51%的算力。攻擊者首先向整個網(wǎng)絡廣播進行交易,然后挖掘一個私有區(qū)塊鏈,在那里將上一筆交易的幣加倍。

    由于攻擊者擁有大部分算力,因此保證他在某些時候會擁有比正常網(wǎng)絡更長的鏈。然后,他可以發(fā)布更長的區(qū)塊鏈,取代正常區(qū)塊鏈并取消原始交易。

    這種攻擊極不可能,因為它在像比特幣這樣的區(qū)塊鏈網(wǎng)絡中非常昂貴。

Python中的區(qū)塊鏈實現(xiàn)

在本節(jié)中,我們將使用Python實現(xiàn)基本的區(qū)塊鏈和區(qū)塊鏈客戶端。

區(qū)塊鏈將具有以下功能:

  • 在區(qū)塊鏈中添加多個節(jié)點

  • 工作量證明(PoW)

  • 節(jié)點之間的簡單沖突解決方案

區(qū)塊鏈客戶端將具有以下功能:

  • 使用公鑰/私鑰加密生成錢包(基于RSA算法)

  • 使用RSA加密生成交易

還將實現(xiàn)2個顯示頁:

  • 供礦工使用的“區(qū)塊鏈前端”

  • 供用戶生成錢包和發(fā)送數(shù)字貨幣的“區(qū)塊鏈客戶端”

本文區(qū)塊鏈實現(xiàn)主要參考下面的GitHub項目,作者對原始代碼進行了一些修改,以便為交易添加RSA加密。

使用Jupyter notebook生成電子錢包,進行加密交易,使用HTML / CSS / JS2完成2個顯示頁。

區(qū)塊鏈客戶端

切換到blockchain_client文件夾下,在終端輸入python blockchain_client.py,啟動區(qū)塊鏈客戶端。在瀏覽器中,轉(zhuǎn)到http:// localhost:8080,你將看到下面的顯示頁面。


顯示頁面在導航欄中有3個選項卡:

  • Wallet Generator:使用RSA加密算法生成錢包(公鑰/私鑰對)

  • Make Transaction:生成交易并將其發(fā)送到區(qū)塊鏈節(jié)點

  • View Transasctions:查看區(qū)塊鏈上的交易

要創(chuàng)建或查看交易,你至少需要運行一個區(qū)塊鏈節(jié)點。

下面,對blockchain_client.py代碼重要的部分進行解釋。

定義一個名為Transaction的python類,它有 sender_address,sender_private_key,recipient_address 和 value 4個屬性。這些是發(fā)件人創(chuàng)建交易所需的4條信息。

使用to_dict()方法以Python字典格式(沒有發(fā)件人的私鑰)返回交易信息。

通過使用 sign_transaction()方法獲取交易信息(沒有發(fā)件人的私鑰),并使用發(fā)件人的私鑰對其進行簽名。

啟動一個Python Flask應用程序,使用它來創(chuàng)建不同的API,與區(qū)塊鏈及其客戶端進行交互。

下面定義3個Flask html頁面返回路徑,每個標簽連接一個html頁面。

然后,定義一個生成錢包的API(私鑰/公鑰對)。

下面定義一個API,將sender_address,sender_private_key,recipient_address,value 作為輸入項,并返回交易(沒有私鑰)和簽名。

區(qū)塊鏈

轉(zhuǎn)到blockchain文件夾從終端啟動區(qū)塊鏈節(jié)點,然后鍵入python blockchain_client.py或python blockchain_client.py -p <PORT NUMBER>。如果未指定端口號,則默認為端口5000。在瀏覽器中,轉(zhuǎn)到http:// localhost:<PORT NUMBER>查看區(qū)塊鏈前端顯示頁。

導航欄下顯示頁有2個選項卡:

  • Mine:用于查看交易和區(qū)塊鏈數(shù)據(jù),以及挖掘新的交易區(qū)塊。

  • Configure:用于配置不同區(qū)塊鏈節(jié)點之間的連接。

接下來,對blockchain.py代碼中重要部分進行解釋。

首先定義一個具有以下屬性的Blockchain類:

  • transactions:將添加到下一區(qū)塊的交易列表。

  • chain:由一系列區(qū)塊組成的區(qū)塊鏈。

  • nodes:包含節(jié)點url的集合。區(qū)塊鏈使用這些節(jié)點從其他節(jié)點檢索區(qū)塊鏈數(shù)據(jù),如果它們不同步則更新其區(qū)塊鏈。

  • node_id:用于標識區(qū)塊鏈節(jié)點的隨機字符串。

Blockchain類還實現(xiàn)了以下方法:

  • register_node(node_url):將新的區(qū)塊鏈節(jié)點添加到節(jié)點列表中。

  • verify_transaction_signature(sender_address, signature, transaction):檢查提供的簽名是否與公鑰(sender_address)簽名的交易相對應。

  • socmit_transaction(sender_address,recipient_address,value,signature):如果簽名已驗證,則將交易添加到交易列表中。

  • create_block(Nonce,previous_hash):向區(qū)塊鏈添加一個包含交易信息的區(qū)塊。

  • hash(block):創(chuàng)建一個區(qū)塊的SHA-256 Hash值。

  • proof_of_work():工作量證明。尋找滿足挖掘條件的Nonce。

  • valid_proof(transactions,last_hash,Nonce,difficulty = MINING_DIFFICULTY):檢查Hash值是否滿足挖掘條件,此函數(shù)在proof_of_work函數(shù)中使用。

  • vaid_chain(chain):檢查區(qū)塊鏈是否有效。

  • resolution_conflicts():通過用網(wǎng)絡中最長的鏈替換鏈來解決區(qū)塊鏈節(jié)點之間的沖突。

啟動一個Python Flask應用程序,使用它創(chuàng)建不同的API以與區(qū)塊鏈進行交互。

接下來,啟動Blockchain實例。

定義2條返回區(qū)塊鏈前端html頁面的Flask路徑。

下面定義Flask API來管理交易和挖掘區(qū)塊鏈。

  • '/ transactions / new':此API用來輸入 'sender_address', 'recipient_address','amount'和'signature',并將交易添加到簽名有效的、可添加到下一區(qū)塊的交易列表中。

  • '/ transactions / get':此API返回可以被添加到下一區(qū)塊的所有交易。

  • '/ chain':此API返回所有區(qū)塊鏈數(shù)據(jù)。

  • '/ mine':此API運行工作量證明算法,并將新的交易塊添加到區(qū)塊鏈中。


下面定義Flask API來管理區(qū)塊鏈節(jié)點。

  • '/ nodes / register':此API將節(jié)點URL列表作為輸入,并將它們添加到節(jié)點列表中。

  • '/ nodes / resolve':此API通過用網(wǎng)絡中可用的最長鏈替換本地鏈來解決區(qū)塊鏈節(jié)點之間的沖突。

  • '/ nodes / get':此API返回節(jié)點列表。

數(shù)據(jù)分析咨詢請掃描二維碼

若不方便掃碼,搜微信號:CDAshujufenxi

數(shù)據(jù)分析師資訊
更多

OK
客服在線
立即咨詢
客服在線
立即咨詢
') } function initGt() { var handler = function (captchaObj) { captchaObj.appendTo('#captcha'); captchaObj.onReady(function () { $("#wait").hide(); }).onSuccess(function(){ $('.getcheckcode').removeClass('dis'); $('.getcheckcode').trigger('click'); }); window.captchaObj = captchaObj; }; $('#captcha').show(); $.ajax({ url: "/login/gtstart?t=" + (new Date()).getTime(), // 加隨機數(shù)防止緩存 type: "get", dataType: "json", success: function (data) { $('#text').hide(); $('#wait').show(); // 調(diào)用 initGeetest 進行初始化 // 參數(shù)1:配置參數(shù) // 參數(shù)2:回調(diào),回調(diào)的第一個參數(shù)驗證碼對象,之后可以使用它調(diào)用相應的接口 initGeetest({ // 以下 4 個配置參數(shù)為必須,不能缺少 gt: data.gt, challenge: data.challenge, offline: !data.success, // 表示用戶后臺檢測極驗服務器是否宕機 new_captcha: data.new_captcha, // 用于宕機時表示是新驗證碼的宕機 product: "float", // 產(chǎn)品形式,包括:float,popup width: "280px", https: true // 更多配置參數(shù)說明請參見:http://docs.geetest.com/install/client/web-front/ }, handler); } }); } function codeCutdown() { if(_wait == 0){ //倒計時完成 $(".getcheckcode").removeClass('dis').html("重新獲取"); }else{ $(".getcheckcode").addClass('dis').html("重新獲取("+_wait+"s)"); _wait--; setTimeout(function () { codeCutdown(); },1000); } } function inputValidate(ele,telInput) { var oInput = ele; var inputVal = oInput.val(); var oType = ele.attr('data-type'); var oEtag = $('#etag').val(); var oErr = oInput.closest('.form_box').next('.err_txt'); var empTxt = '請輸入'+oInput.attr('placeholder')+'!'; var errTxt = '請輸入正確的'+oInput.attr('placeholder')+'!'; var pattern; if(inputVal==""){ if(!telInput){ errFun(oErr,empTxt); } return false; }else { switch (oType){ case 'login_mobile': pattern = /^1[3456789]\d{9}$/; if(inputVal.length==11) { $.ajax({ url: '/login/checkmobile', type: "post", dataType: "json", data: { mobile: inputVal, etag: oEtag, page_ur: window.location.href, page_referer: document.referrer }, success: function (data) { } }); } break; case 'login_yzm': pattern = /^\d{6}$/; break; } if(oType=='login_mobile'){ } if(!!validateFun(pattern,inputVal)){ errFun(oErr,'') if(telInput){ $('.getcheckcode').removeClass('dis'); } }else { if(!telInput) { errFun(oErr, errTxt); }else { $('.getcheckcode').addClass('dis'); } return false; } } return true; } function errFun(obj,msg) { obj.html(msg); if(msg==''){ $('.login_submit').removeClass('dis'); }else { $('.login_submit').addClass('dis'); } } function validateFun(pat,val) { return pat.test(val); }