鎖定腳本和解鎖腳本
比特幣腳本存在的意義是讓每筆交易合法化,這個合法化不是人工審核而是有腳本自動執行校驗的。
腳本分為鎖定腳本和解鎖腳本。鎖定腳本和UTXO是對應的,一個UTXO中包含一個鎖定腳本。
當這個UTXO要被使用時,比如alice轉賬給bob需要引用這個UTXO,這就產生了一筆交易。這筆交易只有被驗證了才可能在比特幣的網絡中傳播(傳播后就可以被礦工加入區塊鏈,這部分就不詳述了。)
驗證的時候需要的就是解鎖腳本。
從上述流程可以看出: 鎖定腳本和UTXO 關聯,而解鎖腳本和某筆交易關聯。
鎖定腳本被叫做scriptPubKey, 解鎖腳本被叫做ScriptSig。
腳本究竟是什么形式存在的呢?其實就是一堆命令加參數。
上圖中的dup, hash160等是命令,sig, pubk是參數。
腳本語言執行原理
腳本的執行流程基于堆棧模型。這個非常類似于我大學時期數據結構課程中講到的表達式求值的實現邏輯。
輸入的形式:表達式,例如2*(3+4)
輸出的形式:運算結果
其中2,3,4相當于腳本中的參數,而*,+號是腳本的命令。
實現邏輯就是基于棧結構,初始都入棧,然后出棧判斷如何操作。
比特幣腳本也是類似的實現邏輯,而且它更加簡單(沒有優先級判斷那些)。
上圖是一個很簡單的腳本,就是判斷2 add 3是否equal 5。下面的篇幅會詳述一個實際的比特幣交易腳本的執行過程。
數字簽名和驗簽
比特幣腳本的驗證機制會用到數字簽名的概念。這一部分知識是獨立的一塊,它基于非對稱密鑰算法,并不是比特幣腳本特有的。如果要詳細解釋這一塊也是很大篇幅,這里不再贅述,不懂的請自行查閱。
比特幣地址如何生成
繼續往下看之前,你需要了解公鑰和比特幣地址之間的關系:
以公鑰 K 為輸入,計算其 SHA256 哈希值,并以此結果計算 RIPEMD160 哈
希值,得到一個長度為 160 比特(20 字節)的數字:
A = RIPEMD160(SHA256(K))
公式中,K 是公鑰,A 是生成的比特幣地址。
比特幣交易示例
假設alice要向bob支付0.015比特幣, alice會用到一個UTXO(假設是單輸入,單輸出),這個UTXO帶有一個鎖定腳本,為交易設置“障礙”。
鎖定腳本如下:
OP_DUP OP_HASH160 be10f0a78f5ac63e8746f7f2e62a5663eed05788 OP_EQUALVERIFY OP_CHECKSIG
- OP_DUP:復制棧頂數據,然后該數據放置棧頂
- OP_HASH160:對棧頂數據執行ripemd160(sha256(data)) (這其實是兩次摘要計算,不詳述)
- be10f0a...:bob的比特幣地址
- OP_EQUALVERIFY:對比棧頂的兩個數據,如果相等都被移除
- OP_CHECKSIG:驗證簽名
bob如果要接收這筆比特幣(另一種說法是bob可以引用該筆輸出),就要給出一個解鎖腳本,然后解鎖腳本和鎖定腳本組合后執行的結果為真才能確認交易有效。
解鎖腳本如下:
3046022100ba1427639c9f67f2ca1088d0140318a98cb1e84f604dc90ae00ed7a5f9c61cab02210094233d018f2f014a5864c9e0795f13735780cafd51b950f503534a6af246aca301
03a63ab88e75116b313c6de384496328df2656156b8ac48c75505cd20a4890f5ab
看起來是一堆數字,其實『簽名』和『公鑰』(sig & pubkey)的組合。簽名是bob的私鑰對該筆交易的信息加密的結果,公鑰就是指的bob的公鑰。
由于私鑰只有bob才知道,所以也只有他才能拿出正確的簽名。
下面是腳本執行的過程:
簡單的幾十個字節的腳本,就完成了交易的驗證確保該筆轉賬的合法性。
比特幣腳本變種
上文講述的示例都是基于比特幣最基本的P2PKH交易類型。現在比特幣核心已經升級了很多版本,腳本的驗證機制發生了不小的變化。比如說現在用的比較廣泛的多重簽名腳本。這些變種腳本雖然越來越復雜,但是基本思想都是基于上述原理。
參考
[1] Andreas M. Antonopoulos <<精通比特幣>>
[2] http://www.8btc.com/understand-bitcoin-script