官术网_书友最值得收藏!

第2節
代碼創富的技術邏輯與技術框架:比特幣運行機制解析

一、比特幣交易

比特幣交易分為三部分:元數據、一系列輸入和一系列輸出。元數據存放內部處理信息,包含這筆交易的規模、輸入數量、輸出數量和哈希值,也是這個交易獨一無二的ID,并有時間戳證明;所有輸入排成一個序列,每個輸入格式一樣,包括之前那筆交易的哈希值、之前交易的輸出索引(從0開始)、數字簽名;所有輸出排成一個序列,要和特定公鑰(地址)對應,所有輸出的金額之和必須小于或等于輸入金額之和,二者差額部分作為交易費(激勵)支付給為這筆交易記賬的礦工。

舉例說明,圖2-8所示為與比特幣類似基于交易的賬本。

圖2-8 與比特幣類似基于交易的賬本

其一,地址轉換。由某個交易輸出的比特幣,要么在另一個交易被完全消費掉,要么一個都不被消費,不存在只消費部分的情況。交易1中愛麗絲獲得了25個比特幣,交易2中她必須把這25個比特幣全部消費掉,所以她把17個比特幣轉給鮑勃,剩下8個幣轉給自己,而這8個幣可以轉到另外一個愛麗絲所有的地址(不同于交易1中獲得25個幣的地址)。

其二,有效驗證。當新交易被加入總賬本,比特幣網絡要驗證這25個比特幣之前有沒有被花費掉,只需要從愛麗絲所引用的交易開始,一直核查到賬本上最新記錄的交易為止,而不需要從賬本建立之初的交易開始核查,這樣可以大大提高效率。

其三,資金合并。只需要發起一個交易,交易里有兩個輸入和一個輸出,輸出地址就是所得比特幣(收益)。

我們列出一個真實的比特幣交易程序段來闡釋比特幣交易三個部分。

二、比特幣腳本

大部分比特幣腳本都非常基礎,每個交易輸出不僅要確定一個公鑰,同時還要指定一個腳本(輸入腳本和輸出腳本)。為了確認一筆交易正確獲取了上一筆交易所輸出資金(比特幣),網絡必須把交易輸入腳本和上一筆交易輸出腳本串聯起來,只有在當前交易這個串聯腳本被成功執行后才可獲取資金(比特幣)。輸出腳本指定一個公鑰(或是公鑰哈希值地址),輸入腳本也會指定一個對應公鑰的簽名。

常見比特幣腳本如下。

OP_DUP
OP_HASH160
69e02e18……
OP_EQUALVERIFY
OP_CHECKSIG

比特幣腳本語言是堆棧式、線性、無法循環執行和非圖靈完備[1]的,只有256個指令。每個指令只有1個字節,只能被執行一次。因此,指令數目的執行時間和內存使用上限被硬性規定下來。礦工執行網絡任一交易者遞交的腳本,但設計者并不希望他們提交可能無限循環的腳本。

輸入腳本和輸出腳本舉例如下,虛線下方是上一筆交易的輸出腳本,虛線上方是當前交易的輸入腳本,二者鏈接起來就成為一個新腳本。

<sig>
<pubKey>
————————————————————
OP_DUP
OP_HASH160
<pubKeyHash>
OP_Equalverify
OP_CHECKSIG

一些比特幣腳本工作語言中的指令及其功能見表2-4。

表2-4 一些比特幣腳本工作語言中的指令及其功能

在堆棧中執行一個腳本,只需要一個堆棧來累積數據,不需要分配內存和變量,因而堆棧語言只有兩類指令(數據指令、工作指令)計算相對較為容易。數據指令用于把數據推到堆棧頂部。工作指令用于將堆棧頂部數據作為輸入值,用來計算某個函數。

