《Master Bitcoin》學習筆記02——比特幣的交易模型


 

比特幣的交易模型

模型基本描述

  前面一篇學習筆記01提到了一個交易模型(第三章的內容),在第五章中,除了對這個模型做個詳細介紹之外,其實和我上一篇理解的交易模型差不多,一個交易包含輸入與輸出,比特幣是在各個地址之間轉移,不想中心化系統例如銀行有個服務器,記錄了每個人的賬戶,賬戶這個結構體包含:交易記錄,賬戶余額等一切信息,但是在比特幣交易網絡這種去中心化的體系中,比特幣的交易記錄,一個賬戶擁有多少比特幣等信息存儲在了區塊鏈中,要像銀行賬戶一樣,查詢自己賬戶的相關信息,只能通過查區塊鏈中的區塊獲取,就像從數據庫里查詢數據一樣,就像下面比特幣的交易模型描述。

  模型圖有幾個重點:

  • 個人可用的比特幣是以賬單形式存在的,在發起交易時,查詢區塊鏈中個人可用賬單(賬單輸出賬戶是你),使用賬單來支付相應比特幣,產生輸出,實際上,是比特幣在比特幣地址之間的轉移。
  • 本次交易的輸入就是上次交易輸出,比特幣賬戶(地址)查詢余額和交易,就是對區塊鏈里賬單里對你賬戶輸出的查詢(上圖中,對A可支配比特幣的查詢賬單輸出:退給A的金額,對B可支配比特幣的查詢賬單輸出:轉賬給B的金額)
  • 本次交易的輸入可以只有一張賬單的輸出(如果這張賬單上的比特幣足夠),也可以包含幾張賬單的輸出(幾張賬單加起來比特幣>=此次需要支付金額),注意到,上面的>=比交付,因為不太可能利用已有賬單完全無誤差地湊出本次需支付對應金額,因為賬單里的輸出金額是不可拆分的,只能利用賬單來支付,要將銀行里控制的個人賬戶余額(一串數字)與比特幣個人賬戶余額(賬戶下的賬單輸出)區分開來。
  • 生成的賬單三中有給礦工的獎勵,這個獎勵是你自定的,給不給,給多少都行,這個獎勵影響的是交易的優先級,獎勵越多,越能盡早地將賬單加入區塊鏈中,以保證交易的完成。賬單將會被保存在礦工的礦池中,按照獎勵優先級來處理賬單。

交易輸出的鎖定與解鎖(重點)——鎖定腳本與解鎖腳本

  上面提到了,一個賬戶可支配的比特幣來源於賬單的輸出,而賬單是公開的,每個比特幣賬戶都能知道這筆交易以及交易的輸出,那么怎么保證輸出只有對應的比特幣的賬戶能用呢?

  比特幣的鎖機制是通過一種類Forth語言腳本來,該腳本語言是種非圖靈完備的語言,什么是圖靈完備的語言呢,當一門編程語言在不限制內存和不限制時間下,能夠解決所有問題,就稱為圖靈完備的,例如:C/C++,JAVA都是圖靈完備語言,反之就是圖靈非完備,比特幣腳本里沒有循環,所以這個腳本不能解決:在滿足某種條件下退出循環,否則無限制地循環的問題。比特幣的腳本語言是一種簡單、低級的語言,它的很多功能已經被編譯成立二進制文件,即使我們不了解這種語言,只要能夠調用接口就行了,或者可以直接使用C/C++,JAVA這樣的語言來完成鎖定和解鎖的功能。那么為什么不直接用C++等圖靈完備的語言呢?這是出於安全考慮的,因為C++,JAVA等語言與內存、操作系統等運行環境,息息相關,而比特幣腳本不需要任何運行環境都能運行,這就能抵抗基於內存的攻擊或者其他透過系統漏洞的攻擊(書上是這樣解釋的,我覺得,比特幣腳本更像一串機器語言的0-1串,由於低級機器語言的限制,很難進行高級編程,同樣的,也保證了安全性,因為0-1機器語言很難入侵更改)。

  下面是鎖定腳本與解鎖腳本的例子,以說明鎖的交互機制。

  假設這筆交易為A向B支付比特幣,在交易雙方完成交易,生成賬單時(非礦工加的解鎖和鎖定腳本),A向這個賬單加上了鎖定腳本,這個鎖定腳本包含B的比特幣地址C,因為B只公開了經過對公鑰HASH后的比特幣地址C,因為HASH函數的性質,比特幣網絡上的任何人,都不能通過C逆向得到B的公鑰,也就是說,只有B知道自己的公鑰能夠構建解鎖腳本,即只有B的公鑰,才能通過HASH運算出地址C,只有能運算出地址C的比特幣賬戶,才能支配這筆比特幣。

腳本語言運行

  該腳本語言僅由常數以及操作構成,從前往后遍歷腳本,若遇到常數,則將常數入棧,若遇到操作,根據操作的具體要求,對棧頂元素進行彈出,或者彈出兩個元素進行運算,再入棧,當一句腳本運行完畢后,僅只剩下棧頂元素,其取值為True\False,很清楚地,True代表驗證成功,代表執行腳本的用戶具有該賬單輸出比特幣的支配權,用戶能夠使用該賬單作為下筆交易(賬單)的輸入,下面是個具體例子

鎖定/解鎖腳本類型

1)P2PKH (Pay-to-Public-Key-Hash)——比特幣網絡上大多數交易都屬於此類型

  解鎖腳本鎖定腳本

2)P2PK(Pay-to-Public-Key)

  寫成收款方的公鑰,收款方通過自己的私鑰生成相應公鑰來獲取支配權。

3)P2SH(Pay-to-Script-Hash)

  這個腳本類型用於多重簽名才能支付,比如,一個公司的賬戶,由5個人支配,但只要有2個人以上的簽名就能進行比特幣支付。

  我們考慮使用2)的方式來寫多重簽名命令:

  就是說,再使用上圖方式多重簽名的時候,需要將所有人的公鑰都加在鎖定腳本里,因為Attorney Public Key時是所有人的公鑰運算的結果,而Public Key(公鑰)有260bit長,這樣下來,在人很多的情況下,甚至會使鎖定腳本容量超過賬單本身,而且這樣的腳本也難以維護,並暴露所有人之間的聯系(盡管比特幣地址是匿名的)。

  P2SH很好地解決了這個問題,P2SH分為除了鎖定腳本、解鎖腳本之外,多出了贖回腳本:

  使用方法是分兩步:①使用贖回腳本確認用戶能在屬於定義好的群組;②使用解鎖腳本解鎖(Sig1 Sig2是2個群組用戶的簽名)

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM