Tengo varias transacciones parcialmente firmadas que quiero combinar en una transacción. Todas esas transacciones se firmaron con la misma clave, por lo que debería ser posible combinar todas las firmas parciales en una transacción combinada que se pueda firmar y transmitir a la vez con una clave. De acuerdo con la función rpc de bitcoin, combinerawtransaction
es la adecuada para usar en mi caso, pero esa función no funciona porque, en lugar de combinar todas las transacciones parciales firmadas en una, solo devuelve la primera transacción parcial firmada (no importa el orden de la matriz, es devolverá siempre el primer elemento)
Aquí tiene la forma en que estoy tratando de combinar dos direcciones firmadas parciales:
bitcoin-cli combinerawtransaction '["020000000001014a05cf2073d4ee6aa61256159e421d9f12291c44fc9607d99a4045ab192a580a01000000232200209acb3925f27bec7d8ac16b49705f6d47d5b87d48dc8571d3f49b10dcc7d89051ffffffff037cb002000000000016001488427232a9085b4ab6c334c6115725765864a6ad521d000000000000160014c2fe1292769b585b91fb8b045c651d79398589cc540700000000000016001454c64819279b8cc3e78e5f2be7b9121f1caa2386040047304402207abf6df0650b8723677d493b182e742a8dddd89ad1ee8eaa1c65a9b559841ecb022052fe5bcad01702e0e73c3b34cbfef957ba8e4744d614104f5d8fbc3d57cad4ce010069522103f6de61c401c947aad006ba9dbfdaad795e77be06972a3fb7308e70049d4026db2103e33af80b92e4efd64852166d6126e10aafdcc741579c67c6aa9eb89080cebeb221029791c6e3f0dc5bfa63db3f5aa0066badd6c5608d2a75394124d14df78795178153ae00000000", "02000000000101419e71a8980f8b86890a249e69bc9461f677dbefe4c856eb38baa361f0121d070000000023220020a8c4e11c15bcc878d57238016fe896c586508c913e0b300d80fa9409b031efb7ffffffff037cb002000000000016001488427232a9085b4ab6c334c6115725765864a6ad521d000000000000160014c2fe1292769b585b91fb8b045c651d79398589cc540700000000000016001454c64819279b8cc3e78e5f2be7b9121f1caa23860400473044022061b31eb92fb0555d368c2349ef9584df89bfc573a37acfd0bbf2de18d6cb51420220785706c33d3b7b735e434decddf1520ce687b168d17b40527da2712a3634f42f010069522103f6de61c401c947aad006ba9dbfdaad795e77be06972a3fb7308e70049d4026db2103e33af80b92e4efd64852166d6126e10aafdcc741579c67c6aa9eb89080cebeb221027152e86c82d162b47684a52cd9e74ed57b9fc2295531d8da6a560a7a602357fc53ae00000000"]'
El comando anterior se ejecuta sin ningún error y devuelve la siguiente transacción:
02000000000101419e71a8980f8b86890a249e69bc9461f677dbefe4c856eb38baa361f0121d070000000023220020a8c4e11c15bcc878d57238016fe896c586508c913e0b300d80fa9409b031efb7ffffffff037cb002000000000016001488427232a9085b4ab6c334c6115725765864a6ad521d000000000000160014c2fe1292769b585b91fb8b045c651d79398589cc540700000000000016001454c64819279b8cc3e78e5f2be7b9121f1caa23860400473044022061b31eb92fb0555d368c2349ef9584df89bfc573a37acfd0bbf2de18d6cb51420220785706c33d3b7b735e434decddf1520ce687b168d17b40527da2712a3634f42f010069522103f6de61c401c947aad006ba9dbfdaad795e77be06972a3fb7308e70049d4026db2103e33af80b92e4efd64852166d6126e10aafdcc741579c67c6aa9eb89080cebeb221027152e86c82d162b47684a52cd9e74ed57b9fc2295531d8da6a560a7a602357fc53ae00000000
Y esa transacción sin procesar es exactamente la primera transacción sin procesar pasada en la matriz para combinar la función de transacción sin procesar y devuelta sin modificar
Estoy un poco perdido porque no sé qué está pasando con no tener ambas transacciones combinadas. Además, estoy usando bitcoin testnet, puedo firmar y transmitir esas transacciones individualmente pero no puedo combinarlas en una sola, cualquier ayuda será apreciada
Pasos para reproducir cómo creé esas transacciones sin procesar:
$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
El código anterior es para crear la dirección multisig asociada a la primera transacción sin procesar, para crear la dirección multisig asociada a la segunda transacción, repita los mismos pasos pero cambiando la tercera clave pública para esto.027152e86c82d162b47684a52cd9e74ed57b9fc2295531d8da6a560a7a602357fc
Una vez que creé ambas direcciones multisig, procedo a enviar algunos fondos a ambas direcciones multisig. Puede verificar ambos txids: 0a582a19ab45409ad90796fc441c29129f1d429e155612a66aeed47320cf054a
y 071d12f061a3ba38eb56c8e4efdb77f66194bc699e240a89868b0f98a8719e41
(respectivamente). Para financiar ambas direcciones, acabo de abrir una cuenta de testnet usando electrum y gasté algo de btc testnet.
Ahora, el siguiente paso es crear transacciones firmadas parciales (usando terceras claves públicas). Para eso, necesito verificar las salidas no gastadas y crear una transacción sin procesar basada en esos datos.
$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
En caso de que tenga un nodo bitcoin con testnet blockchain, puede verificar que pubkey1 ( cPkPnf3qhf1AALzroHixPTYBq2cLQ9HLs9fvkTsS82ccBGZDHFaV
) o pubkey2 ( cQmzvzai8ft574ErkUH7nPVcP2SbR7xaPurKigWGPYVbhfMop9ia
) pueden firmar transacciones sin formato firmadas parcialmente
El problema aquí es que las dos transacciones son diferentes y combinerawtransaction
no operan en transacciones diferentes (aparentemente, simplemente no hace nada en silencio). Parece que espera combinerawtransaction
tomar dos transacciones separadas y crear una nueva que tenga las entradas y salidas de ambas transacciones. (o tal vez tomar dos transacciones con los mismos resultados pero diferentes entradas y producir una transacción con las entradas combinadas y las mismas salidas). Sin embargo, eso no es lo que hace. En su lugar, en realidad toma la misma transacción (es decir, las mismas entradas y salidas) y fusiona las firmas de las mismas entradas.
No es posible hacer lo que desea porque las firmas se comprometen con las entradas y salidas particulares de esa transacción. Una vez que intenta unir una transacción con otra, esas firmas se vuelven inválidas y será necesario volver a firmar toda la transacción.
createpsbt
y combinepsbt
?
usuario103136
Kevin Gravel
Kevin Gravel