Implement chainlib cli util

This commit is contained in:
nolash 2021-07-30 07:27:36 +02:00
parent 308fcd727f
commit 4060101b29
Signed by: lash
GPG Key ID: 21D2E7BB88C2A746
6 changed files with 142 additions and 283 deletions

View File

@ -12,20 +12,12 @@ import argparse
import logging import logging
import sys import sys
# third-party imports # external imports
from crypto_dev_signer.eth.signer import ReferenceSigner as EIP155Signer import chainlib.eth.cli
from crypto_dev_signer.keystore.dict import DictKeystore
from chainlib.chain import ChainSpec from chainlib.chain import ChainSpec
from chainlib.eth.nonce import (
RPCNonceOracle,
OverrideNonceOracle,
)
from chainlib.eth.gas import (
RPCGasOracle,
OverrideGasOracle,
)
from chainlib.eth.connection import EthHTTPConnection from chainlib.eth.connection import EthHTTPConnection
from chainlib.eth.tx import receipt from chainlib.eth.tx import receipt
from chainlib.eth.address import to_checksum_address
# local imports # local imports
from eth_accounts_index.registry import AccountRegistry from eth_accounts_index.registry import AccountRegistry
@ -33,87 +25,56 @@ from eth_accounts_index.registry import AccountRegistry
logging.basicConfig(level=logging.WARNING) logging.basicConfig(level=logging.WARNING)
logg = logging.getLogger() logg = logging.getLogger()
script_dir = os.path.dirname(__file__) arg_flags = chainlib.eth.cli.argflag_std_write | chainlib.eth.cli.Flag.EXEC
data_dir = os.path.join(script_dir, '..', 'data') argparser = chainlib.eth.cli.ArgumentParser(arg_flags)
argparser.add_positional('address', type=str, help='Address to add to registry')
argparser = argparse.ArgumentParser()
argparser.add_argument('-p', '--provider', dest='p', default='http://localhost:8545', type=str, help='Web3 provider url (http only)')
argparser.add_argument('-w', action='store_true', help='Wait for the last transaction to be confirmed')
argparser.add_argument('-ww', action='store_true', help='Wait for every transaction to be confirmed')
argparser.add_argument('-i', '--chain-spec', dest='i', type=str, default='evm:ethereum:1', help='Chain specification string')
argparser.add_argument('-y', '--key-file', dest='y', type=str, help='Ethereum keystore file to use for signing')
argparser.add_argument('-a', '--contract-address', dest='a', required=True, type=str, help='Contract address to account index to edit')
argparser.add_argument('-v', action='store_true', help='Be verbose')
argparser.add_argument('-vv', action='store_true', help='Be more verbose')
argparser.add_argument('-d', action='store_true', help='Dump RPC calls to terminal and do not send')
argparser.add_argument('--gas-price', type=int, dest='gas_price', help='Override gas price')
argparser.add_argument('--nonce', type=int, help='Override transaction nonce')
argparser.add_argument('--env-prefix', default=os.environ.get('CONFINI_ENV_PREFIX'), dest='env_prefix', type=str, help='environment prefix for variables to overwrite configuration')
argparser.add_argument('address', type=str, help='Address to add')
args = argparser.parse_args() args = argparser.parse_args()
if args.vv: extra_args = {
logg.setLevel(logging.DEBUG) 'address': None,
elif args.v: }
logg.setLevel(logging.INFO) config = chainlib.eth.cli.Config.from_args(args, arg_flags, extra_args=extra_args, default_fee_limit=AccountRegistry.gas())
block_last = args.w wallet = chainlib.eth.cli.Wallet()
block_all = args.ww wallet.from_config(config)
passphrase_env = 'ETH_PASSPHRASE' rpc = chainlib.eth.cli.Rpc(wallet=wallet)
if args.env_prefix != None: conn = rpc.connect_by_config(config)
passphrase_env = args.env_prefix + '_' + passphrase_env
passphrase = os.environ.get(passphrase_env)
if passphrase == None:
logg.warning('no passphrase given')
passphrase=''
signer_address = None chain_spec = ChainSpec.from_chain_str(config.get('CHAIN_SPEC'))
keystore = DictKeystore()
if args.y != None:
logg.debug('loading keystore file {}'.format(args.y))
signer_address = keystore.import_keystore_file(args.y, password=passphrase)
logg.debug('now have key for signer address {}'.format(signer_address))
signer = EIP155Signer(keystore)
chain_spec = ChainSpec.from_chain_str(args.i)
rpc = EthHTTPConnection(args.p)
nonce_oracle = None
if args.nonce != None:
nonce_oracle = OverrideNonceOracle(signer_address, args.nonce)
else:
nonce_oracle = RPCNonceOracle(signer_address, rpc)
gas_oracle = None
if args.gas_price !=None:
gas_oracle = OverrideGasOracle(price=args.gas_price, conn=rpc, code_callback=AccountRegistry.gas)
else:
gas_oracle = RPCGasOracle(rpc, code_callback=AccountRegistry.gas)
dummy = args.d
contract_address = args.a
account = args.address
def main(): def main():
signer = rpc.get_signer()
signer_address = rpc.get_sender_address()
if __name__ == '__main__': gas_oracle = rpc.get_gas_oracle()
c = AccountRegistry(chain_spec, signer=signer, gas_oracle=gas_oracle, nonce_oracle=nonce_oracle) nonce_oracle = rpc.get_nonce_oracle()
(tx_hash_hex, o) = c.add(contract_address, signer_address, account)
if dummy:
print(tx_hash_hex)
print(o)
else:
rpc.do(o)
r = rpc.wait(tx_hash_hex)
if block_last:
if r['status'] == 0:
sys.stderr.write('EVM revert while deploying contract. Wish I had more to tell you')
sys.exit(1)
print(tx_hash_hex) subject_address = to_checksum_address(config.get('_ADDRESS'))
if not config.true('_UNSAFE') and subject_address != add_0x(config.get('_ADDRESS')):
raise ValueError('invalid checksum address for subject_address')
contract_address = to_checksum_address(config.get('_EXEC_ADDRESS'))
if not config.true('_UNSAFE') and contract_address != add_0x(config.get('_EXEC_ADDRESS')):
raise ValueError('invalid checksum address for contract')
c = AccountRegistry(chain_spec, signer=signer, gas_oracle=gas_oracle, nonce_oracle=nonce_oracle)
(tx_hash_hex, o) = c.add(contract_address, signer_address, subject_address)
if config.get('_RPC_SEND'):
conn.do(o)
if config.get('_WAIT'):
r = conn.wait(tx_hash_hex)
if r['status'] == 0:
sys.stderr.write('EVM revert while deploying contract. Wish I had more to tell you')
sys.exit(1)
print(tx_hash_hex)
else:
print(o)
if __name__ == '__main__': if __name__ == '__main__':

