From 468dd65462eecfea42fcc4a576511ffb47134b9e Mon Sep 17 00:00:00 2001 From: nolash Date: Tue, 12 Jan 2021 14:50:52 +0100 Subject: [PATCH] Avoid empty nonce string from tx --- CHANGELOG | 1 + crypto_dev_signer/eth/signer/defaultsigner.py | 5 ++- crypto_dev_signer/eth/transaction.py | 38 +++++++++++++++---- setup.py | 2 +- test/test_sign.py | 4 +- 5 files changed, 39 insertions(+), 11 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 3fa3e25..e2c4007 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -2,6 +2,7 @@ - Implement DictKeystore - Remove unused insert_key method in keystore interface - Add transaction executor helper, with adapter helper for eth + - Fix bitlength of integers in all tx fields before rlp encoding * 0.4.12 - Enforce hex strings in signer backend for sign message * 0.4.11 diff --git a/crypto_dev_signer/eth/signer/defaultsigner.py b/crypto_dev_signer/eth/signer/defaultsigner.py index eacfcda..551b023 100644 --- a/crypto_dev_signer/eth/signer/defaultsigner.py +++ b/crypto_dev_signer/eth/signer/defaultsigner.py @@ -34,7 +34,10 @@ class ReferenceSigner(Signer): g = h.digest() k = keys.PrivateKey(self.keyGetter.get(tx.sender, password)) z = keys.ecdsa_sign(message_hash=g, private_key=k) - tx.v = (tx.v * 2) + 35 + z[64] + vnum = int.from_bytes(tx.v, 'big') + v = (vnum * 2) + 35 + z[64] + byts = ((v.bit_length()-1)/8)+1 + tx.v = v.to_bytes(int(byts), 'big') tx.r = z[:32] tx.s = z[32:64] return z diff --git a/crypto_dev_signer/eth/transaction.py b/crypto_dev_signer/eth/transaction.py index 14df5f4..8a29e05 100644 --- a/crypto_dev_signer/eth/transaction.py +++ b/crypto_dev_signer/eth/transaction.py @@ -35,21 +35,36 @@ class EIP155Transaction: gas_price = int(tx['gasPrice']) except ValueError: gas_price = int(tx['gasPrice'], 16) + byts = ((gas_price.bit_length()-1)/8)+1 + gas_price = gas_price.to_bytes(int(byts), 'big') try: start_gas = int(tx['gas']) except ValueError: start_gas = int(tx['gas'], 16) + byts = ((start_gas.bit_length()-1)/8)+1 + start_gas = start_gas.to_bytes(int(byts), 'big') try: value = int(tx['value']) except ValueError: value = int(tx['value'], 16) + byts = ((value.bit_length()-1)/8)+1 + value = value.to_bytes(int(byts), 'big') try: nonce = int(nonce) except ValueError: nonce = int(nonce, 16) + byts = ((nonce.bit_length()-1)/8)+1 + nonce = nonce.to_bytes(int(byts), 'big') + + try: + chainId = int(chainId) + except ValueError: + chainId = int(chainId, 16) + byts = ((chainId.bit_length()-1)/8)+1 + chainId = chainId.to_bytes(int(byts), 'big') self.nonce = nonce self.gas_price = gas_price @@ -64,7 +79,6 @@ class EIP155Transaction: def rlp_serialize(self): - b = self.nonce.to_bytes(8, byteorder='little') s = [ self.nonce, self.gas_price, @@ -79,14 +93,24 @@ class EIP155Transaction: return rlp_encode(s) def serialize(self): - return { - 'nonce': add_hex_prefix(hex(self.nonce)), - 'gasPrice': add_hex_prefix(hex(self.gas_price)), - 'gas': add_hex_prefix(hex(self.start_gas)), + tx = { + 'nonce': add_hex_prefix(self.nonce.hex()), + 'gasPrice': add_hex_prefix(self.gas_price.hex()), + 'gas': add_hex_prefix(self.start_gas.hex()), 'to': add_hex_prefix(self.to.hex()), - 'value': add_hex_prefix(hex(self.value)), + 'value': add_hex_prefix(self.value.hex()), 'data': add_hex_prefix(self.data.hex()), - 'v': add_hex_prefix(hex(self.v)), + 'v': add_hex_prefix(self.v.hex()), 'r': add_hex_prefix(self.r.hex()), 's': add_hex_prefix(self.s.hex()), } + if tx['data'] == '': + tx['data'] = '0x' + + if tx['value'] == '': + tx['value'] = '0x00' + + if tx['nonce'] == '': + tx['nonce'] = '0x00' + + return tx diff --git a/setup.py b/setup.py index c73997a..f59cedd 100644 --- a/setup.py +++ b/setup.py @@ -24,7 +24,7 @@ f.close() setup( name="crypto-dev-signer", - version="0.4.13b4", + version="0.4.13b8", description="A signer and keystore daemon and library for cryptocurrency software development", author="Louis Holbrook", author_email="dev@holbrook.no", diff --git a/test/test_sign.py b/test/test_sign.py index 505d3f0..3785a56 100644 --- a/test/test_sign.py +++ b/test/test_sign.py @@ -68,14 +68,14 @@ class TestSign(unittest.TestCase): t = EIP155Transaction(tx_ints, 0) self.assertRegex(t.__class__.__name__, "Transaction") s = t.serialize() - self.assertEqual('{}'.format(s), "{'nonce': '0x0', 'gasPrice': '0x4a817c800', 'gas': '0x5208', 'to': '0x3535353535353535353535353535353535353535', 'value': '0x3e8', 'data': '0xdeadbeef', 'v': '0x1', 'r': '', 's': ''}") + self.assertEqual('{}'.format(s), "{'nonce': '', 'gasPrice': '0x04a817c800', 'gas': '0x5208', 'to': '0x3535353535353535353535353535353535353535', 'value': '0x03e8', 'data': '0xdeadbeef', 'v': '0x01', 'r': '', 's': ''}") r = t.rlp_serialize() self.assertEqual(r.hex(), 'ea808504a817c8008252089435353535353535353535353535353535353535358203e884deadbeef018080') t = EIP155Transaction(tx_hexs, 0) self.assertRegex(t.__class__.__name__, "Transaction") s = t.serialize() - self.assertEqual('{}'.format(s), "{'nonce': '0x0', 'gasPrice': '0x4a817c800', 'gas': '0x5208', 'to': '0x3535353535353535353535353535353535353535', 'value': '0x3e8', 'data': '0xdeadbeef', 'v': '0x1', 'r': '', 's': ''}") + self.assertEqual('{}'.format(s), "{'nonce': '', 'gasPrice': '0x04a817c800', 'gas': '0x5208', 'to': '0x3535353535353535353535353535353535353535', 'value': '0x03e8', 'data': '0xdeadbeef', 'v': '0x01', 'r': '', 's': ''}") r = t.rlp_serialize() self.assertEqual(r.hex(), 'ea808504a817c8008252089435353535353535353535353535353535353535358203e884deadbeef018080')