76 lines
2.4 KiB
Python
76 lines
2.4 KiB
Python
|
# standard imports
|
||
|
import os
|
||
|
|
||
|
# external imports
|
||
|
from crypto_dev_signer.keystore.dict import DictKeystore
|
||
|
from crypto_dev_signer.eth.signer import ReferenceSigner as EIP155Signer
|
||
|
from hexathon import (
|
||
|
add_0x,
|
||
|
strip_0x,
|
||
|
)
|
||
|
|
||
|
# local imports
|
||
|
from chainlib.chain import ChainSpec
|
||
|
from chainlib.eth.nonce import OverrideNonceOracle
|
||
|
from chainlib.eth.gas import OverrideGasOracle
|
||
|
from chainlib.eth.tx import (
|
||
|
TxFactory,
|
||
|
TxFormat,
|
||
|
unpack,
|
||
|
pack,
|
||
|
raw,
|
||
|
)
|
||
|
from chainlib.eth.contract import (
|
||
|
ABIContractEncoder,
|
||
|
ABIContractDecoder,
|
||
|
ABIContractType,
|
||
|
)
|
||
|
|
||
|
# eth transactions need an explicit chain parameter as part of their signature
|
||
|
chain_spec = ChainSpec.from_chain_str('evm:ethereum:1')
|
||
|
|
||
|
# create keystore and signer
|
||
|
keystore = DictKeystore()
|
||
|
signer = EIP155Signer(keystore)
|
||
|
sender_address = keystore.new()
|
||
|
recipient_address = keystore.new()
|
||
|
|
||
|
# explicitly set nonce and gas parameters on this transaction
|
||
|
nonce_oracle = OverrideNonceOracle(sender_address, 0)
|
||
|
gas_oracle = OverrideGasOracle(price=1000000000, limit=21000)
|
||
|
|
||
|
# encode the contract parameters
|
||
|
enc = ABIContractEncoder()
|
||
|
enc.method('fooBar')
|
||
|
enc.typ(ABIContractType.ADDRESS)
|
||
|
enc.typ(ABIContractType.UINT256)
|
||
|
enc.address(recipient_address)
|
||
|
enc.uint256(42)
|
||
|
data = enc.get()
|
||
|
|
||
|
# create a new transaction, but output in raw rlp format
|
||
|
tx_factory = TxFactory(chain_spec, signer=signer, nonce_oracle=nonce_oracle, gas_oracle=gas_oracle)
|
||
|
tx = tx_factory.template(sender_address, recipient_address, use_nonce=True)
|
||
|
tx = tx_factory.set_code(tx, data)
|
||
|
(tx_hash, tx_signed_raw) = tx_factory.finalize(tx, tx_format=TxFormat.RLP_SIGNED)
|
||
|
|
||
|
print('contract transaction: {}'.format(tx))
|
||
|
|
||
|
# retrieve the input data from the transaction
|
||
|
tx_src = unpack(bytes.fromhex(strip_0x(tx_signed_raw)), chain_spec)
|
||
|
data_recovered = strip_0x(tx_src['data'])
|
||
|
|
||
|
# decode the contract parameters
|
||
|
dec = ABIContractDecoder()
|
||
|
dec.typ(ABIContractType.ADDRESS)
|
||
|
dec.typ(ABIContractType.UINT256)
|
||
|
# (yes, this interface needs to be vastly improved, it should take the whole buffer and advance with cursor itself)
|
||
|
cursor = 8 # the method signature is 8 characters long. input data to the solidity function starts after that
|
||
|
dec.val(data_recovered[cursor:cursor+64])
|
||
|
cursor += 64
|
||
|
dec.val(data_recovered[cursor:cursor+64])
|
||
|
r = dec.decode()
|
||
|
|
||
|
print('contract param 1 {}'.format(r[0]))
|
||
|
print('contract param 2 {}'.format(r[1]))
|