I have multiple partially signed transactions that I want to combine into one transaction. All those transactions were signed using the same key so it should be possible to combine all those partial signed into one combined transaction that can be signed and broadcasted at once using one key. According with bitcoin's rpc function combinerawtransaction
is the proper to be used in my case but that function is not working because instead of combining all partial signed transaction into one is returning only the first partial signed transaction (it does not matter the order of the array, it will return always the first element)
Here you have the way I am trying to combine two partial signed address:
bitcoin-cli combinerawtransaction '["020000000001014a05cf2073d4ee6aa61256159e421d9f12291c44fc9607d99a4045ab192a580a01000000232200209acb3925f27bec7d8ac16b49705f6d47d5b87d48dc8571d3f49b10dcc7d89051ffffffff037cb002000000000016001488427232a9085b4ab6c334c6115725765864a6ad521d000000000000160014c2fe1292769b585b91fb8b045c651d79398589cc540700000000000016001454c64819279b8cc3e78e5f2be7b9121f1caa2386040047304402207abf6df0650b8723677d493b182e742a8dddd89ad1ee8eaa1c65a9b559841ecb022052fe5bcad01702e0e73c3b34cbfef957ba8e4744d614104f5d8fbc3d57cad4ce010069522103f6de61c401c947aad006ba9dbfdaad795e77be06972a3fb7308e70049d4026db2103e33af80b92e4efd64852166d6126e10aafdcc741579c67c6aa9eb89080cebeb221029791c6e3f0dc5bfa63db3f5aa0066badd6c5608d2a75394124d14df78795178153ae00000000", "02000000000101419e71a8980f8b86890a249e69bc9461f677dbefe4c856eb38baa361f0121d070000000023220020a8c4e11c15bcc878d57238016fe896c586508c913e0b300d80fa9409b031efb7ffffffff037cb002000000000016001488427232a9085b4ab6c334c6115725765864a6ad521d000000000000160014c2fe1292769b585b91fb8b045c651d79398589cc540700000000000016001454c64819279b8cc3e78e5f2be7b9121f1caa23860400473044022061b31eb92fb0555d368c2349ef9584df89bfc573a37acfd0bbf2de18d6cb51420220785706c33d3b7b735e434decddf1520ce687b168d17b40527da2712a3634f42f010069522103f6de61c401c947aad006ba9dbfdaad795e77be06972a3fb7308e70049d4026db2103e33af80b92e4efd64852166d6126e10aafdcc741579c67c6aa9eb89080cebeb221027152e86c82d162b47684a52cd9e74ed57b9fc2295531d8da6a560a7a602357fc53ae00000000"]'
The above command is executed without any errors and returns the following transaction:
02000000000101419e71a8980f8b86890a249e69bc9461f677dbefe4c856eb38baa361f0121d070000000023220020a8c4e11c15bcc878d57238016fe896c586508c913e0b300d80fa9409b031efb7ffffffff037cb002000000000016001488427232a9085b4ab6c334c6115725765864a6ad521d000000000000160014c2fe1292769b585b91fb8b045c651d79398589cc540700000000000016001454c64819279b8cc3e78e5f2be7b9121f1caa23860400473044022061b31eb92fb0555d368c2349ef9584df89bfc573a37acfd0bbf2de18d6cb51420220785706c33d3b7b735e434decddf1520ce687b168d17b40527da2712a3634f42f010069522103f6de61c401c947aad006ba9dbfdaad795e77be06972a3fb7308e70049d4026db2103e33af80b92e4efd64852166d6126e10aafdcc741579c67c6aa9eb89080cebeb221027152e86c82d162b47684a52cd9e74ed57b9fc2295531d8da6a560a7a602357fc53ae00000000
And that raw transaction is exactly the first raw transaction passed in the array to combinerawtransaction's function and returned unmodified
I am a bit lost because I do not know what is happening to not having both transactions combined. Also, I am using bitcoin testnet, I can sign and broadcast those transactions individually but I cannot combine them into one, any help will be appreciated
Steps to reproduce how I created those raw transactions:
- First of all I create a 2-3 multisig address:
$participants = [];
$participants[] = "03e33af80b92e4efd64852166d6126e10aafdcc741579c67c6aa9eb89080cebeb2";//pubkey1
$participants[] = "03f6de61c401c947aad006ba9dbfdaad795e77be06972a3fb7308e70049d4026db";//pubkey2
$participants[] = "029791c6e3f0dc5bfa63db3f5aa0066badd6c5608d2a75394124d14df787951781";//pubkey3
$res = $this->bitcoin->addmultisigaddress($participants, $pubkey_str);
$multisig_address = $res["address"];
$redeemScript = $res["redeemScript"];
$this->bitcoin->importaddress($multisig_address, "", false); // I import the multisig address so I can check incoming transactions
The above code is to create the multisig address associated to the first raw transaction, to create the multisig address associated to the second transaction repeat same steps but changing the third pubkey for this 027152e86c82d162b47684a52cd9e74ed57b9fc2295531d8da6a560a7a602357fc
Once I created both multisig address I proceed to send some funds to both multisig address. You can check both txids:
0a582a19ab45409ad90796fc441c29129f1d429e155612a66aeed47320cf054a
and071d12f061a3ba38eb56c8e4efdb77f66194bc699e240a89868b0f98a8719e41
(respectively). To fund both addresses I just opened a testnet account using electrum and spend some btc testnet.Now the next step is to create partial signed transactions (using third pubkeys). For that I need to check unspent outputs and create a raw transaction based on that data.
$res = $this->bitcoin->listunspent(2, 9999999, json_decode('["'.$multisig_address.'"]'));
$fee = 0.00002;
$total_amount = 0.00;
$total_amount = 0.00;
$txids = [];
$vouts = [];
$amounts = [];
$scriptPubs = [];
for($i=0; $i<count($transactions); $i++){
$txids[] = $transactions[$i]["txid"];
$total_amount+=$transactions[$i]["amount"];
$vouts[] = $transactions[$i]["vout"];
$amounts[] = $transactions[$i]["amount"];
$scriptPubs[] = $transactions[$i]["scriptPubKey"];
}
$amount1 = 0.00176252;
$amount2 = 0.00007506;
$amount3 = 0.00001876;
$address1 = "tb1q3pp8yv4fppd54dkrxnrpz4e9wevxff4d2v3r6e";
$address2 = "tb1qctlp9ynkndv9hy0m3vz9cega0yuctzwv6z273w";
$address3 = "tb1q2nrysxf8nwxv8euwtu470wgjruw25guxkal3wd";
$inputs = '[';
for($j=0; $j<count($vouts); $j++){
$inputs.='{
"txid": "'.$txids[$j].'",
"vout": '.$vouts[$j].'
}';
if($j+1!=count($vouts)){
$inputs.=',';
}
}
$inputs.=']';
$outputs = '{"'.$address1.'": '.$amount1.', "'.$address2.'": '.$amount2.', "'.$address3.'": '.$amount3.'}';
$rawtransaction = $this->bitcoin->createrawtransaction(json_decode($inputs), json_decode($outputs));
$prevtxs = '[';
for($j=0; $j<count($txids); $j++){
$prevtxs .= '{
"txid": "'.$txids[$j].'",
"vout": '.$vouts[$j].',
"scriptPubKey": "'.$scriptPubs[$j].'",
"redeemScript": "'.$redeemScript.'",
"amount": '.$amounts[$j].'
}';
if($j+1!=count($txids)){
$prevtxs.=',';
}
}
$prevtxs.=']';
$private_key = $this->dumpKey($pubkey3_privkey); // replace this value with cTe9h3HqgqC7wzUsVVw7hgoPkBNLUuChZNB7aKFsSYeTi5MYcABX or cQon9MgHPoAj3wBU8ne2BVaThTuRkXvb9FUFyQdjePUrYWTjdCaE
$partially_signed = $this->signrawtransactionwithkey($rawtransaction, json_decode('["'.$private_key.'"]'), json_decode($prevtxs))["hex"]; // and in this step I get the transaction hex string
In case you have a bitcoin node with testnet blockchain you can verify that pubkey1 (cPkPnf3qhf1AALzroHixPTYBq2cLQ9HLs9fvkTsS82ccBGZDHFaV
) or pubkey2 (cQmzvzai8ft574ErkUH7nPVcP2SbR7xaPurKigWGPYVbhfMop9ia
) can sign partial signed raw transactions