View File

@ -12,18 +12,9 @@ import json
import argparse import argparse
import logging import logging
# third-party imports # external imports
from crypto_dev_signer.eth.signer import ReferenceSigner as EIP155Signer import chainlib.eth.cli
from crypto_dev_signer.keystore.dict import DictKeystore
from chainlib.chain import ChainSpec from chainlib.chain import ChainSpec
from chainlib.eth.nonce import (
RPCNonceOracle,
OverrideNonceOracle,
)
from chainlib.eth.gas import (
RPCGasOracle,
OverrideGasOracle,
)
from chainlib.eth.connection import EthHTTPConnection from chainlib.eth.connection import EthHTTPConnection
from chainlib.eth.tx import receipt from chainlib.eth.tx import receipt
@ -33,75 +24,36 @@ from eth_accounts_index.registry import AccountRegistry
logging.basicConfig(level=logging.WARNING) logging.basicConfig(level=logging.WARNING)
logg = logging.getLogger() logg = logging.getLogger()
script_dir = os.path.dirname(__file__) arg_flags = chainlib.eth.cli.argflag_std_write
data_dir = os.path.join(script_dir, '..', 'data') argparser = chainlib.eth.cli.ArgumentParser(arg_flags)
argparser = argparse.ArgumentParser()
argparser.add_argument('-p', '--provider', dest='p', default='http://localhost:8545', type=str, help='Web3 provider url (http only)')
argparser.add_argument('-w', action='store_true', help='Wait for the last transaction to be confirmed')
argparser.add_argument('-ww', action='store_true', help='Wait for every transaction to be confirmed')
argparser.add_argument('-i', '--chain-spec', dest='i', type=str, default='evm:ethereum:1', help='Chain specification string')
argparser.add_argument('-y', '--key-file', dest='y', type=str, help='Ethereum keystore file to use for signing')
argparser.add_argument('-v', action='store_true', help='Be verbose')
argparser.add_argument('-vv', action='store_true', help='Be more verbose')
argparser.add_argument('-d', action='store_true', help='Dump RPC calls to terminal and do not send')
argparser.add_argument('--gas-price', type=int, dest='gas_price', help='Override gas price')
argparser.add_argument('--nonce', type=int, help='Override transaction nonce')
argparser.add_argument('--env-prefix', default=os.environ.get('CONFINI_ENV_PREFIX'), dest='env_prefix', type=str, help='environment prefix for variables to overwrite configuration')
args = argparser.parse_args() args = argparser.parse_args()
if args.vv: config = chainlib.eth.cli.Config.from_args(args, arg_flags, default_fee_limit=AccountRegistry.gas())
logg.setLevel(logging.DEBUG)
elif args.v:
logg.setLevel(logging.INFO)
block_all = args.ww wallet = chainlib.eth.cli.Wallet()
block_last = args.w or block_all wallet.from_config(config)
passphrase_env = 'ETH_PASSPHRASE' rpc = chainlib.eth.cli.Rpc(wallet=wallet)
if args.env_prefix != None: conn = rpc.connect_by_config(config)
passphrase_env = args.env_prefix + '_' + passphrase_env
passphrase = os.environ.get(passphrase_env)
if passphrase == None:
logg.warning('no passphrase given')
passphrase=''
signer_address = None chain_spec = ChainSpec.from_chain_str(config.get('CHAIN_SPEC'))
keystore = DictKeystore()
if args.y != None:
logg.debug('loading keystore file {}'.format(args.y))
signer_address = keystore.import_keystore_file(args.y, password=passphrase)
logg.debug('now have key for signer address {}'.format(signer_address))
signer = EIP155Signer(keystore)
chain_spec = ChainSpec.from_chain_str(args.i)
rpc = EthHTTPConnection(args.p)
nonce_oracle = None
if args.nonce != None:
nonce_oracle = OverrideNonceOracle(signer_address, args.nonce)
else:
nonce_oracle = RPCNonceOracle(signer_address, rpc)
gas_oracle = None
if args.gas_price !=None:
gas_oracle = OverrideGasOracle(price=args.gas_price, conn=rpc, code_callback=AccountRegistry.gas)
else:
gas_oracle = RPCGasOracle(rpc, code_callback=AccountRegistry.gas)
dummy = args.d
def main(): def main():
signer = rpc.get_signer()
signer_address = rpc.get_sender_address()
gas_oracle = rpc.get_gas_oracle()
nonce_oracle = rpc.get_nonce_oracle()
c = AccountRegistry(chain_spec, signer=signer, gas_oracle=gas_oracle, nonce_oracle=nonce_oracle) c = AccountRegistry(chain_spec, signer=signer, gas_oracle=gas_oracle, nonce_oracle=nonce_oracle)
(tx_hash_hex, o) = c.constructor(signer_address) (tx_hash_hex, o) = c.constructor(signer_address)
if dummy:
print(tx_hash_hex) if config.get('_RPC_SEND'):
print(o) conn.do(o)
else: if config.get('_WAIT'):
rpc.do(o) r = conn.wait(tx_hash_hex)
if block_last:
r = rpc.wait(tx_hash_hex)
if r['status'] == 0: if r['status'] == 0:
sys.stderr.write('EVM revert while deploying contract. Wish I had more to tell you') sys.stderr.write('EVM revert while deploying contract. Wish I had more to tell you')
sys.exit(1) sys.exit(1)
@ -111,6 +63,8 @@ def main():
print(address) print(address)
else: else:
print(tx_hash_hex) print(tx_hash_hex)
else:
print(o)
if __name__ == '__main__': if __name__ == '__main__':

