Signature

使用 bitcoinj 簽署具有多個輸入的比特幣交易。交易廣播失敗

  • August 11, 2018

再會!我正在使用低級 API 來製作 tx 並離線簽名。但經過所有準備後,我嘗試廣播它,然後我從網路收到錯誤:

16: mandatory-script-verify-flag-failed (signature must be zero for failed check(multi)sig operation)

首先,我在沒有簽名輸入的情況下創建 tx,然後我嘗試使用我的 priv 密鑰對每個輸入進行簽名。

這是簽名前的原始交易:

01000000028bcf82619e93eb92cc78d5bb0b7b22d6ee419820428402e721fbac1386c9673f0000000000ffffffffd50ea1cd97af5295cddcd4f0c7c0d531fed5683bde80af45ede25a0571c31add0100000000ffffffff02087f0300000000001976a9146fb643fe63bcc6c352899298d6072cc5d4178c0f88acfa6b0100000000001976a914196e59ee4c151e742af69bca308fc1b4445c577288ac00000000

從<https://live.blockcypher.com/btc/decodetx/>解析 tx :

{
   "addresses": [
       "16Yb7QP5jVmjXvHawH2ZA66k1b46FmtmE3", 
       "13KU69194fJj13G1SajUWokudsuekhT1kw", 
       "1BBgML68FuyRwU8RzwYn1FvqAXDDSgjVKC"
   ], 
   "block_height": -1, 
   "block_index": -1, 
   "confirmations": 0, 
   "double_spend": false, 
   "fees": 55194, 
   "hash": "2010928be1525a89aae1e0ece367757f6deb3754bfc4c891ffddbad403ecc3c9", 
   "inputs": [
       {
           "addresses": [
               "16Yb7QP5jVmjXvHawH2ZA66k1b46FmtmE3"
           ], 
           "age": 534819, 
           "output_index": 0, 
           "output_value": 251628, 
           "prev_hash": "3f67c98613acfb21e7028442209841eed6227b0bbbd578cc92eb939e6182cf8b", 
           "script_type": "pay-to-pubkey-hash", 
           "sequence": 4294967295
       }, 
       {
           "addresses": [
               "13KU69194fJj13G1SajUWokudsuekhT1kw"
           ], 
           "age": 534818, 
           "output_index": 1, 
           "output_value": 125872, 
           "prev_hash": "dd1ac371055ae2ed45af80de3b68d5fe31d5c0c7f0d4dccd9552af97cda10ed5", 
           "script_type": "pay-to-pubkey-hash", 
           "sequence": 4294967295
       }
   ], 
   "outputs": [
       {
           "addresses": [
               "1BBgML68FuyRwU8RzwYn1FvqAXDDSgjVKC"
           ], 
           "script": "76a9146fb643fe63bcc6c352899298d6072cc5d4178c0f88ac", 
           "script_type": "pay-to-pubkey-hash", 
           "value": 229128
       }, 
       {
           "addresses": [
               "13KU69194fJj13G1SajUWokudsuekhT1kw"
           ], 
           "script": "76a914196e59ee4c151e742af69bca308fc1b4445c577288ac", 
           "script_type": "pay-to-pubkey-hash", 
           "value": 93178
       }
   ], 
   "preference": "high", 
   "received": "2018-08-05T18:04:52.877018121Z", 
   "relayed_by": "54.162.141.93", 
   "size": 160, 
   "total": 322306, 
   "ver": 1, 
   "vin_sz": 2, 
   "vout_sz": 2
}

這是我簽署每個輸入的程式碼:

for (int i = 0; i &lt; transaction.getInputs().size(); i++) {

   TransactionInput transactionInput = transaction.getInput(i);
   String addressFromUtxo = mUTXOs.get(i).getAddress();
   byte[] privKeyBytes = getPrivKeyBitesForAddress(addressFromUtxo);
   ECKey ecKey = ECKey.fromPrivate(privKeyBytes);

   Script scriptPubKey = ScriptBuilder.createOutputScript(Address.fromBase58(params, mUTXOs.get(i).getAddress()));

   Sha256Hash hash = transaction.hashForSignature(i, scriptPubKey, Transaction.SigHash.ALL, false);
   ECKey.ECDSASignature ecSig = ecKey.sign(hash);   
   TransactionSignature txSig = new TransactionSignature(ecSig, Transaction.SigHash.ALL, false);
   transactionInput.setScriptSig(ScriptBuilder.createInputScript(txSig, ecKey));
}

//serialization and broadcasting
byte[] bytesRawTransaction = transaction.bitcoinSerialize();
String rawTransaction = HEX.encode(bytesRawTransaction);
broadcastTx(rawTransaction);

這裡是我的原始 tx 在簽名後的樣子:

