天天看點

區塊鍊系列(六)之比特币交易

本文個人部落格位址:http://www.huweihuang.com/article/blockchain/blockchain-transactions/

1. 比特币交易簡介

比特币交易是比特币系統最重要的部分,本質是

資料結構

,資料結構中含有比特币交易參與者

價值轉移

的相關資訊。比特币區塊鍊是一本

全球複制記賬總賬簿

,每個

比特币交易

即賬簿上公開的一頁

轉賬記錄

2. 比特币交易的生命周期

  1. 建立比特币交易,通過一個或多個簽名加密,

    簽名

    标志了該比特币的使用許可。
  2. 交易廣播到比特币網絡中,每個節點進行驗證,并進行廣播,直到該交易被大多數節點接收。
  3. 比特币交易被一個挖坑節點驗證,并被添加到區塊鍊一個記錄多筆交易的區塊中。

一個交易如果被記錄到區塊鍊上并被足夠多的後續區塊确認,便成為比特币總賬簿的一部分,并被所有比特币交易參與者認可為有效交易。

2.1. 建立比特币交易

比特币交易類似

紙質支票

,比特币交易帶有

貨币轉移

的目的,交易可以被任何人線上上或線下建立,但是交易的發起人并不一定是簽署該筆交易的人,比如一個負責應付賬款的櫃員發起交易,但需要CEO進行簽名才有效。比特币交易的資金來源是以往的某筆交易輸入,而不是一個特定賬戶。

一筆比特币交易被建立,會被所有資金所有者簽名,如果是合法建立和簽名,則該交易是有效的。

2.2. 廣播交易至比特币網絡

一筆交易需要傳遞到比特币網絡中,才能被傳播也才能加入區塊鍊中。本質上比特币交易是一份資料,并且需要被發送到比特币節點的任何一個。該交易經過簽名但不含任何機密資訊、私鑰等,是以可以被公開傳播。

2.3. 比特币交易在比特币網絡中傳播

比特币交易被發送到比特币網絡的任一節點,該節點将會驗證該筆交易。具體如下:

  • 如果驗證為有效,則廣播該交易至其他連接配接節點;交易發起者會接收到表示交易有效并被接受的傳回資訊。
  • 如果驗證為無效,則拒絕該交易;交易發起者會接收到交易被拒絕的資訊。

比特币網絡是個

點對點網絡

,每個比特币節點都可以連接配接其他節點。整個比特币網絡形成松散連接配接,沒有固定拓撲的網狀結構,是以

節點地位同等

。一筆有效的交易被驗證後會被傳播到其他節點,以此類推,交易會被迅速擴散式傳播,直到所有節點都接收到它。

每個節點在傳播每筆交易前均進行獨立驗證,是以比特币網絡可以抵禦入侵,拒絕服務式攻擊等。

3. 交易結構

一筆比特币交易是一個包含

輸入值

輸出值

的資料結構,該資料結構植入了将一筆資金從起始點(輸入值)轉移至目标位址(輸出值)的代碼資訊。比特币交易的輸入值和輸出值與賬戶或身份資訊無關。

交易結構

大小 字段 描述
4位元組 版本 明确這筆交易參照的規則
1-9位元組 輸入數量 被包含的輸入的數量
不定 輸入 一個或多個交易輸入
1-9位元組 輸出數量 被包含的輸出的數量
不定 輸出 一個或多個交易輸出
4位元組 時鐘時間 一個UNIX時間戳或區塊号

4. 交易的輸出和輸入

比特币交易的基本機關是一個

未花費的輸出

(UTXO),

UTXO

是不能分割,被記錄于區塊鍊中并被整個網絡識别成貨币機關的一定量的比特币貨币。

比特币沒有賬戶和餘額的概念,隻有分散到區塊鍊中的UTXO

。比特币的餘額是比特币錢包通過掃描區塊鍊并聚合所有屬于該使用者的UTXO來計算該使用者餘額。

比特币可以分成表示八位小數的

,一個UTXO可以是一“聰”的任意倍,UTXO雖然可以是任意值但一旦被創造出來就不能被切分。就好比,用5元紙币支付2元的商品,不能将5元撕成一半支付,而是支付5元,找零3元。比特币錢包可以自動通過組合若幹UTXO來準确支付或找零。

被交易消耗的UTXO被稱為

交易輸入

,被交易建立的UTXO稱為

交易輸出

。通過不斷在交易鍊中消耗和建立UTXO,實作比特币價值在不同所有者之間轉移。一筆比特币交易通過使用所有者的簽名來解鎖UTXO,通過新的使用者的比特币位址來鎖定并建立UTXO。

4.1. 交易輸出