執行腳本過程如下:前兩條指令是數據指令,分別是輸入腳本簽名和用來驗證簽名的公鑰,直接把它們堆到堆棧最上面。接著執行復制指令OP_DUP,將堆棧最上層的公鑰復制,并置于堆棧最上層。下一個指令是OP_HASH160,該指令取得最上層數據,并計算其哈希值,然后將結果再堆到堆棧最上層。接下來,執行pubkeyHash指令,將發送者指定的公鑰哈希值堆到堆棧最上面。這時候,執行OP_EQUALVERIFY指令,檢查堆棧頂部的兩個數值是否相等,假設相等,也就代表接受者使用的是正確公鑰,這條指令會移除堆棧頂部的兩條數據。同時使用OP_CHECKSIG來檢查簽名,假如沒有碰到任何差錯,這個腳本輸出的就是TRUE。腳本執行堆棧狀態如圖2-9所示。

圖2-9 比特幣腳本的執行堆棧狀態圖

比特幣“銷毀證明腳本”(proof of burn)也應給予關注,如果交易代碼運行結果是將比特幣轉到“銷毀證明腳本”,那么這筆比特幣將被銷毀,在實際應用中它主要被用來引導用戶使用其他加密數字貨幣系統。

三、比特幣腳本的應用

比特幣有較完善的技術手段(腳本、礦工、交易驗證等)保證強制執行全網共識的智能合約,而非通過法律、仲裁等中心化權威機構。

1.第三方支付交易(escrow transaction)

比特幣第三方支付交易可以用“多重簽名”(MULTISIG)實現。只要網絡2/3用戶簽名,比特幣即可完成點對點支付,并納入全網監管。如果支付過程中出現爭議,同樣是2/3用戶簽名支持的那一方得到權益保障。

2.綠色地址(green addresses)

如果小王要將某筆比特幣轉賬給小李,但是小李沒有在線或者當時沒有時間處理,無法通過查看比特幣網絡更新來確認小王轉賬是否完成。一般情況下,小王可以等待小李和網絡確認,但是如果小王轉賬的目的是購買商品等用途,可能就無法等那么長時間。

為了解決這個時延問題,比特幣采取了第三方交易所等金融媒介方式,交易方式從點對點改為了第三方參與。小王通知交易所需要轉賬給小李,如果小李在交易所也有賬戶,那么交易所從小王賬戶扣取費用,從交易所綠色地址轉賬給小李,而小李不需要實時查看交易所賬戶和比特幣網絡來確認交易。當然,小王和小李要信任交易所簽名的交易,交易所也要保證不會進行雙重支付等造假行為。另外,如果收款人小李信任交易所,他就無須信任轉賬人小王,這就實現了雙方的無須信任交易。

Base58是比特幣的一種特殊編碼方式,主要用于產生比特幣錢包地址。相比Base64等其他編碼方式,Base58不使用數字“0”、字母大寫“O”、字母大寫“I”、字母小寫“i”“+”和“/”符號,采用數學經常使用的進制轉換方法——輾轉相除法。

Base58設計的主要目的如下。

①避免混淆,在某些字體下,數字0和字母大寫O,以及字母大寫I和字母小寫i會非常相似。

②Base64編碼中包含“+”和“/”,非字母或數字的字符串作為賬號較難被接受。

③在郵件系統中,使用字符和數字的組合不容易換行。

④大部分軟件支持雙擊選中整個字符串。

比特幣使用Base58算法對公鑰Hash160及私鑰編碼,從而生成以1或者3開頭的比特幣地址,以及WIF(Wallet Import Format)格式的私鑰。

3.高效小額支付(efficient micro-payments)

如果小王是小李的客戶,需要持續向小李支付小額費用(比特幣),但多次小額支付會產生較大網絡流量費和交易手續費,解決方案是將多次小額費用累積起來,最后一次性支付。

小王先發起一個MULTISIG交易,把可能花費的最大金額先轉到MULTISIG地址,這個交易需要小王和小李兩個人簽名才有效。小王在每次轉賬時簽名一次,直到所有轉賬完成,這些轉賬交易只有小王簽名,小李沒有簽名,因而沒有放到比特幣網絡記賬。小李在小王最后一筆轉賬里簽名,并把小王所有轉賬信息記賬到比特幣網絡。