01000000028bcf82619e93eb92cc78d5bb0b7b22d6ee419820428402e721fbac1386c9673f000000006a473044022054720cc14562000ed1a6fa7952d2343bef48e2fa4fd0f1c1894579026ae83692022042735beb03c4d53c8d72126e1e4e8bee7acd5530284b05d6707a4e71cc891e9a01210312e1997fc0cb4c037c94885e7e4a8d0eca9d5cff8628cc3d870e5c158c9b0901ffffffffd50ea1cd97af5295cddcd4f0c7c0d531fed5683bde80af45ede25a0571c31add010000006a47304402206a70b6dacea9e9435c21fe920471daccf2edb636592b9d9163b1f5d740e582e102203416f80e9859fcfacc9f41ea3e04774ef47c9b0b9fa5a61f2b77dffee4c2710e012103522a472dd00a929e0f0980b98eb6a0d10a6e5a6ff7d45709cdb9f022b881ca66ffffffff02087f0300000000001976a9146fb643fe63bcc6c352899298d6072cc5d4178c0f88acfa6b0100000000001976a914196e59ee4c151e742af69bca308fc1b4445c577288ac00000000

從<https://live.blockcypher.com/btc/decodetx/>解析 tx :

{
   "addresses": [
       "16Yb7QP5jVmjXvHawH2ZA66k1b46FmtmE3", 
       "13KU69194fJj13G1SajUWokudsuekhT1kw", 
       "1BBgML68FuyRwU8RzwYn1FvqAXDDSgjVKC"
   ], 
   "block_height": -1, 
   "block_index": -1, 
   "confirmations": 0, 
   "double_spend": false, 
   "fees": 55194, 
   "hash": "26859671de7bd5f0ab758517d90dcb2ef7c8a8a331a2d4fc59c7d98e07857d09", 
   "inputs": [
       {
           "addresses": [
               "16Yb7QP5jVmjXvHawH2ZA66k1b46FmtmE3"
           ], 
           "age": 534819, 
           "output_index": 0, 
           "output_value": 251628, 
           "prev_hash": "3f67c98613acfb21e7028442209841eed6227b0bbbd578cc92eb939e6182cf8b", 
           "script": "473044022054720cc14562000ed1a6fa7952d2343bef48e2fa4fd0f1c1894579026ae83692022042735beb03c4d53c8d72126e1e4e8bee7acd5530284b05d6707a4e71cc891e9a01210312e1997fc0cb4c037c94885e7e4a8d0eca9d5cff8628cc3d870e5c158c9b0901", 
           "script_type": "pay-to-pubkey-hash", 
           "sequence": 4294967295
       }, 
       {
           "addresses": [
               "13KU69194fJj13G1SajUWokudsuekhT1kw"
           ], 
           "age": 534818, 
           "output_index": 1, 
           "output_value": 125872, 
           "prev_hash": "dd1ac371055ae2ed45af80de3b68d5fe31d5c0c7f0d4dccd9552af97cda10ed5", 
           "script": "47304402206a70b6dacea9e9435c21fe920471daccf2edb636592b9d9163b1f5d740e582e102203416f80e9859fcfacc9f41ea3e04774ef47c9b0b9fa5a61f2b77dffee4c2710e012103522a472dd00a929e0f0980b98eb6a0d10a6e5a6ff7d45709cdb9f022b881ca66", 
           "script_type": "pay-to-pubkey-hash", 
           "sequence": 4294967295
       }
   ], 
   "outputs": [
       {
           "addresses": [
               "1BBgML68FuyRwU8RzwYn1FvqAXDDSgjVKC"
           ], 
           "script": "76a9146fb643fe63bcc6c352899298d6072cc5d4178c0f88ac", 
           "script_type": "pay-to-pubkey-hash", 
           "value": 229128
       }, 
       {
           "addresses": [
               "13KU69194fJj13G1SajUWokudsuekhT1kw"
           ], 
           "script": "76a914196e59ee4c151e742af69bca308fc1b4445c577288ac", 
           "script_type": "pay-to-pubkey-hash", 
           "value": 93178
       }
   ], 
   "preference": "high", 
   "received": "2018-08-05T10:44:42.584042561Z", 
   "relayed_by": "54.162.141.93", 
   "size": 372, 
   "total": 322306, 
   "ver": 1, 
   "vin_sz": 2, 
   "vout_sz": 2
}

畢竟我得到了:

16: mandatory-script-verify-flag-failed (signature must be zero for failed check(multi)sig operation)

請幫幫我,我做錯了什麼???

最後我找到了解決方案以及我做錯了什麼。簽署 tx 的方式是完全正確的,問題出在另一件事上。在我想廣播 tx 之前,我計算每 kb 的費用(不是固定的)。簽署 tx 後 - 原始 tx 的大小增加,費用金額相應增加。之後,我應該為更改地址提供新的更改(tx 的第二個輸出的值)。在那之後,我應該再簽署一次輸入,因為更改的輸出值已更改。不幸的是,我以前沒有這樣做。也許它對某人有用。

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