Transactions

建構/發送多重簽名交易時出錯

  • January 17, 2019

在這裡舉個例子:https ://bitcoinj.github.io/working-with-contracts

我相信我做的一切都是正確的。但是我的程序無法正確傳播或由於 tx 錯誤而無法確定原因

有幾件事我認為是原因

  1. 我的 peergroup.broadcastTransaction(spendTx) 沒有正確廣播 2) 格式錯誤的原始交易或腳本(我假設是這樣,但同樣沒有錯誤) 3) 通常不了解將輸對外連結接到輸入並對其進行簽名的最佳方法適當地(例如,我是否使用 UTXO 類或 TransactionSignature) 3)試圖從被監視的地址花費資金。我有解鎖 UTXO 的必要密鑰,但我想看看我是否可以在不使用錢包類的情況下花費這些資金 4)普遍缺乏或不完整的比特幣多重簽名支持。我希望不是這樣,因為我真的很想讓這個工作。但是——我認為這不是最大的問題,因為我執行了單元測試,它們仍然檢查得很乾淨。

一步通過程式碼來徹底:

為 2-of-3 多重簽名合約創建 3 個 ECKey,將它們放入列表中,創建一個按字典順序對密鑰進行排序並編寫 m-of-n 多重簽名輸出腳本的兌換腳本,然後實例化一個 Transaction 對象並將其分配為 OUTPUT我將用作我的 INPUT(金額 + 贖回腳本)AKA 我將花費的 UTXO(編輯:快速提及。我真正使用的 ECKey 是我不久前製作的硬編碼值,這些是為了說明目的。我還應該提到這是一個 P2SH 多重簽名,而不是原始的非標準多重簽名。

ECKey keyA = new ECKey();
ECKey keyB = new ECKey();
ECKey keyC = new ECKey();

List<ECKey> keys = ImmutableList.of(key1, key2, key3);

Script script = ScriptBuilder.createRedeemScript(2, keys);
Script scriptPubKey = ScriptBuilder.createP2SHOutputScript(script);

Transaction contract = new Transaction(params);
TransactionOutput multiSigOutput = contract.addOutput(Coin.valueOf(50000), scriptPubKey);

創建第二個交易對象,我將使用它來組裝輸出腳本 AKA(值 + 目標)地址,我將簽署我的 UTXO 到該地址。還有 sigHash 由我的 2 個密鑰簽名並添加到交易的 scriptSig

                       Transaction spendTx = new Transaction(params);
                       Address address = Address.fromBase58(params, "19EfMrs5WkcvtBBnuEqP6v1yppeWww61Kc");
                       Script outputScript = ScriptBuilder.createOutputScript(address);
                       spendTx.addOutput(multiSigOutput.getValue(), outputScript);
//                        System.out.println(spendTx.getOutputs());
                       TransactionInput input = spendTx.addInput(multiSigOutput);

現在手動對輸入進行簽名…(簽名的順序與腳本中的順序相同)

//sign transaction manually
Sha256Hash sigHash = spendTx.hashForSignature(0, script, Transaction.SigHash.ALL, false);
ECKey.ECDSASignature signature = list.get(0).sign(sigHash);
ECKey.ECDSASignature signature1 = list.get(1).sign(sigHash);
TransactionSignature txSig = new TransactionSignature(signature, Transaction.SigHash.ALL, false);
TransactionSignature txSig1 = new TransactionSignature(signature1, Transaction.SigHash.ALL, false);

…現在創建 multisiginputscript,驗證和廣播 tx

                       Script inputScript = ScriptBuilder.createP2SHMultiSigInputScript((ImmutableList.of(txSig, txSig1)));
//                        System.out.println(inputScript);
                       input.setScriptSig(inputScript);
                       input.verify(multiSigOutput);

                       peerGroup.broadcastTransaction(spendTx);

                       System.out.println(kit.peerGroup().getConnectedPeers());
                       System.out.println("transaction broadcasted");

好的…這不會傳播,但​​驗證會檢查出來。而且我什至不知道這是否是一個網路問題,因為它是一個程式碼問題,因為當我將輸出腳本中的值更改為 > UTXO 的餘額時,它不會像我想像的那樣拋出 InsufficientMoneyException 它應該。我會顯示一些錯誤日誌,但沒有。唯一的錯誤是當我將 createmultisiginputscript 更改為 createP2SHmultisiginputscript 時,控制台會顯示一個非空 nulldummy 錯誤,我也無法修復該錯誤,因此我永遠無法知道更改為該方法是否是正確的修復。我想我也正確設置了與對等組的連接

File chainFile = new File(this.getFilesDir(), "test.spvchain");
System.out.println("does chainfile exist?"  + chainFile.exists());
if(chainFile.exists()) {
   try {
       SPVBlockStore chainStore = new SPVBlockStore(params, chainFile);
       BlockChain chain = new BlockChain(params, chainStore);
       peerGroup = new PeerGroup(params, chain);
       peerGroup.addPeerDiscovery(new DnsDiscovery(params));
       peerGroup.startAsync();
   } catch (BlockStoreException e) {
       e.printStackTrace();
   }

所以我真的不明白……我得出的結論是我的理解不知何故。很抱歉這篇令人困惑的長篇文章。已經好幾天了。任何人都可以幫忙嗎?

編輯:這是原始交易

十六進制:

在日誌中:

fbb119d8990cd3912a9ec0118fe3ad8ad61a8388e4a13dd342d9eb67aacfdc65

01-12 17:49:20.670 2507年至2507年/ com.cryptoapp.app I / System.out的:在0 [] PUSHDATA(71)[3044022022b97b9372d35acaea70f3735dee290f5697cab7b5d6be6f7cdfe31139fba4f90220651091b83570843d4fe8afe02d81417194908b0f6af6f8f3b8f1ad020592409f01] PUSHDATA(71)[3044022036eff4f54b8bf3f834f7bb6e417a04a6a696047f5c75a896c6f9b624ad87680a02200bf2115b64b3b15647178b69151d4588d8a4ade16a4d66e375d0e1265c79fad601] PUSHDATA1 [5221025ab78e076801b45ccb2172bce562103cce1714edbeb02ce6123ce1235eb08c762102d1b74577050b696d5886a7afa61d099ea7ab0a3797766f9819dbd72526b0ce512103facf04db5d9bee657151e30c21e839489c326a277891ebcf75b736ec1e17fc1f53ae] 0.0005 BTC 01-12 17:49:20.670 2507年至2507年/ com.cryptoapp.app I / System.out的:外點:c33858b433ef445db35a84daa4da772895df7f03af4b31f21cfa199ea1c017d9:0 hash160:6d49586d7529626aaab49812bcd7839aee7e5800 01-12 17:49:20.670 2507年至2507年/ COM。cryptoapp.app I/System.out: out DUP HASH160 PUSHDATA(20)[5a566f4eda18e818b8d5ca04ee7c5fa3cfbf0e00] EQUALVERIFY CHECKSIG 0.0005 BTC 01-12 17:49:20.670 2507-2507/com.cryptoapp.app I/System.out: 費用kB, 0.00 BTC for 337 bytes 01-12 17:49:20.670 2507-2507/com.cryptoapp.app I/System.out: prps UNKNOWN

檢查您發布的交易數據的一些評論。

1)我檢查了你消費的UTXO,也就是UTXO

  • 9e7562d19165077d566af47bfbc18283629ed6799da8862660dfb037c353de11
  • 索引 0

但是,您的交易輸入目前引用了以下 UTXO:

  • c33858b433ef445db35a84daa4da772895df7f03af4b31f21cfa199ea1c017d9
  • 索引 0

這不是主網上的確認交易。

2)您的輸入腳本似乎格式正確,可以使用您的 P2SH(Multisig) 輸出:

  • zero
  • [3044022022b97b9372d35acaea70f3735dee290f5697cab7b5d6be6f7cdfe31139fba4f90220651091b83570843d4fe8afe02d81417194908b0f6af6f8f3b8f1ad020592409f01]
  • [3044022036eff4f54b8bf3f834f7bb6e417a04a6a696047f5c75a896c6f9b624ad87680a02200bf2115b64b3b15647178b69151d4588d8a4ade16a4d66e375d0e1265c79fad601]
  • [2 [025ab78e076801b45ccb2172bce562103cce1714edbeb02ce6123ce1235eb08c76] [02d1b74577050b696d5886a7afa61d099ea7ab0a3797766f9819dbd72526b0ce51] [03facf04db5d9bee657151e30c21e839489c326a277891ebcf75b736ec1e17fc1f] 3 checkmultisig]

最後一個元素是嵌入式腳本,並且應該散列到您花費的 UTXO 中的 20B 摘要:它確實正確地散列到6d49586d7529626aaab49812bcd7839aee7e5800.

供您參考,您的 UTXO 的 P2SH(Multisig) 輸出腳本是:"hash160 [6d49586d7529626aaab49812bcd7839aee7e5800] equal",請注意雜湊是相同的,所以這很好。

  1. 您沒有在交易中包含費用。50000 sats 的輸出量與 UTXO 量相同。此交易需要支付最低費用才能被記憶體池接受。

我希望這有幫助。

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