Transactions

廣播原始比特幣測試網交易時出錯

  • January 1, 2021

我正在嘗試從頭開始創建一個簡單的 P2PKH 原始比特幣測試網交易。以下是有關交易的資訊:

hash of the UTXO consumed - 03e3f89f38ea81a5f1ed277e6ac424cebde4426f4bcc291006f7ecf67350e986
index of the UTXO - 1
private key of the input - 4b5963fc219d1848cc67d52e0a929340f88ff9d316b1990b24d0ae1d37edeef1 
UTXO amount - 0.01 tBTC
receiving address - mtCrEgpKyRhLguqGySE4qUFXzn8sMG7hrm
receiving amount - 0.001 tBTC
change Address - mjHQ5W5B14psNsYBEmh1BykXyY4sY9r9DF
fees used - 378 sats
change amount - 0.00899622 tBTC

這是我創建的未簽名原始交易:

010000000186e95073f6ecf7061029cc4b6f42e4bdce24c46a7e27edf1a581ea389ff8e303010000001976a914d4dc68f4d94196536c0726f51a91d500c7afa60888acffffffff0226ba0d00000000001976a914295033e5bfe3e8734334addc62c82d9c6eab981388aca0860100000000001976a9148b2d174384a41deeb78e012f4582e29b6e0d161588ac0000000001000000

上面要簽名的雙 SHA-256 摘要:

4b5963fc219d1848cc67d52e0a929340f88ff9d316b1990b24d0ae1d37edeef1

接下來我使用自寫的 ECDSA 庫來簽署交易。我已經使用我的圖書館簽署了上述交易三遍。

簽署交易1:

010000000186e95073f6ecf7061029cc4b6f42e4bdce24c46a7e27edf1a581ea389ff8e303010000006b483045022100a482537e4225c1ba3470c68d2304d807a6e245491b486e1c6d0778a8436d25dd0220cf4cc90f2e41cafca39555caeb47be235b9c10c2b497528532cb419a7736a8d1012103ab127bf811fd8a6753fbc8cd68731a120d05ac64f1e03df5ec223d7a734e6199ffffffff0226ba0d00000000001976a914295033e5bfe3e8734334addc62c82d9c6eab981388aca0860100000000001976a9148b2d174384a41deeb78e012f4582e29b6e0d161588ac00000000

Signature: 3045022100a482537e4225c1ba3470c68d2304d807a6e245491b486e1c6d0778a8436d25dd0220cf4cc90f2e41cafca39555caeb47be235b9c10c2b497528532cb419a7736a8d1012103ab127bf811fd8a6753fbc8cd68731a120d05ac64f1e03df5ec223d7a734e6199

R: a482537e4225c1ba3470c68d2304d807a6e245491b486e1c6d0778a8436d25dd
S: cf4cc90f2e41cafca39555caeb47be235b9c10c2b497528532cb419a7736a8d1

簽署交易2:

010000000186e95073f6ecf7061029cc4b6f42e4bdce24c46a7e27edf1a581ea389ff8e303010000006b48304502210076a3092727f537453e938a07c9558c605bb79824972b50386e909d8b0394f9700220745b9869b1a4e7b4671a538b7f015a19567250a66f7e965af09060450fdf4288012103ab127bf811fd8a6753fbc8cd68731a120d05ac64f1e03df5ec223d7a734e6199ffffffff0226ba0d00000000001976a914295033e5bfe3e8734334addc62c82d9c6eab981388aca0860100000000001976a9148b2d174384a41deeb78e012f4582e29b6e0d161588ac00000000

Signature: 304502210076a3092727f537453e938a07c9558c605bb79824972b50386e909d8b0394f9700220745b9869b1a4e7b4671a538b7f015a19567250a66f7e965af09060450fdf4288012103ab127bf811fd8a6753fbc8cd68731a120d05ac64f1e03df5ec223d7a734e6199

R: 76a3092727f537453e938a07c9558c605bb79824972b50386e909d8b0394f970
S: 745b9869b1a4e7b4671a538b7f015a19567250a66f7e965af09060450fdf4288

簽署交易3:

010000000186e95073f6ecf7061029cc4b6f42e4bdce24c46a7e27edf1a581ea389ff8e303010000006b4830450221009b6cf3115f5738998b249cafecd69bc489b770cb104a885f93f000df662ca9860220459c6548f4a5b8032529069d704857b92ff3693684be401430a7ca6b2c28e66d012103ab127bf811fd8a6753fbc8cd68731a120d05ac64f1e03df5ec223d7a734e6199ffffffff0226ba0d00000000001976a914295033e5bfe3e8734334addc62c82d9c6eab981388aca0860100000000001976a9148b2d174384a41deeb78e012f4582e29b6e0d161588ac00000000

Signature: 30450221009b6cf3115f5738998b249cafecd69bc489b770cb104a885f93f000df662ca9860220459c6548f4a5b8032529069d704857b92ff3693684be401430a7ca6b2c28e66d012103ab127bf811fd8a6753fbc8cd68731a120d05ac64f1e03df5ec223d7a734e6199

R: 9b6cf3115f5738998b249cafecd69bc489b770cb104a885f93f000df662ca986
S: 459c6548f4a5b8032529069d704857b92ff3693684be401430a7ca6b2c28e66d

我使用Blockstream 廣播工具來推送我的交易。但是,簽名交易 1 和 2 失敗並出現以下錯誤:

sendrawtransaction RPC error: {"code":-26,"message":"non-mandatory-script-verify-flag (Non-canonical DER signature)"}

最後,簽名交易 3 成功並在區塊鏈上確認。我已經驗證了所有三個簽名,ECDSA 參數 R 和 S 沒有任何問題。因此,在我看來,問題出在簽名的 DER 編碼中。幫我定位一下為什麼前兩筆交易sig-script驗證失敗的問題。

關於您未遵循的 DER 簽名有一些規則。在第一筆交易中,您沒有遵循 Low-S 價值規則。在第二筆交易中,您沒有遵循嚴格的 DER 編碼規則。

在第一次交易中,s價值太高。目前的標準規則要求s介於0x10x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0包容之間。你s的不在這個範圍內。要將 high 轉換s為 low s,您可以執行s' = n - ssecp256k1n曲線的順序,即n = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141

在第二筆交易中,您的簽名沒有遵循嚴格的 DER 編碼規則。這些規則在BIP 66中定義。具體來說,r當只有 32 個字節就足夠時,使用 33 個字節進行編碼。在這種0x00情況下,您預先添加的 是不必要的,因為r32 字節有符號整數是正數。僅當32 字節有符號整數為負數0x00時才需要前置,即設置了最高位。r

在您的第三筆交易中,您很幸運。因為您使用的是隨機隨機數,所以一半時間s將是低的,而r作為 32 字節整數的一半時間將是負數,並且需要前置0x00變為正數。所以應該接受四分之一的簽名,這基本上就是我們在這裡看到的。

與第二次交易中的錯誤有關,您需要注意的是何時rs小於 32 字節。這種情況很少見,但它可能會發生。本質上,對這些數字進行編碼的規則是將它們編碼為大端有符號整數,但要盡可能小。

引用自:https://bitcoin.stackexchange.com/questions/100984