contract-registry

Ethereum Smart Contract key-value registry
Log | Files | Refs

commit 8b673c313cc9b2ba4b9edeb854adca563c414c45
parent e313638c7bdfea851fc7a816dbdd91d8f40f1de6
Author: nolash <dev@holbrook.no>
Date:   Mon, 22 Mar 2021 18:37:00 +0100

Add deploy,set runnables

Diffstat:
Mpython/contract_registry/registry.py | 15++++++++++++---
Apython/contract_registry/runnable/deploy.py | 101+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Apython/contract_registry/runnable/set.py | 103+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mpython/gmon.out | 0
Mpython/setup.cfg | 2+-
5 files changed, 217 insertions(+), 4 deletions(-)

diff --git a/python/contract_registry/registry.py b/python/contract_registry/registry.py @@ -2,6 +2,7 @@ import os import logging import json +import hashlib # third-party imports from chainlib.eth.contract import ( @@ -61,6 +62,10 @@ class Registry(TxFactory): return Registry.__bytecode + @staticmethod + def gas(code=None): + return 1500000 + def constructor(self, sender_address, identifier_strings=[]): # TODO: handle arrays in chainlib encode instead enc = ABIContractEncoder() @@ -70,7 +75,7 @@ class Registry(TxFactory): enc.bytes32(to_identifier(s)) data = enc.get_contents() - tx = self.template(sender_address, b'', use_nonce=True) + tx = self.template(sender_address, None, use_nonce=True) tx = self.set_code(tx, Registry.bytecode() + data) logg.debug('bytecode {}\ndata {}\ntx {}'.format(Registry.bytecode(), data, tx)) return self.build(tx) @@ -109,7 +114,7 @@ class Registry(TxFactory): return abi_decode_single(ABIContractType.ADDRESS, v) - def set(self, contract_address, sender_address, identifier_string, address, chain_descriptor_hash, chain_config_hash): + def set(self, contract_address, sender_address, identifier_string, address, chain_spec, chain_config_hash): enc = ABIContractEncoder() enc.method('set') enc.typ(ABIContractType.BYTES32) @@ -119,7 +124,11 @@ class Registry(TxFactory): identifier = to_identifier(identifier_string) enc.bytes32(identifier) enc.address(address) - enc.bytes32(chain_descriptor_hash) + chain_str = str(chain_spec) + h = hashlib.new('sha256') + h.update(chain_str.encode('utf-8')) + chain_description_hash_bytes = h.digest() + enc.bytes32(chain_description_hash_bytes.hex()) enc.bytes32(chain_config_hash) data = enc.encode() tx = self.template(sender_address, contract_address, use_nonce=True) diff --git a/python/contract_registry/runnable/deploy.py b/python/contract_registry/runnable/deploy.py @@ -0,0 +1,101 @@ +"""Deploys contract registry + +.. moduleauthor:: Louis Holbrook <dev@holbrook.no> +.. pgp:: 0826EDA1702D1E87C6E2875121D2E7BB88C2A746 + +""" + +# standard imports +import sys +import os +import json +import argparse +import logging + +# third-party imports +from crypto_dev_signer.eth.signer import ReferenceSigner as EIP155Signer +from crypto_dev_signer.keystore.dict import DictKeystore +from crypto_dev_signer.eth.helper import EthTxExecutor +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.tx import receipt + +# local imports +from contract_registry import Registry + +logging.basicConfig(level=logging.WARNING) +logg = logging.getLogger() + +script_dir = os.path.dirname(__file__) +data_dir = os.path.join(script_dir, '..', 'data') + +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='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('--identifier', type=str, action='append', help='Add contract identifier') +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() + +if args.vv: + logg.setLevel(logging.DEBUG) +elif args.v: + logg.setLevel(logging.INFO) + +block_last = args.w +block_all = args.ww + +passphrase_env = 'ETH_PASSPHRASE' +if args.env_prefix != None: + 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 +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) +chain_id = chain_spec.network_id() + +rpc = EthHTTPConnection(args.p) +nonce_oracle = RPCNonceOracle(signer_address, rpc) +gas_oracle = RPCGasOracle(rpc, code_callback=Registry.gas) +identifiers = args.identifier +if 'ContractRegistry' not in identifiers: + identifiers = ['ContractRegistry'] + identifiers +logg.debug('adding identifiers {}'.format(identifiers)) + +def main(): + c = Registry(signer=signer, gas_oracle=gas_oracle, nonce_oracle=nonce_oracle, chain_id=chain_id) + (tx_hash_hex, o) = c.constructor(signer_address, identifiers) + rpc.do(o) + if block_last: + r = rpc.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) + # TODO: pass through translator for keys (evm tester uses underscore instead of camelcase) + address = r['contractAddress'] + + print(address) + else: + print(tx_hash_hex) + + sys.exit(0) + + +if __name__ == '__main__': + main() diff --git a/python/contract_registry/runnable/set.py b/python/contract_registry/runnable/set.py @@ -0,0 +1,103 @@ +"""Set identifier value on contract registry + +.. moduleauthor:: Louis Holbrook <dev@holbrook.no> +.. pgp:: 0826EDA1702D1E87C6E2875121D2E7BB88C2A746 + +""" + +# standard imports +import sys +import os +import json +import argparse +import logging + +# third-party imports +from crypto_dev_signer.eth.signer import ReferenceSigner as EIP155Signer +from crypto_dev_signer.keystore.dict import DictKeystore +from crypto_dev_signer.eth.helper import EthTxExecutor +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.tx import receipt +from chainlib.eth.constant import ZERO_CONTENT + +# local imports +from contract_registry import Registry + +logging.basicConfig(level=logging.WARNING) +logg = logging.getLogger() + +script_dir = os.path.dirname(__file__) +data_dir = os.path.join(script_dir, '..', 'data') + +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='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', type=str, help='Alias for -r') +argparser.add_argument('-r', '--registry', dest='r', type=str, help='Contract registry 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('--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('identifier', type=str, help='Contract registry identifier') +argparser.add_argument('address', type=str, help='Address to set for identifier') +args = argparser.parse_args() + +if args.vv: + logg.setLevel(logging.DEBUG) +elif args.v: + logg.setLevel(logging.INFO) + +block_last = args.w +block_all = args.ww + +passphrase_env = 'ETH_PASSPHRASE' +if args.env_prefix != None: + 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 +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) +chain_id = chain_spec.network_id() + +rpc = EthHTTPConnection(args.p) +nonce_oracle = RPCNonceOracle(signer_address, rpc) +gas_oracle = RPCGasOracle(rpc, code_callback=Registry.gas) +registry_address = args.r +if registry_address == None: + registry_address = args.a +if registry_address == None: + raise ValueError('Registry address must be set') +identifier = args.identifier +address = args.address + + +def main(): + c = Registry(signer=signer, gas_oracle=gas_oracle, nonce_oracle=nonce_oracle, chain_id=chain_id) + (tx_hash_hex, o) = c.set(registry_address, signer_address, identifier, address, chain_spec, ZERO_CONTENT) + rpc.do(o) + if block_last: + r = rpc.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) + + +if __name__ == '__main__': + main() diff --git a/python/gmon.out b/python/gmon.out Binary files differ. diff --git a/python/setup.cfg b/python/setup.cfg @@ -1,6 +1,6 @@ [metadata] name = eth-contract-registry -version = 0.5.3a25 +version = 0.5.4a1 description = Contract registry author = Louis Holbrook author_email = dev@holbrook.no