This commit is contained in:
nolash 2021-02-08 11:23:07 +01:00
parent 4788326c4e
commit d85d96b325
Signed by: lash
GPG Key ID: 21D2E7BB88C2A746
6 changed files with 137 additions and 3 deletions

View File

@ -7,7 +7,6 @@ from hexathon import (
def to_checksum(address_hex):
address_hex = strip_0x(address_hex)
address_hex = uniform(address_hex)
h = sha3.keccak_256()

View File

@ -25,7 +25,7 @@ import sha3
from eth_abi import encode_single
# local imports
from cic_tools.eth.checksum import to_checksum
from cic_tools.eth.address import to_checksum
from cic_tools.eth.method import (
jsonrpc_template,
erc20_balance,

View File

@ -2,7 +2,7 @@
import sys
# local imports
from cic_tools.eth.checksum import to_checksum
from cic_tools.eth.address import to_checksum
print(to_checksum(sys.argv[1]))

View File

@ -0,0 +1,51 @@
#!python3
"""Decode raw transaction
.. moduleauthor:: Louis Holbrook <dev@holbrook.no>
.. pgp:: 0826EDA1702D1E87C6E2875121D2E7BB88C2A746
"""
# SPDX-License-Identifier: GPL-3.0-or-later
# standard imports
import os
import json
import argparse
import logging
# third-party imports
from cic_tools.eth.tx import unpack_signed
logging.basicConfig(level=logging.WARNING)
logg = logging.getLogger()
default_abi_dir = os.environ.get('ETH_ABI_DIR', '/usr/share/local/cic/solidity/abi')
default_eth_provider = os.environ.get('ETH_PROVIDER', 'http://localhost:8545')
argparser = argparse.ArgumentParser()
argparser.add_argument('-v', action='store_true', help='Be verbose')
argparser.add_argument('-i', '--chain-id', dest='i', type=str, help='Numeric network id')
argparser.add_argument('tx', type=str, help='hex-encoded signed raw transaction')
args = argparser.parse_args()
if args.v:
logg.setLevel(logging.DEBUG)
(chain_name, chain_id) = args.i.split(':')
def main():
tx_raw = args.tx
if tx_raw[:2] == '0x':
tx_raw = tx_raw[2:]
tx_raw_bytes = bytes.fromhex(tx_raw)
tx = unpack_signed(tx_raw_bytes, int(chain_id))
for k in tx.keys():
print('{}: {}'.format(k, tx[k]))
if __name__ == '__main__':
main()

83
cic_tools/eth/tx.py Normal file
View File

@ -0,0 +1,83 @@
# standard imports
import logging
# third-party imports
import sha3
from eth_keys import KeyAPI
from eth_keys.backends import NativeECCBackend
from rlp import decode as rlp_decode
from rlp import encode as rlp_encode
# local imports
from .address import to_checksum
logg = logging.getLogger(__name__)
field_debugs = [
'nonce',
'gasPrice',
'gas',
'to',
'value',
'data',
'v',
'r',
's',
]
def unpack_signed(tx_raw_bytes, chain_id=1):
d = rlp_decode(tx_raw_bytes)
logg.debug('decoding using chain id {}'.format(chain_id))
j = 0
for i in d:
logg.debug('decoded {}: {}'.format(field_debugs[j], i.hex()))
j += 1
vb = chain_id
if chain_id != 0:
v = int.from_bytes(d[6], 'big')
vb = v - (chain_id * 2) - 35
s = b''.join([d[7], d[8], bytes([vb])])
so = KeyAPI.Signature(signature_bytes=s)
h = sha3.keccak_256()
h.update(rlp_encode(d))
signed_hash = h.digest()
d[6] = chain_id
d[7] = b''
d[8] = b''
h = sha3.keccak_256()
h.update(rlp_encode(d))
unsigned_hash = h.digest()
p = so.recover_public_key_from_msg_hash(unsigned_hash)
a = p.to_checksum_address()
logg.debug('decoded recovery byte {}'.format(vb))
logg.debug('decoded address {}'.format(a))
logg.debug('decoded signed hash {}'.format(signed_hash.hex()))
logg.debug('decoded unsigned hash {}'.format(unsigned_hash.hex()))
to = d[3].hex() or None
if to != None:
to = to_checksum(to)
return {
'from': a,
'nonce': int.from_bytes(d[0], 'big'),
'gasPrice': int.from_bytes(d[1], 'big'),
'gas': int.from_bytes(d[2], 'big'),
'to': to,
'value': int.from_bytes(d[4], 'big'),
'data': '0x' + d[5].hex(),
'v': chain_id,
'r': '0x' + s[:32].hex(),
's': '0x' + s[32:64].hex(),
'chainId': chain_id,
'hash': '0x' + signed_hash.hex(),
'hash_unsigned': '0x' + unsigned_hash.hex(),
}

View File

@ -11,3 +11,4 @@ crypto-dev-signer==0.4.13rc2
pysha3==1.0.2
hexathon==0.0.1a2
eth-abi==2.1.1
eth-keys==0.3.3