廣播原始比特幣測試網交易時出錯
我正在嘗試從頭開始創建一個簡單的 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
介於0x1
和0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0
包容之間。你s
的不在這個範圍內。要將 high 轉換s
為 lows
,您可以執行s' = n - s
secp256k1n
曲線的順序,即n = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141
。在第二筆交易中,您的簽名沒有遵循嚴格的 DER 編碼規則。這些規則在BIP 66中定義。具體來說,
r
當只有 32 個字節就足夠時,使用 33 個字節進行編碼。在這種0x00
情況下,您預先添加的 是不必要的,因為r
32 字節有符號整數是正數。僅當32 字節有符號整數為負數0x00
時才需要前置,即設置了最高位。r
在您的第三筆交易中,您很幸運。因為您使用的是隨機隨機數,所以一半時間
s
將是低的,而r
作為 32 字節整數的一半時間將是負數,並且需要前置0x00
變為正數。所以應該接受四分之一的簽名,這基本上就是我們在這裡看到的。與第二次交易中的錯誤有關,您需要注意的是何時
r
或s
小於 32 字節。這種情況很少見,但它可能會發生。本質上,對這些數字進行編碼的規則是將它們編碼為大端有符號整數,但要盡可能小。