View File

@ -12,12 +12,9 @@ import json
import argparse import argparse
import logging import logging
# third-party imports # external imports
from crypto_dev_signer.eth.signer import ReferenceSigner as EIP155Signer import chainlib.eth.cli
from crypto_dev_signer.keystore.dict import DictKeystore
from chainlib.chain import ChainSpec from chainlib.chain import ChainSpec
from chainlib.eth.nonce import RPCNonceOracle
from chainlib.eth.gas import RPCGasOracle
from chainlib.eth.connection import EthHTTPConnection from chainlib.eth.connection import EthHTTPConnection
from chainlib.eth.tx import receipt from chainlib.eth.tx import receipt
from chainlib.eth.constant import ZERO_CONTENT from chainlib.eth.constant import ZERO_CONTENT
@ -25,73 +22,62 @@ from chainlib.error import JSONRPCException
# local imports # local imports
from eth_accounts_index import AccountsIndex from eth_accounts_index import AccountsIndex
from eth_accounts_index.registry import AccountRegistry
logging.basicConfig(level=logging.WARNING) logging.basicConfig(level=logging.WARNING)
logg = logging.getLogger() logg = logging.getLogger()
script_dir = os.path.dirname(__file__) arg_flags = chainlib.eth.cli.argflag_std_write | chainlib.eth.cli.Flag.EXEC
data_dir = os.path.join(script_dir, '..', 'data') argparser = chainlib.eth.cli.ArgumentParser(arg_flags)
argparser.add_positional('address', required=False, type=str, help='Check only whether given address is in registry')
default_format = 'terminal'
argparser = argparse.ArgumentParser()
argparser.add_argument('-p', '--provider', dest='p', default='http://localhost:8545', type=str, help='RPC provider url (http only)')
argparser.add_argument('-i', '--chain-spec', dest='i', type=str, default='evm:ethereum:1', help='Chain specification string')
argparser.add_argument('-a', '--contract-address', dest='a', required=True, type=str, help='Contract address')
argparser.add_argument('-f', '--format', dest='f', type=str, default=default_format, help='Output format [human, brief]')
argparser.add_argument('-v', action='store_true', help='Be verbose')
argparser.add_argument('-vv', action='store_true', help='Be more verbose')
argparser.add_argument('--env-prefix', default=os.environ.get('CONFINI_ENV_PREFIX'), dest='env_prefix', type=str, help='environment prefix for variables to overwrite configuration')
argparser.add_argument('address', type=str, nargs='?', help='Address to check registration for')
args = argparser.parse_args() args = argparser.parse_args()
if args.vv: extra_args = {
logg.setLevel(logging.DEBUG) 'address': None,
elif args.v: }
logg.setLevel(logging.INFO) config = chainlib.eth.cli.Config.from_args(args, arg_flags, extra_args=extra_args, default_fee_limit=AccountRegistry.gas())
chain_spec = ChainSpec.from_chain_str(args.i) wallet = chainlib.eth.cli.Wallet()
wallet.from_config(config)
rpc = EthHTTPConnection(args.p) rpc = chainlib.eth.cli.Rpc(wallet=wallet)
account_registry_address = args.a conn = rpc.connect_by_config(config)
address = args.address
fmt = args.f chain_spec = ChainSpec.from_chain_str(config.get('CHAIN_SPEC'))
def out_element(e, fmt=default_format, w=sys.stdout): def out_element(e, w=sys.stdout):
logg.debug('format {}'.format(fmt)) w.write(str(e[1]) + '\n')
if fmt == 'brief':
w.write(str(e[1]) + '\n')
else:
w.write('{} {}\n'.format(e[0], e[1]))
def element(ifc, address, fmt=default_format, w=sys.stdout): def element(ifc, conn, contract_address, address, w=sys.stdout):
o = ifc.have(account_registry_address, address) o = ifc.have(contract_address, address)
r = rpc.do(o) r = conn.do(o)
have = ifc.parse_have(r) have = ifc.parse_have(r)
out_element((address, have), fmt, w) out_element((0, address), w)
def ls(ifc, fmt=default_format, w=sys.stdout): def ls(ifc, conn, contract_address, w=sys.stdout):
i = 0 i = 0
while True: while True:
o = ifc.entry(account_registry_address, i) o = ifc.entry(contract_address, i)
try: try:
r = rpc.do(o) r = conn.do(o)
account = ifc.parse_account(r) account = ifc.parse_account(r)
out_element((i, account), fmt, w) out_element((i, account), w)
i += 1 i += 1
except JSONRPCException as e: except JSONRPCException as e:
break break
def main(): def main():
address = config.get('_ADDRESS')
contract_address = config.get('_EXEC_ADDRESS')
c = AccountsIndex(chain_spec) c = AccountsIndex(chain_spec)
if address != None: if address != None:
element(c, address, fmt=fmt, w=sys.stdout) element(c, conn, contract_address, address, w=sys.stdout)
else: else:
ls(c, fmt=fmt, w=sys.stdout) ls(c, conn, contract_address, w=sys.stdout)
if __name__ == '__main__': if __name__ == '__main__':

