Skip to content

Commit c39e305

Browse files
committed
refactor: eip 155 support
1 parent f1ba5f6 commit c39e305

6 files changed

Lines changed: 30 additions & 40 deletions

File tree

crypto/enums/constants.py

Lines changed: 0 additions & 5 deletions
This file was deleted.

crypto/identity/private_key.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
from base58 import b58decode
66

77
from crypto.configuration.network import Network
8-
from crypto.enums.constants import Constants
98

109
class PrivateKey(object):
1110
def __init__(self, private_key: str):
@@ -26,7 +25,7 @@ def sign(self, message: bytes) -> bytes:
2625

2726
der = self.private_key.sign_recoverable(message_hash, hasher=None)
2827

29-
return bytes([der[64] + Constants.ETHEREUM_RECOVERY_ID_OFFSET.value]) + der[0:64]
28+
return bytes([der[64]]) + der[0:64]
3029

3130
def to_hex(self):
3231
"""Returns a private key in hex format

crypto/transactions/builder/abstract_transaction_builder.py

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
from crypto.configuration.network import Network
21
from crypto.identity.private_key import PrivateKey
32
from crypto.transactions.types.abstract_transaction import AbstractTransaction
43

@@ -9,9 +8,8 @@ def __init__(self, data: dict):
98
'value': 0,
109
'senderPublicKey': '',
1110
'gasPrice': '5',
11+
'gasLimit': 1_000_000,
1212
'nonce': '1',
13-
'network': Network.get_network().chain_id(),
14-
'gas': 1_000_000,
1513
'data': '',
1614

1715
**data,
@@ -26,8 +24,8 @@ def __str__(self):
2624
def new(cls):
2725
return cls({})
2826

29-
def gas(self, gas: int):
30-
self.transaction.data['gas'] = int(gas)
27+
def gas_limit(self, gas_limit: int):
28+
self.transaction.data['gasLimit'] = int(gas_limit)
3129
return self
3230

3331
def to(self, to: str):
@@ -42,10 +40,6 @@ def nonce(self, nonce: str):
4240
self.transaction.data['nonce'] = nonce
4341
return self
4442

45-
def network(self, network: int):
46-
self.transaction.data['network'] = network
47-
return self
48-
4943
def sign(self, passphrase: str):
5044
keys = PrivateKey.from_passphrase(passphrase)
5145
self.transaction.data['senderPublicKey'] = keys.public_key

crypto/transactions/deserializer.py

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from binascii import unhexlify
22
from typing import Optional
3-
from crypto.enums.constants import Constants
3+
from crypto.configuration.network import Network
44
from crypto.enums.contract_abi_type import ContractAbiType
55
from crypto.transactions.types.abstract_transaction import AbstractTransaction
66
from crypto.transactions.types.multipayment import Multipayment
@@ -26,7 +26,7 @@ def __init__(self, serialized: str):
2626
self.serialized = unhexlify(serialized) if isinstance(serialized, str) else serialized
2727
self.pointer = 0
2828

29-
self.encoded_rlp = '0x' + serialized[2:]
29+
self.encoded_rlp = '0x' + serialized
3030

3131
@staticmethod
3232
def new(serialized: str):
@@ -36,19 +36,18 @@ def deserialize(self) -> AbstractTransaction:
3636
decoded_rlp = RlpDecoder.decode(self.encoded_rlp)
3737

3838
data = {
39-
'network': Deserializer.__parse_number(decoded_rlp[0]),
40-
'nonce': Deserializer.__parse_big_number(decoded_rlp[1]),
41-
'gasPrice': Deserializer.__parse_number(decoded_rlp[3]),
42-
'gas': Deserializer.__parse_number(decoded_rlp[4]),
43-
'to': Deserializer.__parse_address(decoded_rlp[5]),
44-
'value': Deserializer.__parse_big_number(decoded_rlp[6]),
45-
'data': Deserializer.__parse_hex(decoded_rlp[7]),
39+
'nonce': Deserializer.__parse_big_number(decoded_rlp[0]),
40+
'gasPrice': Deserializer.__parse_number(decoded_rlp[1]),
41+
'gasLimit': Deserializer.__parse_number(decoded_rlp[2]),
42+
'to': Deserializer.__parse_address(decoded_rlp[3]),
43+
'value': Deserializer.__parse_big_number(decoded_rlp[4]),
44+
'data': Deserializer.__parse_hex(decoded_rlp[5]),
4645
}
4746

48-
if len(decoded_rlp) == 12:
49-
data['v'] = Deserializer.__parse_number(decoded_rlp[9]) + Constants.ETHEREUM_RECOVERY_ID_OFFSET.value
50-
data['r'] = Deserializer.__parse_hex(decoded_rlp[10])
51-
data['s'] = Deserializer.__parse_hex(decoded_rlp[11])
47+
if len(decoded_rlp) >= 9:
48+
data['v'] = Deserializer.__parse_number(decoded_rlp[6]) + (Network.get_network().chain_id() * 2 + 35)
49+
data['r'] = Deserializer.__parse_hex(decoded_rlp[7])
50+
data['s'] = Deserializer.__parse_hex(decoded_rlp[8])
5251

5352
transaction = self.__guess_transaction_from_data(data)
5453

crypto/transactions/types/abstract_transaction.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import json
22
from typing import Optional
33

4-
from crypto.enums.constants import Constants
4+
from crypto.configuration.network import Network
55
from crypto.enums.contract_abi_type import ContractAbiType
66
from crypto.identity.address import Address
77
from crypto.identity.private_key import PrivateKey
@@ -73,7 +73,7 @@ def hash(self, skip_signature: bool) -> str:
7373
return TransactionUtils.to_hash(self.data, skip_signature=skip_signature)
7474

7575
def _get_signature(self):
76-
recover_id = int(self.data.get('v', 0)) - Constants.ETHEREUM_RECOVERY_ID_OFFSET.value
76+
recover_id = int(self.data.get('v', 0))
7777
r = self.data.get('r')
7878
s = self.data.get('s')
7979

crypto/utils/transaction_utils.py

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
from binascii import unhexlify
2-
import hashlib
32
import re
43

54
from Cryptodome.Hash import keccak
6-
from crypto.enums.constants import Constants
5+
from crypto.configuration.network import Network
76
from crypto.utils.rlp_encoder import RlpEncoder
87

98
class TransactionUtils:
@@ -19,25 +18,29 @@ def to_buffer(cls, transaction: dict, skip_signature: bool = False) -> bytes:
1918

2019
# Build the fields array
2120
fields = [
22-
cls.to_be_array(int(transaction['network'])),
2321
cls.to_be_array(int(transaction.get('nonce', 0))),
24-
cls.to_be_array(0),
2522
cls.to_be_array(int(transaction['gasPrice'])),
26-
cls.to_be_array(int(transaction['gas'])),
23+
cls.to_be_array(int(transaction['gasLimit'])),
2724
to,
2825
cls.to_be_array(int(transaction.get('value', 0))),
2926
bytes.fromhex(cls.parse_hex_from_str(transaction.get('data', ''))) if transaction.get('data') else b'',
30-
[],
3127
]
3228

33-
if not skip_signature and 'v' in transaction and 'r' in transaction and 's' in transaction:
34-
fields.append(cls.to_be_array(int(transaction['v']) - Constants.ETHEREUM_RECOVERY_ID_OFFSET.value))
29+
if not skip_signature and 'v' in transaction and transaction['v'] is not None and 'r' in transaction and 's' in transaction:
30+
fields.append(cls.to_be_array(int(transaction['v']) + (Network.get_network().chain_id() * 2 + 35)))
3531
fields.append(bytes.fromhex(transaction['r']))
3632
fields.append(bytes.fromhex(transaction['s']))
33+
else:
34+
# Push chainId + 0s for r and s
35+
fields.append(cls.to_be_array(Network.get_network().chain_id()))
36+
fields.append(cls.to_be_array(0))
37+
fields.append(cls.to_be_array(0))
38+
39+
# TODO: second signature handling
3740

3841
encoded = RlpEncoder.encode(fields)
3942

40-
hash_input = Constants.EIP_1559_PREFIX.value + encoded
43+
hash_input = encoded
4144

4245
return hash_input.encode()
4346

0 commit comments

Comments
 (0)