Unsigned transactions cannot be parsed by bitcoind
jasonbcox opened this issue · 5 comments
Steps to reproduce
- Setup a transaction in ElectrumABC
- Preview the transaction (do not sign it)
- Click 'Copy' to copy the raw tx to clipboard
bitcoin-cli decoderawtransaction <raw-tx-hex>
Expected output
{
"txid": "db...4d",
"hash": "db...4d",
"version": 2,
"size": 85,
"locktime": 0,
"vin": [
{
"txid": "ed...f6",
"vout": 1,
"scriptSig": {
"asm": "",
"hex": ""
},
"sequence": 4294967295
}
]...
(note empty script sig)
Actual output
error code: -22
error message:
TX decode failed
Investigation at a glance
The raw hex output by ElectrumABC appears to fill in some garbage in the scriptSig instead of the scriptSig byte length expected to be 0 (which will give output like in the Expected Output section above). The expected output was generated using createrawtransaction
(see example here: https://developer.bitcoin.org/examples/transactions.html#simple-raw-transaction ) and comparing its output fed back into decoderawtransaction
against the output from ElectrumABC.
So, when a transaction has an unsigned input, the serialized script is
41000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000021000000000000000000000000000000000000000000000000000000000000000000
It looks like garbage indeed.
The code is confusing, because of all the branching. It seems that unsigned transactions get through an "estimate_size" branch, in which a blank pubkey ("210000...") and a blank Schnorr signature ("410000...") are used in the serialization.
But simply forcing the other branch (estimate_size=Falase) does not produce a raw tx that works for "decoderawtransaction" either.
This could be the issue: https://github.com/Bitcoin-ABC/ElectrumABC/blob/master/electroncash/transaction.py#L673
There is additional (non standard) data added to each input when unsigned transactions are generated. So my initial assessment was wrong, it is not causes by dummy signatures being added.
Related discussions:
Confirmed: if I comment out that block, the hex is a proper unsigned tx that can be decoded by the node.
But it has a bunch of side effects, like being unable to sign and broadcast the generated transaction. I'll have another look at this a bit later. This is calling for a refactoring of the transaction.py module.
Thanks for doing a proper investigation. Looking forward to the fix.