p2sh地址是怎麼花的
因此,我正在研究 P2SH 交易是如何工作的,並通過查看不同的部落格文章,特別是對於這個答案,我有以下問題。
因此,讓我們進行相同的交易:
我沒有得到的是操作是如何完成的。
- scriptSig 是先執行的嗎?
- 檢查等於
0b49fe...df1
什麼?它是如何計算的?
我沒有得到的是操作是如何完成的。
該地址對redeemScript 的hash160 進行編碼。該地址被提供給發送者,發送者使用它來構造一個形式為的輸出scriptPubKey
OP_HASH160 <scripthash> OP_EQUAL
。scripthash確實是hash160(redeemScript),但發件人不知道這一點,因為他們沒有得到實際的redeemScript,只是它的hash160。這裡的<...>
符號表示“將 … 推入堆棧的腳本操作碼”。贖回
OP_2 <pubkey1> <pubkey2> <pubkey3> OP_3 OP_CHECKMULTISIG
腳本是. 該腳本由接收方創建,對其支出策略進行編碼,然後以 P2SH 地址 (3…) 的形式將其 hash160 提供給發送方。scriptSig是接收者在想要花費硬幣時創建的。在這種情況下,它由
OP_0 <sig1> <sig2> <redeemScript>
.在驗證期間,會發生以下情況:
首先執行scriptSig,將 4 個項目壓入堆棧(0、sig1、sig2和redeemScript)。
然後執行 scriptPubKey,從上一次執行的最終堆棧作為初始狀態開始。它包含 3 個操作碼,每個操作碼都修改該堆棧:
OP_HASH160
: 獲取堆棧的最後一個元素(redeemScript)並將其替換為hash160(redeemScript)。<scripthash>
: 將scripthash推入堆棧,所以現在堆棧是 (0, sig1 , sig2 , hash160(redeemScript) , scripthash )。OP_EQUALVERIFY
: 移除棧頂的兩項並進行比較。如果它們相等,則將 1 壓入堆棧,否則將 0 壓入堆棧。在我們的例子中,scripthash等於hash160(redeemScript ) (因為支出者顯示了正確的redeemScript),因此推送了 1。堆棧現在是 (0, sig1 , sig2 , 1)。檢查最終堆棧:有效性規則要求堆棧不為空,並且其頂部元素非零。這裡就是這種情況:頂部元素是 1。如果不是這種情況,則支出將被標記為無效並且執行將在此處停止。
這就是普通的執行。但是,由於scriptSig的格式正好
OP_HASH160 <20-byte scripthash> OP_EQUAL
是,因此 BIP16 P2SH 驗證規則會觸發第二輪處理。這次:
經驗證,scriptSig僅包含推送操作碼,沒有其他操作碼。如果不是這樣,P2SH 驗證會將交易標記為無效。
我們剛剛執行scriptSig後的堆棧被恢復(0,sig1,sig2,redeemScript)。
它的頂部元素(redeemScript)從堆棧中移除,並重新解釋為腳本並執行,所有其他堆棧元素作為輸入。它由 6 個操作碼組成:
OP_2
: 將 2 推入堆棧,現在變為 (0, sig1 , sig2 , 2)。<pubkey1>
: 將pubkey1推入堆棧,堆棧變為 (0, sig1 , sig2 , 2, pubkey1 )。<pubkey2>
:將pubkey2推入堆棧,堆棧變為 (0, sig1 , sig2 , 2, pubkey1 , pubkey2 )。<pubkey3>
: 將pubkey3推入堆棧,堆棧變為 (0, sig1 , sig2 , 2, pubkey1 , pubkey2 , pubkey3 )。OP_3
: 將 2 壓入堆棧,現在變為 (0, sig1 , sig2 , 2, pubkey1 , pubkey2 , pubkey3 , 3)。OP_CHECKMULTISIG
檢查堆棧,看到頂部的 3,刪除它,以及它之前的 3 個 pubkey。然後它遇到頂部的 2,刪除,以及它之前的 2 個簽名。然後它又刪除了一個元素(一個很難修復的歷史錯誤)。然後它根據這 3 個公鑰中的 2 個的每個子集檢查這些簽名。如果找到匹配項,則將 1 放入堆棧,否則放入 0。在這種情況下,簽名對某些公鑰子集有效,堆棧變為 (1)。檢查最終堆棧,要求它不為空,並且其頂部元素非零。因為這裡是 1,所以就是這樣。