Transactions

使用 Openssl 手動簽名 P2WSH 本機

  • April 22, 2020

我正在研究 segwit 部分,我想手動簽署 P2WSH(本機)(openssl)。

我剛剛閱讀BIP0143並看到了新的交易摘要。

Double SHA256 of the serialization of:
    1. nVersion of the transaction (4-byte little endian)
    2. hashPrevouts (32-byte hash)
    3. hashSequence (32-byte hash)
    4. outpoint (32-byte hash + 4-byte little endian) 
    5. scriptCode of the input (serialized as scripts inside CTxOuts)
    6. value of the output spent by this input (8-byte little endian)
    7. nSequence of the input (4-byte little endian)
    8. hashOutputs (32-byte hash)
    9. nLocktime of the transaction (4-byte little endian)
   10. sighash type of the signature (4-byte little endian

我正在使用 regtest,我創建了一個從 P2WSH 到 P2WPKH 的交易,在那裡我移動了 ~49.999991 個比特幣。

這是我的UTXO

  020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03510101ffffffff0200f2052a01000000220020896386cc04087d76450a506b09e88de6d68bba45f50c4967818e6fd10e6eaade0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000
{
 "txid": "0237415f2eb789a48e43ed68862ea9db3455f7b21203f4b526cd88b970b1329b",
 "hash": "76069338f9fd11b43901b6b5260e6b279dd26071148643a1b31fc41190dc73f1",
 "version": 2,
 "size": 180,
 "vsize": 153,
 "weight": 612,
 "locktime": 0,
 "vin": [
   {
     "coinbase": "510101",
     "sequence": 4294967295
   }
 ],
 "vout": [
   {
     "value": 50,
     "n": 0,
     "scriptPubKey": {
       "asm": "0 896386cc04087d76450a506b09e88de6d68bba45f50c4967818e6fd10e6eaade",
       "hex": "0020896386cc04087d76450a506b09e88de6d68bba45f50c4967818e6fd10e6eaade",
       "reqSigs": 1,
       "type": "witness_v0_scripthash",
       "addresses": [
         "bcrt1q393cdnqypp7hv3g22p4sn6ydumtghwj975xyjeup3ehazrnw4t0q7p0v3p"
       ]
     }
   },
   {
     "value": 0,
     "n": 1,
     "scriptPubKey": {
       "asm": "OP_RETURN aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf9",
       "hex": "6a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf9",
       "type": "nulldata"
     }
   }
 ],
 "hex": "020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03510101ffffffff0200f2052a01000000220020896386cc04087d76450a506b09e88de6d68bba45f50c4967818e6fd10e6eaade0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000",
 "blockhash": "42f85575b186494c8ac18487a0f21f4645346c6d9740d17f764a8a56e74fa2e3",
 "confirmations": 101,
 "time": 1587537959,
 "blocktime": 1587537959
}

我的原始交易數據是:

02000000019b32b170b988cd26b5f40312b2f75534dba92e8668ed438ea489b72e5f4137020000000000ffffffff017cee052a01000000160014f545040775837a55962bb8abfcc341f574d6791700000000

我像這樣創建新的交易摘要:

   TX_VERSION: 02000000
   OUTPOINT: 9b32b170b988cd26b5f40312b2f75534dba92e8668ed438ea489b72e5f41370200000000
   HASH_PREV_OUT: b98dd14dcfff442ee1562d70b507402d6ba089dc8af7fe0360f422ff5d60a206
(HASH_PREV_OUT is SHA256 twice of $OUTPOINT)
   SEQUENCE: ffffffff
   HASH_SEQUENCE: 3bb13029ce7b1f559ef5e747fcac439f1455a2ec7c5f09b72290795e70665044
(HASH_SEQUENCE is SHA256 twice of $SEQUENCE)
   SCRIPTCODE: 1976a91427275283377b40957701cecd37d2e170c41d387488AC
   AMOUNT: 00f2052a01000000
(TOTAL AMOUNT - 50 bitcoin )
   OUTPUT: 160014f545040775837a55962bb8abfcc341f574d67917
   OUTPUT_HASH: 9fbf0bcf967eb3f1fcd41f60ce73e69f8b5073185ff81f787d9caac0e5992fd2
(OUTPUT_HASH is SHA256 twice of $AMOUNT$OUTPUT)
   LOCKTIME_PART: 00000000
   SIGHASH: 01000000

SCRIPT-CODE 是我的 UTXO 見證腳本(腳本是 P2PKH)然後我“合併”所有值,如下所示:

$ WITNESS_V0_DIGEST=$TX_VERSION$HASH_PREV_OUT$HASH_SEQUENCE$OUTPOINT$SCRIPTCODE$AMOUNT$SEQUENCE$OUTPUT_HASH$LOCKTIME_PART$SIGHASH
$ echo $WITNESS_V0_DIGEST
02000000b98dd14dcfff442ee1562d70b507402d6ba089dc8af7fe0360f422ff5d60a2063bb13029ce7b1f559ef5e747fcac439f1455a2ec7c5f09b72290795e706650449b32b170b988cd26b5f40312b2f75534dba92e8668ed438ea489b72e5f413702000000001976a91427275283377b40957701cecd37d2e170c41d387488AC00f2052a01000000ffffffff9fbf0bcf967eb3f1fcd41f60ce73e69f8b5073185ff81f787d9caac0e5992fd20000000001000000

然後我可以做雙 SHA56 並簽名:

printf $WITNESS_V0_DIGEST | xxd -r -p | sha256sum -b | xxd -r -p | sha256sum -b | xxd -r -p > WITNESS_V0_DIGEST.txt

SIGNATURE=`openssl pkeyutl -inkey private_key_1.pem -sign -in WITNESS_V0_DIGEST.txt -pkeyopt digest:sha256 | xxd -p -c 256`

SIGNATURE="${SIGNATURE}01"

現在我可以像這樣創建我的交易:

020000000001019b32b170b988cd26b5f40312b2f75534dba92e8668ed438ea489b72e5f4137020000000000ffffffff017cee052a01000000160014f545040775837a55962bb8abfcc341f574d679170347304402202d7d72d425e407160554e9c29688164a7e5c2f380c86e26c0595a7c6c8d526df02206ff13970212a77d6febcdcdcc2945db3947f02137324ae7d822b4fa7f81292100121024633c32245c6709e7f756c41e0f163919fa00977798f30245d3498f88c53e8941976a91427275283377b40957701cecd37d2e170c41d387488AC00000000

這是解碼版

    {
 "txid": "23704afa715351b1d1810f41015fd3bfc33fed75842530ae0c00564eb7f16103",
 "hash": "5f6b1edafdd814d8c9ec85bad6125dbf2efbb245c28017b62ee4aa35ab712789",
 "version": 2,
 "size": 217,
 "vsize": 116,
 "weight": 463,
 "locktime": 0,
 "vin": [
   {
     "txid": "0237415f2eb789a48e43ed68862ea9db3455f7b21203f4b526cd88b970b1329b",
     "vout": 0,
     "scriptSig": {
       "asm": "",
       "hex": ""
     },
     "txinwitness": [
       "304402202d7d72d425e407160554e9c29688164a7e5c2f380c86e26c0595a7c6c8d526df02206ff13970212a77d6febcdcdcc2945db3947f02137324ae7d822b4fa7f812921001",
       "024633c32245c6709e7f756c41e0f163919fa00977798f30245d3498f88c53e894",
       "76a91427275283377b40957701cecd37d2e170c41d387488ac"
     ],
     "sequence": 4294967295
   }
 ],
 "vout": [
   {
     "value": 49.999991,
     "n": 0,
     "scriptPubKey": {
       "asm": "0 f545040775837a55962bb8abfcc341f574d67917",
       "hex": "0014f545040775837a55962bb8abfcc341f574d67917",
       "reqSigs": 1,
       "type": "witness_v0_keyhash",
       "addresses": [
         "bcrt1q74zsgpm4sda9t93thz4les6p746dv7gh4jhqxz"
       ]
     }
   }
 ]
}

但是當我嘗試發送它(sendrawtransaction)時,我收到了這個錯誤:

error code: -26
error message:
non-mandatory-script-verify-flag (Signature must be zero for failed CHECK(MULTI)SIG operation) (code 64)

其中 SCRIPT-CODE 是我的 UTXO scriptpubkey hex(見證版本見證程序)然後我“合併”所有值,如下所示:

這是你的問題。與 P2SH 一樣,P2WSH 的 scriptCode 不是 scriptPubKey。它是 P2WSH 輸出具有雜湊值的腳本。所以在這種情況下scriptCode 是witnessScript,而不是scriptPubKey。

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