Electron-cash: Serialization error while loading partially signed Mecenas transaction from file

Created on 23 Sep 2019  路  4Comments  路  Source: Electron-Cash/Electron-Cash

I'm making escrow version of Mecenas contract and I need to do some sort of multisig there. I generate partially signed transaction with dummy script instead od scriptSig, save it with "Save" button on transaction window, and then, when I want to load it with main window method

try:
    tx = self.main_window.read_tx_from_file(fileName=None)
except SerializationError as e:
    self.show_critical(_("Electron Cash was unable to deserialize the transaction:") + "\n" + str(e))

I get error:

Traceback (most recent call last):
  File "/usr/lib/python3.7/site-packages/electroncash_gui/qt/main_window.py", line 3273, in tx_from_text
    tx.deserialize()
  File "/usr/lib/python3.7/site-packages/electroncash/transaction.py", line 518, in deserialize
    d = deserialize(self.raw)
  File "/usr/lib/python3.7/site-packages/electroncash/transaction.py", line 352, in deserialize
    d['outputs'] = [parse_output(vds, i) for i in range(n_vout)]
  File "/usr/lib/python3.7/site-packages/electroncash/transaction.py", line 352, in <listcomp>
    d['outputs'] = [parse_output(vds, i) for i in range(n_vout)]
  File "/usr/lib/python3.7/site-packages/electroncash/transaction.py", line 335, in parse_output
    d['value'] = vds.read_int64()
  File "/usr/lib/python3.7/site-packages/electroncash/transaction.py", line 112, in read_int64
    def read_int64(self): return self._read_num('<q')
  File "/usr/lib/python3.7/site-packages/electroncash/transaction.py", line 157, in _read_num
    raise SerializationError(e)
electroncash.transaction.SerializationError: unpack_from requires a buffer of at least 8 bytes

I had similar problem with loading transactions few months ago but I assumed I'm just doing something wrong, but now I'm quite confident it should work :P
The transaction in question is the following:

unsigned.txt

bug

All 4 comments

Thanks for reporting this. I鈥檒l investigate it either now or when I get back from vacation.

OK, the issue is about what I expected. I've decomposed your tx into its parts, below.

The issue is that when Electron Cash saves transaction inputs that are incomplete, it "helpfully" inserts the input's value just after the sequence number. However when reading the transaction, it only knows to try reading that input value for very special scriptSig types (which it believes are incomplete P2PK, or P2PKH, or P2SH Multisigs). Since in this case it is not a special type, it doesn't think to actually read the value. This means that it starts trying to parse the rest of the transaction and snarfs up the value first, and everything ends up all confused. The specific exception you see will vary.

See transaction.py's parse_input function and serialize_input method.

02000000  (tx version)
01  (num inputs)
5754f752c8f957f32dd7e630216ba9044d9edd3bcb7c9b61723d4b972d8a934c   (input txid)
04000000 (input tx's output index)
fdb901   (varint scriptsig length: 441)
Scriptsig:
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000   (sequence number)
1027000000000000      (<<<<   THE PROBLEM -- electron cash inserted txin's value!)
01  (num outputs)
ff24000000000000  (output value
19  (varint output script length: 25)
76a914236db63400b54be82597c58766e69340f9a3675988ac\  (output script
00000000  (locktime)

I'm going to submit a PR with a small fix for this, at least as far as smart contracts go. Ultimately the root of this problem is that our partially-signed transaction format (with the extra inserted value) is ... kinda dumb. A while ago I started on #1394 to do this but it's a bit of a headache.

oops didn't mean to close just yet

Thanks for looking at this.. 馃憤

Was this page helpful?
0 / 5 - 0 ratings