4.退款鎖定時間

如果小王所有轉賬完成后,小李沒有在最后一筆轉賬里簽名,那么小王轉給小李的比特幣可能會存放入第三方交易所,損失掉他轉到MULTISIG地址的所有比特幣。為了解決這個問題,小王和小李需要預先約定退款鎖定時間。比特幣元數據有一個參數“lock_time”,在此參數上可以填寫具體時間值t。這個值告訴礦工在記賬時,需要經過確定的t時間才能記賬到比特幣網絡,這筆挖礦方能生效,這個技術就解決了退款的鎖定時間問題。

小王發起MULTISIG交易,陸續把比特幣轉入第三方交易所托管,如果過了退款鎖定時間,小李還沒有在最后一個轉賬交易里簽字,小王則可以通過這個退款交易指令收回已轉賬的所有比特幣。

四、比特幣網絡

比特幣網絡底層是一個運行在TCP網絡上的點對點網絡,有一個隨機拓撲結構,在規則和技術上實現了所有節點平等,沒有權限更高的主節點(超級節點),每個節點和其他隨機節點相連,節點之間不需要信任,但可在比特幣網絡完成可信交易。每個節點既是服務者(如礦工),也是消費者。新節點隨時可以加入,舊節點隨時可以離開,因此比特幣網絡一直處于動態變化。比特幣網絡底層結構示意圖如圖2-10所示。

圖2-10 比特幣網絡底層結構示意圖

隨著比特幣網絡發展,各地又出現了公共節點。2018年3月,公共節點達到歷史峰值的11083個。排名前十名地區共有公共節點7792個,占總公共節點總數的79.3%,美國、德國,法國位列前三。比特幣網絡公共節點主要分布見圖2-11。

圖2-11 比特幣網絡公共節點主要分布

用戶發起一個交易,需要通過洪泛算法[2](flooding algorithm)讓整個比特幣網絡都知道。小王要轉賬比特幣給小李,小王在客戶端發起一個交易,把這個交易告訴與小王(節點)相連接的其他節點,這些節點核驗后,決定是否轉播這筆交易。如果核驗通過,這些與小王相連接的節點會將交易轉播給與其連接的節點。以此類推,直到小李接收這筆轉賬并在區塊和網絡記賬。需要注意的是,在小李還沒有確認前,每個節點會有一個交易池將接收的轉播交易信息儲存,但不會記賬到比特幣網絡,只是用于避免這個交易在網絡不停轉播帶來的效率降低和數據冗余。

每個節點收到一筆新交易信息時,會有四個環節核驗:一是交易驗證,針對每個前序交易輸出,運行核驗腳本;二是檢查是否有雙重支付;三是檢查該交易信息在之前是否被接收過,默認保留最早接收的交易信息。用戶也可以自行操作保留和轉播收到的歷次交易信息,如2013年以來有礦工為了獲得更高收益,遇到交易沖突時,將手續費高的交易放入自己的交易池,將手續費低的交易替換出去;四是只接收和傳播白名單標準腳本。

區塊傳播與交易傳播類似。礦工挖到比特幣,打包一個區塊,將區塊加入比特幣網絡,傳播給該礦工相連接節點,以此類推轉播出去。如果某個區塊同時被多名礦工挖到,只有其中一個區塊可以加入比特幣網絡,其他區塊則被丟棄。哪個區塊被確認取決于其他節點的共識和轉播。

完全有效節點必須長期在線,才能接收比特幣網絡所有交易數據。一個節點離線時間越長,其保存的交易數據就越不完整。由于離線期間無法執行交易,只有重新上線后,把缺省交易數據重新下載更新,才能確保在比特幣網絡的所有權益(如交易、轉播交易信息等),同時也會消耗較長時間。比特幣網絡完整交易數據(區塊鏈)的存儲空間在2016年年初已經超過50G,到今天已是龐大的數據量。