每一筆比特币交易創造輸出,輸出都會被比特币賬簿記錄下來。幾乎所有的輸出都能創造一定數量的可用于支付的比特币,也就是UTXO。這些UTXO被整個網絡識别,并且所有者可在未來的交易中使用它們。給某人發送比特币實際上是創造新的UTXO,注冊到那個人的位址,并且能被他用于新的支付。

UTXO被每一個全節點比特币用戶端在一個儲存于記憶體中的資料庫所追蹤,該資料庫也被稱為“

UTXO集

”或者“

UTXO池

”。新的交易從UTXO集中消耗(支付)一個或多個輸出。

交易輸出包含兩部分:

  • 一定量的比特币,被命名為“聰”,是最小的比特币機關;
  • 一個鎖定腳本,也被當作是“障礙”,提出支付輸出所必須被滿足的條件以“鎖住”這筆總額。

交易輸出結構

尺寸 字段 說明
8個位元組 總量 用聰表示的比特币值(10-8比特币)
1–9個位元組(可變整數) 鎖定腳本尺寸 用位元組表示的後面的鎖定腳本長度
變長 鎖定腳本 一個定義了支付輸出所需條件的腳本

支付條件(障礙)

交易輸出把用聰表示的一定數量的比特币,和特定的定義了支付輸出所必須被滿足的條件的障礙,或者叫鎖定腳本,關聯到了一起。在大多數情況下,鎖定腳本會把輸出鎖在一個特定的比特币位址上,進而把一定數量的比特币的所有權轉移到新的所有者上。

4.2. 交易輸入

交易輸入是指向UTXO的指針。它們指向特定的UTXO,并被交易哈希和在區塊鍊中記錄UTXO的序列号作為參考。若想支付UTXO,一個交易的輸入也需要包含一個解鎖腳本,用來滿足UTXO的支付條件。解鎖腳本通常是一個簽名,用來證明對于在鎖定腳本中的比特币位址擁有所有權。

當使用者付款時,他的錢包通過選擇可用的UTXO來構造一筆交易。比如說,要支付0.015比特币,錢包應用會選擇一個0.01 UTXO和一個0.005 UTXO,使用它們加在一起來得到想要的付款額。

一旦UTXO被選中,錢包會為每個UTXO生成包含簽名的解鎖腳本,由此讓它們變得可以通過滿足鎖定腳本的條件來被支付。錢包把這些UTXO作為參考,并且連同解鎖腳本一起作為輸入加到交易中。

交易輸入的結構

尺寸 字段 說明
32個位元組 交易 指向交易包含的被花費的UTXO的哈希指針
4個位元組 輸出索引 被花費的UTXO的索引号,第一個是0
1–9個位元組(可變整數) 解鎖腳本尺寸 用位元組表示的後面的解鎖腳本長度
變長 解鎖腳本 一個達到UTXO鎖定腳本中的條件的腳本
4個位元組 序列号 目前未被使用的交易替換功能,設成0xFFFFFFFF

4.3. 交易費

交易費可當作是為了包含(挖礦)一筆交易到下一個區塊中的一種鼓勵,也可當作是對于欺詐交易和任何種類的系統濫用,在每一筆交易上通過征收一筆小成本的稅而造成的一種妨礙。交易費被挖出這個區塊的礦工得到,并且記錄在這個交易的區塊鍊中。

交易費基于交易的尺寸,用千位元組來計算,與參加交易的比特币值無關。總的來說,交易費基于市場所設定,生效于比特币網絡中。

交易費的高低影響交易被處理的

優先級

,即交易費高的交易可以被優先處理,交易費低的交易被延遲處理,甚至不被處理。

4.4. 把交易費加到交易中

交易的資料結構沒有交易費的字段,而是輸入總額與輸出總額之間的差來表示。

交易費 = 求和(所有輸入) - 求和(所有輸出)

當一筆交易需要找零時,

交易費 = 付款金額 - 收款金額 - 找零金額

5. 交易鍊條和孤立交易

交易形成一條鍊,這條鍊的形式是一筆交易消耗了先前的交易(父交易)的輸出,并為随後的交易(子交易)創造了輸出。

有的時候組成整個鍊條的所有交易依賴于他們自己——比如父交易、子交易和孫交易——而他們又被同時創造出來,來滿足複雜交易的工作流程。這需要在一個交易的父交易被簽名之前,有一個合法的子交易被簽名。

當父交易和子交易同時被建立的時候,如果子交易比父交易先到達目的地,驗證的時候找不到父交易,此時子交易會被放到臨時池中(沒有父交易的交易池稱為

孤立交易池

),一旦接收到父交易,孤立池的子交易就會被釋放出來,遞歸重新驗證。

