Initial commit; receive all eth code from chainlib package
This commit is contained in:
25
example/call_balance.py
Normal file
25
example/call_balance.py
Normal file
@@ -0,0 +1,25 @@
|
||||
# standard imports
|
||||
import os
|
||||
|
||||
# external imports
|
||||
from hexathon import strip_0x, add_0x
|
||||
|
||||
# local imports
|
||||
from chainlib.eth.gas import balance, parse_balance
|
||||
from chainlib.eth.connection import EthHTTPConnection
|
||||
|
||||
|
||||
# create a random address to check
|
||||
address_bytes = os.urandom(20)
|
||||
address = add_0x(address_bytes.hex())
|
||||
|
||||
# connect to rpc node and send request for balance
|
||||
rpc_provider = os.environ.get('RPC_PROVIDER', 'http://localhost:8545')
|
||||
rpc = EthHTTPConnection(rpc_provider)
|
||||
o = balance(address)
|
||||
r = rpc.do(o)
|
||||
|
||||
clean_address = strip_0x(address)
|
||||
clean_balance = parse_balance(r)
|
||||
|
||||
print('address {} has balance {}'.format(clean_address, clean_balance))
|
||||
75
example/contract_transaction.py
Normal file
75
example/contract_transaction.py
Normal file
@@ -0,0 +1,75 @@
|
||||
# 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]))
|
||||
29
example/jsonrpc.py
Normal file
29
example/jsonrpc.py
Normal file
@@ -0,0 +1,29 @@
|
||||
# standard imports
|
||||
import os
|
||||
import sys
|
||||
|
||||
# local imports
|
||||
from chainlib.jsonrpc import jsonrpc_template
|
||||
from chainlib.eth.connection import EthHTTPConnection
|
||||
|
||||
# set up node connection and execute rpc call
|
||||
rpc_provider = os.environ.get('RPC_PROVIDER', 'http://localhost:8545')
|
||||
rpc = EthHTTPConnection(rpc_provider)
|
||||
|
||||
# check the connection
|
||||
if not rpc.check():
|
||||
sys.stderr.write('node {} not usable\n'.format(rpc_provider))
|
||||
sys.exit(1)
|
||||
|
||||
# build and send rpc call
|
||||
o = jsonrpc_template()
|
||||
o['method'] = 'eth_blockNumber'
|
||||
r = rpc.do(o)
|
||||
|
||||
# interpret result for humans
|
||||
try:
|
||||
block_number = int(r, 10)
|
||||
except ValueError:
|
||||
block_number = int(r, 16)
|
||||
|
||||
print('block number {}'.format(block_number))
|
||||
57
example/online_transaction.py
Normal file
57
example/online_transaction.py
Normal file
@@ -0,0 +1,57 @@
|
||||
# standard imports
|
||||
import sys
|
||||
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.connection import EthHTTPConnection
|
||||
from chainlib.eth.nonce import RPCNonceOracle
|
||||
from chainlib.eth.gas import RPCGasOracle
|
||||
from chainlib.eth.tx import (
|
||||
TxFactory,
|
||||
TxFormat,
|
||||
)
|
||||
from chainlib.error import JSONRPCException
|
||||
|
||||
# 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()
|
||||
|
||||
# set up node connection
|
||||
rpc_provider = os.environ.get('RPC_PROVIDER', 'http://localhost:8545')
|
||||
rpc = EthHTTPConnection(rpc_provider)
|
||||
|
||||
# check the connection
|
||||
if not rpc.check():
|
||||
sys.stderr.write('node {} not usable\n'.format(rpc_provider))
|
||||
sys.exit(1)
|
||||
|
||||
# nonce will now be retrieved from network
|
||||
nonce_oracle = RPCNonceOracle(sender_address, rpc)
|
||||
|
||||
# gas price retrieved from network, and limit from callback
|
||||
def calculate_gas(code=None):
|
||||
return 21000
|
||||
gas_oracle = RPCGasOracle(rpc, code_callback=calculate_gas)
|
||||
|
||||
# create a new transaction
|
||||
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['value'] = 1024
|
||||
(tx_hash, tx_rpc) = tx_factory.finalize(tx)
|
||||
|
||||
print('transaction hash: ' + tx_hash)
|
||||
print('jsonrpc payload: ' + str(tx_rpc))
|
||||
65
example/transaction.py
Normal file
65
example/transaction.py
Normal file
@@ -0,0 +1,65 @@
|
||||
# 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,
|
||||
)
|
||||
|
||||
# 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)
|
||||
|
||||
# create a new transaction
|
||||
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['value'] = 1024
|
||||
(tx_hash, tx_rpc) = tx_factory.finalize(tx)
|
||||
|
||||
print('transaction hash: ' + tx_hash)
|
||||
print('jsonrpc payload: ' + str(tx_rpc))
|
||||
|
||||
# create a new transaction, but output in raw rlp format
|
||||
tx = tx_factory.template(sender_address, recipient_address, use_nonce=True) # will now have increased nonce by 1
|
||||
tx['value'] = 1024
|
||||
(tx_hash, tx_signed_raw) = tx_factory.finalize(tx, tx_format=TxFormat.RLP_SIGNED)
|
||||
print('transaction hash: ' + tx_hash)
|
||||
print('raw rlp payload: ' + tx_signed_raw)
|
||||
|
||||
# convert tx from raw RLP
|
||||
tx_signed_raw_bytes = bytes.fromhex(strip_0x(tx_signed_raw))
|
||||
tx_src = unpack(tx_signed_raw_bytes, chain_spec)
|
||||
print('tx parsed from rlp payload: ' + str(tx_src))
|
||||
|
||||
# .. and back
|
||||
tx_signed_raw_bytes_recovered = pack(tx_src, chain_spec)
|
||||
tx_signed_raw_recovered = add_0x(tx_signed_raw_bytes_recovered.hex())
|
||||
print('raw rlp payload re-parsed: ' + tx_signed_raw_recovered)
|
||||
|
||||
# create a raw send jsonrpc payload from the raw RLP
|
||||
o = raw(tx_signed_raw_recovered)
|
||||
print('jsonrpc payload: ' + str(o))
|
||||
51
example/tx_object.py
Normal file
51
example/tx_object.py
Normal file
@@ -0,0 +1,51 @@
|
||||
# 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 crypto_dev_signer.eth.transaction import EIP155Transaction
|
||||
from hexathon import (
|
||||
add_0x,
|
||||
strip_0x,
|
||||
)
|
||||
|
||||
# local imports
|
||||
from chainlib.chain import ChainSpec
|
||||
from chainlib.eth.tx import (
|
||||
unpack,
|
||||
Tx,
|
||||
)
|
||||
|
||||
# eth transactions need an explicit chain parameter as part of their signature
|
||||
chain_spec = ChainSpec.from_chain_str('evm:ethereum:1')
|
||||
chain_id = chain_spec.chain_id()
|
||||
|
||||
# create keystore and signer
|
||||
keystore = DictKeystore()
|
||||
signer = EIP155Signer(keystore)
|
||||
sender_address = keystore.new()
|
||||
recipient_address = keystore.new()
|
||||
|
||||
|
||||
# set up a transaction dict source
|
||||
tx_src = {
|
||||
'from': sender_address,
|
||||
'to': recipient_address,
|
||||
'gas': 21000,
|
||||
'gasPrice': 1000000000,
|
||||
'value': 1024,
|
||||
'data': '0xdeadbeef',
|
||||
}
|
||||
sender_nonce = 0
|
||||
tx = EIP155Transaction(tx_src, sender_nonce, chain_id)
|
||||
signature = signer.sign_transaction(tx)
|
||||
print('signature: {}'.format(signature.hex()))
|
||||
|
||||
tx.apply_signature(chain_id, signature)
|
||||
print('tx with signature: {}'.format(tx.serialize()))
|
||||
|
||||
tx_signed_raw_bytes = tx.rlp_serialize()
|
||||
tx_src = unpack(tx_signed_raw_bytes, chain_spec)
|
||||
tx_parsed = Tx(tx_src)
|
||||
print('parsed signed tx: {}'.format(tx_parsed.to_human()))
|
||||
Reference in New Issue
Block a user