由于完全有效節點存儲空間過大,用戶難以實現快速查看、運行、核驗腳本,也就出現了輕量節點(Lightweight Nodes),也稱簡單轉賬驗證(Simple Payment Verification,簡稱SPV節點)。SPV節點通過某個比特幣錢包軟件實現,不會存儲比特幣網絡所有交易數據,而是只下載和存儲與用戶有關的、用戶關心的、需要核驗的部分交易數據。

SPV節點的優勢在于節省了大量存儲空間,只需要幾十MB存儲空間即可,一部智能手機下載比特幣錢包軟件就能操作,但是SPV節點的安全性不如完全節點,不能核驗某個區塊所有交易的歷史記錄,因而只能依賴完全節點去核驗沒有存儲的其他交易。

比特幣網絡是一個開源協議網絡,由使用C++、Go等不同語言編寫的不同軟件系統無縫交互,兼容性強,即使部分軟件出現問題,也不至于影響整個網絡。為了確保交易及時有效,大部分節點會調用比特幣早期核心代碼開發者用C++語言編寫的資源數據庫(Bitcoind Library)。

由于比特幣投資人、礦工、用戶投入很大,規則改變的負面影響也會很大,那么比特幣總數量和挖礦記賬獎勵也可能長期不變,但是比特幣交易處理能力和效率急需提升。按照中本聰的白皮書,比特幣區塊大小限定在1MB,每個交易占用空間大致為250字節,每個區塊最多容納4000個交易。平均每隔10分鐘有一個礦工獲得記賬權利,所以每秒只能處理7個交易,效率遠低于以太坊等其他加密數字貨幣和銀行等傳統金融機構的記賬能力。

如果要引入一些新特性來改善效率,則需要修改比特幣規則協議,在操作上會非常復雜,很難判斷所有節點都會達成共識并更新版本。修訂協議分為硬分叉、軟分叉兩種類型。

硬分叉指通過修改協議引入新特性,可能使之前協議失效,造成運行新協議的節點認定有效的區塊會被運行舊協議的節點認為無效,就會使比特幣網絡產生分裂,所有節點根據運行協議版本的不同擴展為兩條不同的區塊鏈(兩個網絡)。比特幣現金就是硬分叉的典型案例。比特幣硬分叉示意圖如圖2-12所示。

圖2-12 比特幣硬分叉示意圖

如果比特幣網絡共識規則改變后,這種改變是向前兼容的,舊節點可以兼容新節點產生區塊,則不會擴展為兩條不同的區塊鏈,即為軟分叉。新規則下產生的區塊會被舊節點接受,舊節點只是無法識別新規則的真實意義,新舊節點仍然處于同一條區塊鏈,對整個系統的影響相對較小。

五、比特幣的存儲和使用

1.用戶自己存儲和管理比特幣

用戶把比特幣存放在個人電腦、手機等聯網智能終端,這是熱存儲方式,方便但不安全。將比特幣存儲在離線智能終端,這是冷存儲方式,相對更加安全,但使用起來不方便。用戶要有效區分和管理熱存儲、冷存儲,需使用不同的私鑰和地址。由于冷存儲不在線,熱存儲必須通過相應技術手段找到冷存儲地址,兩者才能進行轉賬。

目前用得較多的解決方法是使用分層確定性地址機制的電子錢包(分層確定性錢包,Hierarchical Deterministic Wallet),它通過橢圓曲線密碼學機制,在確保沒有私鑰參與的情況下,將公鑰直接分散成子公鑰,并且分散子公鑰可以由分散子私鑰認證,也就是冷存儲端制造多個地址,并且熱存儲端能夠知曉其制造的所有地址。

2.用戶通過第三方機構提供服務來存儲和管理比特幣

一些專業公司為用戶提供“在線錢包”服務。用戶將密鑰、交易等比特幣的存儲、管理等信息上傳到云端服務器,通過網頁或者APP客戶端操作。由于在線錢包第三方運營公司存儲了用戶的比特幣密鑰,用戶使用在線錢包登錄密碼保護密鑰,所以用戶需要信任第三方公司,并與之約定責權利。在線錢包的優勢是方便,風險在于第三方公司及其技術人員掌握密鑰,可能存在安全隱患。