記憶體中儲存的孤立交易數量是有限制的,避免拒絕服務攻擊(DoS)。最大值為

MAX_ORPHAN_TRANSACTIONS

,如果超過該值,會随機選出一個或多個孤立交易丢棄,直到交易數低于該值。

6. 比特币交易腳本和腳本語言

比特币用戶端通過執行一個用類Forth腳本語言編寫的腳本驗證比特币交易。鎖定腳本被寫入UTXO,同時它往往包含一個用同種腳本語言編寫的簽名。當一筆比特币交易被驗證時,每一個輸入值中的解鎖腳本被與其對應的鎖定腳本同時(互不幹擾地)執行,進而檢視這筆交易是否滿足使用條件。

6.1. 腳本建立(鎖定和解鎖)

比特币的交易驗證引擎依賴于兩類腳本來驗證比特币交易:一個

鎖定腳本

和一個

解鎖腳本

  • 鎖定腳本

    是一個放在一個輸出值上的“障礙”,同時它明确了今後花費這筆輸出的條件。由于鎖定腳本往往含有一個

    公鑰

    (即比特币位址)。
  • 解鎖腳本

    是一個“解決”或滿足被鎖定腳本在一個輸出上設定的花費條件的腳本,同時它将允許輸出被消費。解鎖腳本是每一筆比特币交易輸出的一部分,而且往往含有一個被使用者的比特币錢包(通過使用者的

    私鑰

    )生成的

    數字簽名

    。由于解鎖腳本常常包含一個數字簽名,是以它曾被稱作

    ScriptSig

每一個比特币用戶端會通過同時執行鎖定和解鎖腳本來驗證一筆交易。對于比特币交易中的每一個輸入,驗證軟體會先檢索輸入所指向的UTXO。這個UTXO包含一個定義了花費條件的鎖定腳本。接下來,驗證軟體會讀取試圖花費這個UTXO的輸入中所包含的解鎖腳本,并執行這兩個腳本。

使用堆棧執行引擎執行解鎖腳本。如果解鎖腳本在執行過程中未報錯(沒有懸空操作符),主堆棧(非其它堆棧)将被複制,然後腳本将被執行。如果采用從解鎖腳本處複制而來的資料執行鎖定腳本的結果為真,那麼解鎖腳本就成功地滿足了鎖定腳本所設定的條件,因而,該輸入是一個能使用該UTXO的有效授權。如果在執行完組合腳本後的結果不是真,那麼輸入就不是有效的,因為它并未能滿足UTXO中所設定的使用該筆資金的條件。

UTXO是永久性地記錄在區塊鍊中的,是以它不會因一筆新交易所發起的無效嘗試而變化或受影響。隻有一筆有效的能準确滿足UTXO條件的交易才會導緻UTXO被标記為“已使用”,然後從有效的(未使用)UTXO集中所移除。

解鎖和鎖定腳本樣本

區塊鍊系列(六)之比特币交易

6.2. 腳本語言

比特币腳本語言被稱為基于棧語言,因為它使用的資料結構被稱為棧。腳本語言通過從左至右地處理每個項目的方式執行腳本。數字(常數)被推送至堆棧,操作符向堆棧推送(或移除)一個或多個參數,對它們進行處理,甚至可能會向堆棧推送一個結果。

6.3. 圖靈非完備性

比特币腳本語言

沒有循環

或者複雜流控制功能以外的其他條件的流控制。即

圖靈非完備性

,這意味着腳本的複雜性有限,交易可執行的次數有限。這種限制避免受到拒絕服務攻擊。

6.4. 非主權驗證

比特币交易腳本語言是

無國家主權

的,一個腳本能在任何系統上以相同的方式執行。如果你的系統對一個腳本進行驗證,可以确信的是每一個比特币網絡中的其他系統也将對其進行驗證,這意味着一個有效的交易對每個人而言都是有效的。

7. 标準交易

比特币發展中,開發者對可以經由用戶端進行操作的腳本類型設定了一些限制。這些限制被編譯為一個Standard()函數,該函數定義了五種類型的标準交易。五大标準腳本分别為

P2PKH

P2PK

MS(限15個密鑰)[多重簽名]

P2SH

OP_Return

7.1. 多重簽名

多重簽名

腳本設定了這樣一個條件,假如記錄在腳本中的公鑰個數為N,則至少需提供其中的M個公鑰才可以解鎖。這也被稱為

M-N組合

,其中,

N

是記錄在腳本中的

公鑰總個數

M

是使得多重簽名生效的

公鑰數閥值

(最少數目)。

參考:

  • Mastering Bitcoin
  • https://github.com/bitcoinbook/bitcoinbook/blob/develop/ch06.asciidoc