View File

@ -12,20 +12,12 @@ import argparse
import logging import logging
import sys import sys
# third-party imports # external imports
from crypto_dev_signer.eth.signer import ReferenceSigner as EIP155Signer import chainlib.eth.cli
from crypto_dev_signer.keystore.dict import DictKeystore
from chainlib.chain import ChainSpec from chainlib.chain import ChainSpec
from chainlib.eth.nonce import (
RPCNonceOracle,
OverrideNonceOracle,
)
from chainlib.eth.gas import (
RPCGasOracle,
OverrideGasOracle,
)
from chainlib.eth.connection import EthHTTPConnection from chainlib.eth.connection import EthHTTPConnection
from chainlib.eth.tx import receipt from chainlib.eth.tx import receipt
from chainlib.eth.address import to_checksum_address
# local imports # local imports
from eth_accounts_index.registry import AccountRegistry from eth_accounts_index.registry import AccountRegistry
@ -33,94 +25,60 @@ from eth_accounts_index.registry import AccountRegistry
logging.basicConfig(level=logging.WARNING) logging.basicConfig(level=logging.WARNING)
logg = logging.getLogger() logg = logging.getLogger()
script_dir = os.path.dirname(__file__) arg_flags = chainlib.eth.cli.argflag_std_write | chainlib.eth.cli.Flag.EXEC
data_dir = os.path.join(script_dir, '..', 'data') argparser = chainlib.eth.cli.ArgumentParser(arg_flags)
argparser.add_argument('--rm', action='store_true', help='Delete entry')
argparser = argparse.ArgumentParser() argparser.add_positional('address', type=str, help='Update writer array with this address')
argparser.add_argument('-p', '--provider', dest='p', default='http://localhost:8545', type=str, help='Web3 provider url (http only)')
argparser.add_argument('-w', action='store_true', help='Wait for the last transaction to be confirmed')
argparser.add_argument('-ww', action='store_true', help='Wait for every transaction to be confirmed')
argparser.add_argument('-i', '--chain-spec', dest='i', type=str, default='evm:ethereum:1', help='Chain specification string')
argparser.add_argument('-y', '--key-file', dest='y', type=str, help='Ethereum keystore file to use for signing')
argparser.add_argument('-a', '--contract-address', dest='a', required=True, type=str, help='Contract address to account index to edit')
argparser.add_argument('--delete', action='store_true', help='Delete address')
argparser.add_argument('-v', action='store_true', help='Be verbose')
argparser.add_argument('-vv', action='store_true', help='Be more verbose')
argparser.add_argument('-d', action='store_true', help='Dump RPC calls to terminal and do not send')
argparser.add_argument('--gas-price', type=int, dest='gas_price', help='Override gas price')
argparser.add_argument('--nonce', type=int, help='Override transaction nonce')
argparser.add_argument('--env-prefix', default=os.environ.get('CONFINI_ENV_PREFIX'), dest='env_prefix', type=str, help='environment prefix for variables to overwrite configuration')
argparser.add_argument('address', type=str, help='Subject address')
args = argparser.parse_args() args = argparser.parse_args()
if args.vv: extra_args = {
logg.setLevel(logging.DEBUG) 'rm': None,
elif args.v: 'address': None,
logg.setLevel(logging.INFO) }
config = chainlib.eth.cli.Config.from_args(args, arg_flags, extra_args=extra_args, default_fee_limit=AccountRegistry.gas())
block_last = args.w wallet = chainlib.eth.cli.Wallet()
block_all = args.ww wallet.from_config(config)
passphrase_env = 'ETH_PASSPHRASE' rpc = chainlib.eth.cli.Rpc(wallet=wallet)
if args.env_prefix != None: conn = rpc.connect_by_config(config)
passphrase_env = args.env_prefix + '_' + passphrase_env
passphrase = os.environ.get(passphrase_env)
if passphrase == None:
logg.warning('no passphrase given')
passphrase=''
signer_address = None chain_spec = ChainSpec.from_chain_str(config.get('CHAIN_SPEC'))
keystore = DictKeystore()
if args.y != None:
logg.debug('loading keystore file {}'.format(args.y))
signer_address = keystore.import_keystore_file(args.y, password=passphrase)
logg.debug('now have key for signer address {}'.format(signer_address))
signer = EIP155Signer(keystore)
chain_spec = ChainSpec.from_chain_str(args.i)
rpc = EthHTTPConnection(args.p)
nonce_oracle = None
if args.nonce != None:
nonce_oracle = OverrideNonceOracle(signer_address, args.nonce)
else:
nonce_oracle = RPCNonceOracle(signer_address, rpc)
gas_oracle = None
if args.gas_price !=None:
gas_oracle = OverrideGasOracle(price=args.gas_price, conn=rpc, code_callback=AccountRegistry.gas)
else:
gas_oracle = RPCGasOracle(rpc, code_callback=AccountRegistry.gas)
dummy = args.d
contract_address = args.a
address = args.address
delete = False
if args.delete:
delete = True
def main(): def main():
signer = rpc.get_signer()
signer_address = rpc.get_sender_address()
gas_oracle = rpc.get_gas_oracle()
nonce_oracle = rpc.get_nonce_oracle()
c = AccountRegistry(chain_spec, signer=signer, gas_oracle=gas_oracle, nonce_oracle=nonce_oracle) c = AccountRegistry(chain_spec, signer=signer, gas_oracle=gas_oracle, nonce_oracle=nonce_oracle)
tx_hash_hex = None
o = None subject_address = to_checksum_address(config.get('_ADDRESS'))
if delete: if not config.true('_UNSAFE') and subject_address != add_0x(config.get('_ADDRESS')):
(tx_hash_hex, o) = c.delete_writer(contract_address, signer_address, address) raise ValueError('invalid checksum address for subject_address')
contract_address = to_checksum_address(config.get('_EXEC_ADDRESS'))
if not config.true('_UNSAFE') and contract_address != add_0x(config.get('_EXEC_ADDRESS')):
raise ValueError('invalid checksum address for contract')
if config.get('_RM'):
(tx_hash_hex, o) = c.delete_writer(contract_address, signer_address, subject_address)
else: else:
(tx_hash_hex, o) = c.add_writer(contract_address, signer_address, address) (tx_hash_hex, o) = c.add_writer(contract_address, signer_address, subject_address)
if dummy: if config.get('_RPC_SEND'):
print(tx_hash_hex) conn.do(o)
print(o) if config.get('_WAIT'):
else: r = conn.wait(tx_hash_hex)
rpc.do(o)
r = rpc.wait(tx_hash_hex)
if block_last:
if r['status'] == 0: if r['status'] == 0:
sys.stderr.write('EVM revert while deploying contract. Wish I had more to tell you') sys.stderr.write('EVM revert while deploying contract. Wish I had more to tell you')
sys.exit(1) sys.exit(1)
print(tx_hash_hex) print(tx_hash_hex)
else:
print(o)
if __name__ == '__main__': if __name__ == '__main__':

View File

@ -1,3 +1,3 @@
confini>=0.3.6rc3,<0.5.0 confini>=0.3.6rc3,<0.5.0
chainlib-eth~=0.0.5a2 chainlib-eth>=0.0.7a4,<=0.1.0
crypto-dev-signer~=0.4.14b7 crypto-dev-signer>=0.4.14b7,<=0.4.14

View File

@ -1,6 +1,6 @@
[metadata] [metadata]
name = eth-accounts-index name = eth-accounts-index
version = 0.0.12a2 version = 0.1.1a1
description = Accounts index evm contract tooling with permissioned writes description = Accounts index evm contract tooling with permissioned writes
author = Louis Holbrook author = Louis Holbrook
author_email = dev@holbrook.no author_email = dev@holbrook.no