一些比特幣交易所也提供比特幣存儲服務,類似于銀行存款業務,用戶將比特幣存儲到交易所,以便在將來某個時間需要時提取比特幣,或者兌換成法幣。用戶在交易所完成上述操作時,比特幣網絡并不會記錄任何交易,交易所不需要在網絡將比特幣從一個地址轉移到另一個地址,交易所和用戶只需要簽署和修改智能合約。交易所提供比特幣存儲服務的風險在于擠兌、黑客入侵、借新還舊等。

部分交易所會公開用戶比特幣存儲信息,如公布用戶姓名、比特幣數量、市值等,用戶據此可以計算交易所的存儲規模(也可以理解為交易所需要兌付的負債規模),不過這種模式也存在用戶隱私信息泄露、交易所瞞報假報信息等問題,因而一些交易所采取梅克爾樹來描述用戶比特幣存儲規模(也稱為負債證明,Proof of Liabilities)。

技術原理如下:交易所構建一個梅克爾二叉樹,每個葉節點為一個用戶(儲戶),每個葉節點添加一個存儲金額字段。每個葉節點存儲金額字段保存用戶比特幣存儲數量。每個節點存儲金額字段等于最相鄰兩個子節點存款金額之和,根節點存儲金額字段代表比特幣存儲總數量。用戶可以要求交易所證明自己在梅克爾樹上,以此判斷自己的比特幣是否安全。負債證明如圖2-13所示。

圖2-13 交易所梅克爾二叉樹負債證明

交易所構建完梅克爾樹負債證明后,把根節點(用戶)哈希指針和存儲金額字段進行加密簽名,然后在比特幣網絡廣播,并且聲明交易所的所有用戶都可以對應到葉節點,所有存儲數據都是準確的,那么根節點存儲金額字段就是用戶在交易所的比特幣存儲規模和交易所負債證明。

3.交易費用

交易費用是用于補償交易所、支付商、礦工處理某筆交易所付出的代價,具體金額可以由發起交易方自行設定,也可以采取鏈上用戶提供的參考標準。用戶支付交易費越高,其交易數據就會被更快、更安全地轉播和記賬。2015年以前,交易費在礦工收入中占比不到1%,因而大部分用戶并不在意交易費收入和支出,但隨著挖礦難度加大、挖礦獎勵降低,交易費占比不斷上升。目前,很多比特幣錢包、交易所等第三方服務商都會收取標準化交易費用,用戶的每筆交易都要繳納一定比例的交易費。收取交易費成為第三方服務商的主要營收。

[1] 圖靈完備:如果一門編程語言、一個指令集可實現圖靈機模型里面的全部功能,或者說能夠滿足任意數據按照一定順序計算出結果,就可稱其具有圖靈完備性。

[2] 洪泛算法:不要求維護網絡拓撲結構和相關路由計算,僅要求接收到信息的節點以廣播方式轉發數據包。例如,源節點希望發送一段數據給目標節點,源節點首先通過網絡將數據副本傳送給它的每個鄰居節點,每個鄰居節點再將數據傳送給各自除發送數據來的節點之外的其他鄰居節點。如此繼續下去,直到數據傳送至目標節點或者數據設定的生存期限到0為止。

主站蜘蛛池模板: 蓝田县| 河曲县| 东阳市| 云梦县| 蓝田县| 亳州市| 商洛市| 鞍山市| 高密市| 西安市| 宁武县| 平和县| 津南区| 南昌县| 郑州市| 团风县| 罗平县| 泾阳县| 洛隆县| 松原市| 安徽省| 洛阳市| 乐安县| 塔河县| 沂南县| 将乐县| 横峰县| 洞头县| 安顺市| 娱乐| 新泰市| 屏南县| 东海县| 鹿泉市| 自贡市| 南昌县| 清涧县| 大田县| 锡林浩特市| 玉山县| 盘山县|