Transactions
使用 Openssl 簽署交易遺產
我想了解比特幣如何使用 Openssl 簽署交易。我看到了這篇文章,但我有一些問題。
在我的私鑰和公鑰之上。
私鑰:
$ cat chiave_priv_3.pem -----BEGIN EC PARAMETERS----- BgUrgQQACg== -----END EC PARAMETERS----- -----BEGIN EC PRIVATE KEY----- MHQCAQEEIOLcjvH4RhZFl1hthXl7DD3MHXUCWKiI2b/zoYlvBmKboAcGBSuBBAAK oUQDQgAE3Qc0PacS/HmhnZjIot48dZ++rvh121Rq+xjreFKrf/QCl2sDXTncDbe0 wcCtq4yaUpdbmzV9OgrP94EFsEC/1w== -----END EC PRIVATE KEY-----
公鑰壓縮
$ cat chiave_pubblica_compressa_3.txt 03dd07343da712fc79a19d98c8a2de3c759fbeaef875db546afb18eb7852ab7ff4
我正在做 regtest,我的 UTXO 是:
{ "txid": "0c647aadcb4028260ecb753c727e0237658873a0cbdbeb5695b8cb85ea87f98d", "vout": 0, "address": "myiGTzGG8rJikr2HcVyPYqprh6Ds1kdY7v", "label": "", "scriptPubKey": "76a914c79602205abbe1d35ee6dcb4a19791cbd5a26e1588ac", "amount": 49.99900000, "confirmations": 6, "spendable": true, "solvable": true, "desc": "pkh([c7960220]03dd07343da712fc79a19d98c8a2de3c759fbeaef875db546afb18eb7852ab7ff4)#5c03vyak", "safe": true },
我可以使用以下參數創建交易數據:
TXID=0c647aadcb4028260ecb753c727e0237658873a0cbdbeb5695b8cb85ea87f98d VOUT=0 AMOUNT=49.998 ADDR_MITT=msPjuNgbmbRSkNGJPvquKJRRmrbzS96s62 bitcoin-cli createrawtransaction '[{"txid":"'$TXID'","vout":'$VOUT'}]' '[{"'$ADDR_MITT'":'$AMOUNT'}]' 02000000018df987ea85cbb89556ebdbcba073886537027e723c75cb0e262840cbad7a640c0000000000ffffffff01c0e4022a010000001976a914824441111b374bec1952a5b3fa9dd4e3ed679b3888ac00000000
現在我得到 scriptPubKey 並放入 ScriptSig 並在 little endian 中添加 SIGHASH。
02000000018df987ea85cbb89556ebdbcba073886537027e723c75cb0e262840cbad7a640c000000001976a914c79602205abbe1d35ee6dcb4a19791cbd5a26e1588acffffffff01c0e4022a010000001976a914824441111b374bec1952a5b3fa9dd4e3ed679b3888ac0000000001000000
在哪裡
02000000 01 8df987ea85cbb89556ebdbcba073886537027e723c75cb0e262840cbad7a640c 00000000 19 76a914c79602205abbe1d35ee6dcb4a19791cbd5a26e1588ac ffffffff 01 c0e4022a01000000 19 76a914824441111b374bec1952a5b3fa9dd4e3ed679b3888ac 00000000 01000000
Sha256 兩次
$ printf 02000000018df987ea85cbb89556ebdbcba073886537027e723c75cb0e262840cbad7a640c000000001976a914c79602205abbe1d35ee6dcb4a19791cbd5a26e1588acffffffff01c0e4022a010000001976a914824441111b374bec1952a5b3fa9dd4e3ed679b3888ac0000000001000000 | xxd -r -p | sha256sum -b | xxd -r -p | sha256sum -b | awk '{ print $1 }' > a.txt daac47088b7eba5593282013442dbcba59556d095982d470f0a02972269bc0e1
使用 chiave_priv_3.pem 簽名
$ openssl dgst -sha256 -hex -sign chiave_priv_3.pem a.txt | sed 's/^.* //' 304402207071c9fd7341a15cacfea72e215b44bed42d1a00c7fc5bfed5e01d36acd953c20220308e45aedd080ba65993b69b4c82cc928db8c3e70a6f402fe0258157a4690c6e
在簽名末尾添加01並檢查長度
printf 304402207071c9fd7341a15cacfea72e215b44bed42d1a00c7fc5bfed5e01d36acd953c20220308e45aedd080ba65993b69b4c82cc928db8c3e70a6f402fe0258157a4690c6e01 | wc -c 142
142 char is 47
調試 DER 簽名
30 DER prefix 44 Length of rest of Signature 02 Marker for r value 20 Length of r value r = 7071c9fd7341a15cacfea72e215b44bed42d1a00c7fc5bfed5e01d36acd953c2 02 Marker for s value 20 Length of s value s = 308e45aedd080ba65993b69b4c82cc928db8c3e70a6f402fe0258157a4690c6e 01 SIGHASH_ALL
與壓縮的公鑰連接
47304402207071c9fd7341a15cacfea72e215b44bed42d1a00c7fc5bfed5e01d36acd953c20220308e45aedd080ba65993b69b4c82cc928db8c3e70a6f402fe0258157a4690c6e012103dd07343da712fc79a19d98c8a2de3c759fbeaef875db546afb18eb7852ab7ff4
整個 scriptSig 長度是:6A (212 char hex) 現在我可以建立我的交易:
02000000018df987ea85cbb89556ebdbcba073886537027e723c75cb0e262840cbad7a640c000000006A47304402207071c9fd7341a15cacfea72e215b44bed42d1a00c7fc5bfed5e01d36acd953c20220308e45aedd080ba65993b69b4c82cc928db8c3e70a6f402fe0258157a4690c6e012103dd07343da712fc79a19d98c8a2de3c759fbeaef875db546afb18eb7852ab7ff4ffffffff01c0e4022a010000001976a914824441111b374bec1952a5b3fa9dd4e3ed679b3888ac00000000
發送交易
bitcoin-cli sendrawtransaction 02000000018df987ea85cbb89556ebdbcba073886537027e723c75cb0e262840cbad7a640c000000006A47304402207071c9fd7341a15cacfea72e215b44bed42d1a00c7fc5bfed5e01d36acd953c20220308e45aedd080ba65993b69b4c82cc928db8c3e70a6f402fe0258157a4690c6e012103dd07343da712fc79a19d98c8a2de3c759fbeaef875db546afb18eb7852ab7ff4ffffffff01c0e4022a010000001976a914824441111b374bec1952a5b3fa9dd4e3ed679b3888ac00000000 error code: -26 error message: mandatory-script-verify-flag-failed (Signature must be zero for failed CHECK(MULTI)SIG operation) (code 16)`
問題是您正在執行所有散列(並將其放入十六進制),然後讓 OpenSSL 再次對其進行散列。
openssl dgst
將在簽名之前對消息進行雜湊處理,但這對於比特幣是不正確的。傳統上,在 ECDSA 中,消息被雜湊一次然後簽名。但是對於比特幣,它實際上被雜湊了兩次。另一種思考方式是消息是散列。所以你已經對交易進行了雙重雜湊處理。但是 OpenSSL 會再次對其進行雜湊處理,使其經過三次雜湊處理,這意味著您簽署了不同的消息。此外,OpenSSL 會將您的消息作為二進制數據讀取,而不是解釋您提供的十六進制數據。所以真的你的散列命令應該是
printf 02000000018df987ea85cbb89556ebdbcba073886537027e723c75cb0e262840cbad7a640c000000001976a914c79602205abbe1d35ee6dcb4a19791cbd5a26e1588acffffffff01c0e4022a010000001976a914824441111b374bec1952a5b3fa9dd4e3ed679b3888ac0000000001000000 | xxd -r -p | sha256sum -b | xxd -r -p > a.txt
這將對 sighash 消息進行一次雜湊處理,並將二進制數據放入 a.txt。
然後你就可以像以前那樣簽名了。
或者,OpenSSL 有一個
pkeyutl
工具,它不對要簽名的數據進行任何額外的雜湊處理,而是希望您已經對其進行了雜湊處理。你可以改用它,但你仍然需要你的雜湊是二進製而不是十六進制。所以你可以做printf 02000000018df987ea85cbb89556ebdbcba073886537027e723c75cb0e262840cbad7a640c000000001976a914c79602205abbe1d35ee6dcb4a19791cbd5a26e1588acffffffff01c0e4022a010000001976a914824441111b374bec1952a5b3fa9dd4e3ed679b3888ac0000000001000000 | xxd -r -p | sha256sum -b | xxd -r -p | sha256sum -b | xxd -r -p > a.txt
獲得雙重雜湊。然後做
openssl pkeyutl -inkey chiave_priv_3.pem a.txt -sign -in a.txt -pkeyopt digest:sha256 | xxd -p -c 256
簽署。