eth-erc20

ERC20 interface and example giftable token contract
Log | Files | Refs | LICENSE

commit e007d0754e9d04ab4514393da8f1668393ad24b1
parent 3d71df49b89c0b09d566bcfb0022b6ce15fe61fc
Author: nolash <dev@holbrook.no>
Date:   Thu, 29 Jul 2021 20:25:10 +0200

Implement remaining cli tools on chainlib cli util

Diffstat:
Mpython/MANIFEST.in | 2+-
Mpython/eth_erc20/erc20.py | 5+++++
Mpython/eth_erc20/runnable/balance.py | 58+++++++++++++++++++---------------------------------------
Mpython/eth_erc20/runnable/transfer.py | 143++++++++++++++++++++++++-------------------------------------------------------
Mpython/giftable_erc20_token/data/GiftableToken.bin | 4++--
Mpython/giftable_erc20_token/factory.py | 14+++++++++++++-
Mpython/giftable_erc20_token/runnable/deploy.py | 107++++++++++++++++++++++++-------------------------------------------------------
Mpython/giftable_erc20_token/runnable/gift.py | 129++++++++++++++++++++++++++++---------------------------------------------------
Mpython/giftable_erc20_token/runnable/minter.py | 116+++++++++++++++++++++++++++++++------------------------------------------------
Mpython/requirements.txt | 6+++---
Mpython/setup.cfg | 2+-
Msolidity/GiftableToken.bin | 4++--
12 files changed, 212 insertions(+), 378 deletions(-)

diff --git a/python/MANIFEST.in b/python/MANIFEST.in @@ -1 +1 @@ -include **/data/ERC20.json **/data/GiftableToken.json **/data/GiftableToken.bin requirements.txt test_requirements.txt +include **/data/ERC20.json **/data/GiftableToken.json **/data/GiftableToken.bin *requirements.txt diff --git a/python/eth_erc20/erc20.py b/python/eth_erc20/erc20.py @@ -199,6 +199,11 @@ class ERC20(TxFactory): @classmethod + def parse_balance_of(self, v): + return self.parse_balance(v) + + + @classmethod def parse_total_supply(self, v): return abi_decode_single(ABIContractType.UINT256, v) diff --git a/python/eth_erc20/runnable/balance.py b/python/eth_erc20/runnable/balance.py @@ -16,17 +16,17 @@ import json import argparse import logging -# third-party imports +# external imports from hexathon import ( add_0x, strip_0x, even, ) import sha3 -from eth_abi import encode_single # external imports -from chainlib.eth.address import to_checksum +import chainlib.eth.cli +from chainlib.eth.address import to_checksum_address from chainlib.eth.connection import EthHTTPConnection from chainlib.eth.gas import ( OverrideGasOracle, @@ -40,46 +40,29 @@ from eth_erc20 import ERC20 logging.basicConfig(level=logging.WARNING) logg = logging.getLogger() -default_eth_provider = os.environ.get('RPC_PROVIDER') -if default_eth_provider == None: - default_eth_provider = os.environ.get('ETH_PROVIDER', 'http://localhost:8545') - -argparser = argparse.ArgumentParser() -argparser.add_argument('-p', '--provider', dest='p', default=default_eth_provider, type=str, help='Web3 provider url (http only)') -argparser.add_argument('-a', '--token-address', dest='a', required=True, type=str, help='Token address. If not set, will return gas balance') -argparser.add_argument('-f', '--format', dest='f', type=str, default='terminal', help='Output format [terminal (default), raw, brief]') -argparser.add_argument('-i', '--chain-spec', dest='i', type=str, default='evm:ethereum:1', help='Chain specification string') -argparser.add_argument('-u', '--unsafe', dest='u', action='store_true', help='Auto-convert address to checksum adddress') -argparser.add_argument('--seq', action='store_true', help='Use sequential rpc ids') -argparser.add_argument('-v', action='store_true', help='Be verbose') -argparser.add_argument('-vv', action='store_true', help='Be more verbose') -argparser.add_argument('address', type=str, help='Account address') +arg_flags = chainlib.eth.cli.argflag_std_read | chainlib.eth.cli.Flag.EXEC +argparser = chainlib.eth.cli.ArgumentParser(arg_flags) +argparser.add_positional('address', type=str, help='Ethereum address of recipient') args = argparser.parse_args() +config = chainlib.eth.cli.Config.from_args(args, arg_flags) +wallet = chainlib.eth.cli.Wallet() +wallet.from_config(config) +holder_address = args.address +if wallet.get_signer_address() == None and holder_address != None: + holder_address = wallet.from_address(holder_address) -if args.vv: - logg.setLevel(logging.DEBUG) -elif args.v: - logg.setLevel(logging.INFO) - -conn = EthHTTPConnection(args.p) -gas_oracle = OverrideGasOracle(conn) - -address = to_checksum(args.address) -if not args.u and address != add_0x(args.address): - raise ValueError('invalid checksum address') +rpc = chainlib.eth.cli.Rpc() +conn = rpc.connect_by_config(config) -token_address = args.a +chain_spec = ChainSpec.from_chain_str(config.get('CHAIN_SPEC')) -fmt = args.f - -chain_spec = ChainSpec.from_chain_str(args.i) +token_address = config.get('_EXEC_ADDRESS') def main(): - r = None - decimals = 18 g = ERC20(chain_spec=chain_spec) + # determine decimals decimals_o = g.decimals(token_address) r = conn.do(decimals_o) @@ -96,9 +79,8 @@ def main(): token_symbol = g.parse_symbol(r) logg.info('symbol {}'.format(token_symbol)) - # get balance - balance_o = g.balance(token_address, address) + balance_o = g.balance(token_address, holder_address) r = conn.do(balance_o) hx = strip_0x(r) @@ -107,9 +89,7 @@ def main(): balance_str = str(balance_value) balance_len = len(balance_str) - if fmt == 'terminal': - sys.stdout.write('{} ({}): '.format(token_name, token_symbol)) - if fmt == 'raw': + if config.get('_RAW'): print(balance_str) else: if balance_len < decimals + 1: diff --git a/python/eth_erc20/runnable/transfer.py b/python/eth_erc20/runnable/transfer.py @@ -16,7 +16,7 @@ import json import argparse import logging -# third-party imports +# external imports from crypto_dev_signer.eth.signer import ReferenceSigner as EIP155Signer from crypto_dev_signer.keystore.dict import DictKeystore from hexathon import ( @@ -37,6 +37,8 @@ from chainlib.eth.gas import ( ) from chainlib.chain import ChainSpec from chainlib.eth.runnable.util import decode_for_puny_humans +from chainlib.eth.address import to_checksum_address +import chainlib.eth.cli # local imports from eth_erc20 import ERC20 @@ -44,124 +46,70 @@ from eth_erc20 import ERC20 logging.basicConfig(level=logging.WARNING) logg = logging.getLogger() -logging.getLogger('web3').setLevel(logging.WARNING) -logging.getLogger('urllib3').setLevel(logging.WARNING) - -default_eth_provider = os.environ.get('RPC_PROVIDER') -if default_eth_provider == None: - default_eth_provider = os.environ.get('ETH_PROVIDER', 'http://localhost:8545') - -argparser = argparse.ArgumentParser() -argparser.add_argument('-p', '--provider', dest='p', default=default_eth_provider, 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('-a', '--token-address', required='True', dest='a', type=str, help='Token address') -argparser.add_argument('-y', '--key-file', dest='y', type=str, help='Ethereum keystore file to use for signing') -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('-u', '--unsafe', dest='u', action='store_true', help='Auto-convert address to checksum adddress') -argparser.add_argument('-s', '--send', dest='s', action='store_true', help='Send to network') -argparser.add_argument('--nonce', type=int, help='Override nonce') -argparser.add_argument('--gas-price', dest='gas_price', type=int, help='Override gas price') -argparser.add_argument('--gas-limit', dest='gas_limit', type=int, help='Override gas limit') -argparser.add_argument('--seq', action='store_true', help='Use sequential rpc ids') -argparser.add_argument('-v', action='store_true', help='Be verbose') -argparser.add_argument('-vv', action='store_true', help='Be more verbose') -argparser.add_argument('recipient', type=str, help='Recipient account address') -argparser.add_argument('amount', type=int, help='Amount of tokens to mint and gift') +arg_flags = chainlib.eth.cli.argflag_std_write | chainlib.eth.cli.Flag.EXEC | chainlib.eth.cli.Flag.WALLET +argparser = chainlib.eth.cli.ArgumentParser(arg_flags) +argparser.add_positional('amount', type=int, help='Token amount to send') args = argparser.parse_args() +extra_args = { + 'amount': None, + } +config = chainlib.eth.cli.Config.from_args(args, arg_flags, extra_args=extra_args, default_fee_limit=100000) - -if args.vv: - logg.setLevel(logging.DEBUG) -elif args.v: - logg.setLevel(logging.INFO) - -block_all = args.ww +block_all = args.ww block_last = args.w or block_all -passphrase_env = 'ETH_PASSPHRASE' -if args.env_prefix != None: - passphrase_env = args.env_prefix + '_' + passphrase_env -passphrase = os.environ.get(passphrase_env) -logg.error('pass {}'.format(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) - -rpc_id_generator = None -if args.seq: - rpc_id_generator = IntSequenceGenerator() - -auth = None -#if os.environ.get('RPC_AUTHENTICATION') == 'custom_token': +wallet = chainlib.eth.cli.Wallet() +wallet.from_config(config) -if os.environ.get('RPC_AUTHENTICATION') == 'basic': - from chainlib.auth import BasicAuth - #auth = CustomHeaderTokenAuth('x-api-key', os.environ['RPC_AUTHENTICATION_STRING']) - auth = BasicAuth(os.environ['RPC_USERNAME'], os.environ['RPC_PASSWORD']) -conn = EthHTTPConnection(args.p) +rpc = chainlib.eth.cli.Rpc(wallet=wallet) +conn = rpc.connect_by_config(config) -nonce_oracle = None -if args.nonce != None: - nonce_oracle = OverrideNonceOracle(signer_address, args.nonce, id_generator=rpc_id_generator) -else: - nonce_oracle = RPCNonceOracle(signer_address, conn, id_generator=rpc_id_generator) +chain_spec = ChainSpec.from_chain_str(config.get('CHAIN_SPEC')) -#def _max_gas(code=None): -# return 8000000 +value = config.get('_AMOUNT') -gas_oracle = None -if args.gas_price != None or args.gas_limit != None: - gas_oracle = OverrideGasOracle(price=args.gas_price, limit=args.gas_limit, id_generator=rpc_id_generator, conn=conn) -else: - gas_oracle = RPCGasOracle(conn, code_callback=ERC20.gas, id_generator=rpc_id_generator) +send = config.true('_RPC_SEND') -chain_spec = ChainSpec.from_chain_str(args.i) -chain_id = chain_spec.network_id() -value = args.amount +def balance(generator, token_address, address, id_generator=None): + o = generator.balance(token_address, address, id_generator=id_generator) + r = conn.do(o) + token_balance = generator.parse_balance(r) + return token_balance -send = args.s -g = ERC20(chain_spec, signer=signer, gas_oracle=gas_oracle, nonce_oracle=nonce_oracle) +def main(): + signer = rpc.get_signer() + signer_address = rpc.get_sender_address() + gas_oracle = rpc.get_gas_oracle() + nonce_oracle = rpc.get_nonce_oracle() -def balance(token_address, address, id_generator=None): - o = g.balance(token_address, address, id_generator=id_generator) - r = conn.do(o) - hx = strip_0x(r) - return int(hx, 16) + g = ERC20(chain_spec, signer=signer, gas_oracle=gas_oracle, nonce_oracle=nonce_oracle) + recipient = to_checksum_address(config.get('_RECIPIENT')) + if not config.true('_UNSAFE') and recipient != add_0x(config.get('_RECIPIENT')): + raise ValueError('invalid checksum address for recipient') -def main(): - recipient = args.recipient - if not args.u and recipient != add_0x(args.recipient): - raise ValueError('invalid checksum address') + token_address = to_checksum_address(config.get('_EXEC_ADDRESS')) + if not config.true('_UNSAFE') and token_address != add_0x(config.get('_EXEC_ADDRESS')): + raise ValueError('invalid checksum address for contract') if logg.isEnabledFor(logging.DEBUG): - sender_balance = balance(args.a, signer_address, id_generator=rpc_id_generator) - recipient_balance = balance(args.a, recipient, id_generator=rpc_id_generator) - logg.debug('sender {} balance after: {}'.format(signer_address, sender_balance)) - logg.debug('recipient {} balance after: {}'.format(recipient, recipient_balance)) + sender_balance = balance(g, token_address, signer_address, id_generator=rpc.id_generator) + recipient_balance = balance(g, token_address, recipient, id_generator=rpc.id_generator) + logg.debug('sender {} balance before: {}'.format(signer_address, sender_balance)) + logg.debug('recipient {} balance before: {}'.format(recipient, recipient_balance)) - (tx_hash_hex, o) = g.transfer(args.a, signer_address, recipient, value, id_generator=rpc_id_generator) + (tx_hash_hex, o) = g.transfer(token_address, signer_address, recipient, value, id_generator=rpc.id_generator) if send: conn.do(o) if block_last: r = conn.wait(tx_hash_hex) if logg.isEnabledFor(logging.DEBUG): - sender_balance = balance(args.a, signer_address, id_generator=rpc_id_generator) - recipient_balance = balance(args.a, recipient, id_generator=rpc_id_generator) + sender_balance = balance(g, token_address, signer_address, id_generator=rpc.id_generator) + recipient_balance = balance(g, token_address, recipient, id_generator=rpc.id_generator) logg.debug('sender {} balance after: {}'.format(signer_address, sender_balance)) logg.debug('recipient {} balance after: {}'.format(recipient, recipient_balance)) if r['status'] == 0: @@ -170,12 +118,7 @@ def main(): print(tx_hash_hex) else: - if logg.isEnabledFor(logging.INFO): - io_str = io.StringIO() - decode_for_puny_humans(o['params'][0], chain_spec, io_str) - print(io_str.getvalue()) - else: - print(o['params'][0]) + print(o['params'][0]) if __name__ == '__main__': diff --git a/python/giftable_erc20_token/data/GiftableToken.bin b/python/giftable_erc20_token/data/GiftableToken.bin @@ -1 +1 @@ -60806040523480156200001157600080fd5b50604051620017a5380380620017a583398181016040528101906200003791906200025d565b336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555082600290805190602001906200008f92919062000124565b508160039080519060200190620000a892919062000124565b5080600460006101000a81548160ff021916908360ff16021790555060018060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055505050506200047c565b828054620001329062000387565b90600052602060002090601f016020900481019282620001565760008555620001a2565b82601f106200017157805160ff1916838001178555620001a2565b82800160010185558215620001a2579182015b82811115620001a157825182559160200191906001019062000184565b5b509050620001b19190620001b5565b5090565b5b80821115620001d0576000816000905550600101620001b6565b5090565b6000620001eb620001e5846200030e565b620002e5565b9050828152602081018484840111156200020457600080fd5b6200021184828562000351565b509392505050565b600082601f8301126200022b57600080fd5b81516200023d848260208601620001d4565b91505092915050565b600081519050620002578162000462565b92915050565b6000806000606084860312156200027357600080fd5b600084015167ffffffffffffffff8111156200028e57600080fd5b6200029c8682870162000219565b935050602084015167ffffffffffffffff811115620002ba57600080fd5b620002c88682870162000219565b9250506040620002db8682870162000246565b9150509250925092565b6000620002f162000304565b9050620002ff8282620003bd565b919050565b6000604051905090565b600067ffffffffffffffff8211156200032c576200032b62000422565b5b620003378262000451565b9050602081019050919050565b600060ff82169050919050565b60005b838110156200037157808201518184015260208101905062000354565b8381111562000381576000848401525b50505050565b60006002820490506001821680620003a057607f821691505b60208210811415620003b757620003b6620003f3565b5b50919050565b620003c88262000451565b810181811067ffffffffffffffff82111715620003ea57620003e962000422565b5b80604052505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000601f19601f8301169050919050565b6200046d8162000344565b81146200047957600080fd5b50565b611319806200048c6000396000f3fe608060405234801561001057600080fd5b50600436106100ec576000357c010000000000000000000000000000000000000000000000000000000090048063313ce567116100a957806395d89b411161008357806395d89b411461026b578063983b2d5614610289578063a9059cbb146102b9578063dd62ed3e146102e9576100ec565b8063313ce567146101ed578063449a52f81461020b57806370a082311461023b576100ec565b806301ffc9a7146100f157806306fdde0314610121578063095ea7b31461013f57806318160ddd1461016f57806323b872dd1461018d5780633092afd5146101bd575b600080fd5b61010b60048036038101906101069190610fa1565b610319565b6040516101189190611030565b60405180910390f35b61012961041e565b604051610136919061104b565b60405180910390f35b61015960048036038101906101549190610f65565b6104ac565b6040516101669190611030565b60405180910390f35b610177610630565b604051610184919061106d565b60405180910390f35b6101a760048036038101906101a29190610f16565b610636565b6040516101b49190611030565b60405180910390f35b6101d760048036038101906101d29190610eb1565b610948565b6040516101e49190611030565b60405180910390f35b6101f5610a3a565b6040516102029190611088565b60405180910390f35b61022560048036038101906102209190610f65565b610a4d565b6040516102329190611030565b60405180910390f35b61025560048036038101906102509190610eb1565b610b83565b604051610262919061106d565b60405180910390f35b610273610b9b565b604051610280919061104b565b60405180910390f35b6102a3600480360381019061029e9190610eb1565b610c29565b6040516102b09190611030565b60405180910390f35b6102d360048036038101906102ce9190610f65565b610ce4565b6040516102e09190611030565b60405180910390f35b61030360048036038101906102fe9190610eda565b610e4d565b604051610310919061106d565b60405180910390f35b600063c6bb4b707c010000000000000000000000000000000000000000000000000000000002827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916141561036e5760019050610419565b63449a52f87c010000000000000000000000000000000000000000000000000000000002827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614156103c15760019050610419565b6301ffc9a77c010000000000000000000000000000000000000000000000000000000002827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614156104145760019050610419565b600090505b919050565b6002805461042b906111fd565b80601f0160208091040260200160405190810160405280929190818152602001828054610457906111fd565b80156104a45780601f10610479576101008083540402835291602001916104a4565b820191906000526020600020905b81548152906001019060200180831161048757829003601f168201915b505050505081565b600080821115610540576000600760003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541461053f57600080fd5b5b81600760003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9258460405161061e919061106d565b60405180910390a36001905092915050565b60055481565b600081600760008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205410156106c157600080fd5b81600660008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054101561070d57600080fd5b81600760008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546107959190611115565b600760008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555081600660008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546108649190611115565b9250508190555081600660008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546108ba91906110bf565b925050819055503373ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167f5f7542858008eeb041631f30e6109ae94b83a58e9a58261dd2c42c508850f93985604051610935919061106d565b60405180910390a4600190509392505050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806109d057508173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b6109d957600080fd5b6000600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555060019050919050565b600460009054906101000a900460ff1681565b6000600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16610aa557600080fd5b81600660008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254610af491906110bf565b925050819055508160056000828254610b0d91906110bf565b925050819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fab8530f87dc9b59234c4623bf917212bb2536d647574c8e7e5da92c2ede0c9f884604051610b71919061106d565b60405180910390a36001905092915050565b60066020528060005260406000206000915090505481565b60038054610ba8906111fd565b80601f0160208091040260200160405190810160405280929190818152602001828054610bd4906111fd565b8015610c215780601f10610bf657610100808354040283529160200191610c21565b820191906000526020600020905b815481529060010190602001808311610c0457829003601f168201915b505050505081565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610c8457600080fd5b60018060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555060019050919050565b600081600660003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541015610d3257600080fd5b81600660003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254610d819190611115565b9250508190555081600660008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254610dd791906110bf565b925050819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051610e3b919061106d565b60405180910390a36001905092915050565b6007602052816000526040600020602052806000526040600020600091509150505481565b600081359050610e818161129e565b92915050565b600081359050610e96816112b5565b92915050565b600081359050610eab816112cc565b92915050565b600060208284031215610ec357600080fd5b6000610ed184828501610e72565b91505092915050565b60008060408385031215610eed57600080fd5b6000610efb85828601610e72565b9250506020610f0c85828601610e72565b9150509250929050565b600080600060608486031215610f2b57600080fd5b6000610f3986828701610e72565b9350506020610f4a86828701610e72565b9250506040610f5b86828701610e9c565b9150509250925092565b60008060408385031215610f7857600080fd5b6000610f8685828601610e72565b9250506020610f9785828601610e9c565b9150509250929050565b600060208284031215610fb357600080fd5b6000610fc184828501610e87565b91505092915050565b610fd38161115b565b82525050565b6000610fe4826110a3565b610fee81856110ae565b9350610ffe8185602086016111ca565b6110078161128d565b840191505092915050565b61101b816111b3565b82525050565b61102a816111bd565b82525050565b60006020820190506110456000830184610fca565b92915050565b600060208201905081810360008301526110658184610fd9565b905092915050565b60006020820190506110826000830184611012565b92915050565b600060208201905061109d6000830184611021565b92915050565b600081519050919050565b600082825260208201905092915050565b60006110ca826111b3565b91506110d5836111b3565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0382111561110a5761110961122f565b5b828201905092915050565b6000611120826111b3565b915061112b836111b3565b92508282101561113e5761113d61122f565b5b828203905092915050565b600061115482611193565b9050919050565b60008115159050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600060ff82169050919050565b60005b838110156111e85780820151818401526020810190506111cd565b838111156111f7576000848401525b50505050565b6000600282049050600182168061121557607f821691505b602082108114156112295761122861125e565b5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000601f19601f8301169050919050565b6112a781611149565b81146112b257600080fd5b50565b6112be81611167565b81146112c957600080fd5b50565b6112d5816111b3565b81146112e057600080fd5b5056fea264697066735822122081dda93f8f62cdd00d5a28d40736a4d2ce80f280f7c878ee8bc8ac6980493dbe64736f6c63430008040033 -\ No newline at end of file +60806040523480156200001157600080fd5b50604051620017f0380380620017f0833981810160405281019062000037919062000269565b336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555082600290805190602001906200008f92919062000124565b508160039080519060200190620000a892919062000124565b5080600460006101000a81548160ff021916908360ff16021790555060018060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550505050620004ae565b8280546200013290620003a5565b90600052602060002090601f016020900481019282620001565760008555620001a2565b82601f106200017157805160ff1916838001178555620001a2565b82800160010185558215620001a2579182015b82811115620001a157825182559160200191906001019062000184565b5b509050620001b19190620001b5565b5090565b5b80821115620001d0576000816000905550600101620001b6565b5090565b6000620001eb620001e5846200032c565b62000303565b9050828152602081018484840111156200020a576200020962000474565b5b620002178482856200036f565b509392505050565b600082601f8301126200023757620002366200046f565b5b815162000249848260208601620001d4565b91505092915050565b600081519050620002638162000494565b92915050565b6000806000606084860312156200028557620002846200047e565b5b600084015167ffffffffffffffff811115620002a657620002a562000479565b5b620002b4868287016200021f565b935050602084015167ffffffffffffffff811115620002d857620002d762000479565b5b620002e6868287016200021f565b9250506040620002f98682870162000252565b9150509250925092565b60006200030f62000322565b90506200031d8282620003db565b919050565b6000604051905090565b600067ffffffffffffffff8211156200034a576200034962000440565b5b620003558262000483565b9050602081019050919050565b600060ff82169050919050565b60005b838110156200038f57808201518184015260208101905062000372565b838111156200039f576000848401525b50505050565b60006002820490506001821680620003be57607f821691505b60208210811415620003d557620003d462000411565b5b50919050565b620003e68262000483565b810181811067ffffffffffffffff8211171562000408576200040762000440565b5b80604052505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b6200049f8162000362565b8114620004ab57600080fd5b50565b61133280620004be6000396000f3fe608060405234801561001057600080fd5b50600436106100ec576000357c010000000000000000000000000000000000000000000000000000000090048063313ce567116100a957806395d89b411161008357806395d89b411461026b578063983b2d5614610289578063a9059cbb146102b9578063dd62ed3e146102e9576100ec565b8063313ce567146101ed578063449a52f81461020b57806370a082311461023b576100ec565b806301ffc9a7146100f157806306fdde0314610121578063095ea7b31461013f57806318160ddd1461016f57806323b872dd1461018d5780633092afd5146101bd575b600080fd5b61010b60048036038101906101069190610fb1565b610319565b6040516101189190611044565b60405180910390f35b61012961041e565b604051610136919061105f565b60405180910390f35b61015960048036038101906101549190610f71565b6104ac565b6040516101669190611044565b60405180910390f35b610177610630565b6040516101849190611081565b60405180910390f35b6101a760048036038101906101a29190610f1e565b610636565b6040516101b49190611044565b60405180910390f35b6101d760048036038101906101d29190610eb1565b610948565b6040516101e49190611044565b60405180910390f35b6101f5610a3a565b604051610202919061109c565b60405180910390f35b61022560048036038101906102209190610f71565b610a4d565b6040516102329190611044565b60405180910390f35b61025560048036038101906102509190610eb1565b610b83565b6040516102629190611081565b60405180910390f35b610273610b9b565b604051610280919061105f565b60405180910390f35b6102a3600480360381019061029e9190610eb1565b610c29565b6040516102b09190611044565b60405180910390f35b6102d360048036038101906102ce9190610f71565b610ce4565b6040516102e09190611044565b60405180910390f35b61030360048036038101906102fe9190610ede565b610e4d565b6040516103109190611081565b60405180910390f35b600063c6bb4b707c010000000000000000000000000000000000000000000000000000000002827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916141561036e5760019050610419565b63449a52f87c010000000000000000000000000000000000000000000000000000000002827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614156103c15760019050610419565b6301ffc9a77c010000000000000000000000000000000000000000000000000000000002827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614156104145760019050610419565b600090505b919050565b6002805461042b90611211565b80601f016020809104026020016040519081016040528092919081815260200182805461045790611211565b80156104a45780601f10610479576101008083540402835291602001916104a4565b820191906000526020600020905b81548152906001019060200180831161048757829003601f168201915b505050505081565b600080821115610540576000600760003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541461053f57600080fd5b5b81600760003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9258460405161061e9190611081565b60405180910390a36001905092915050565b60055481565b600081600760008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205410156106c157600080fd5b81600660008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054101561070d57600080fd5b81600760008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546107959190611129565b600760008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555081600660008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546108649190611129565b9250508190555081600660008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546108ba91906110d3565b925050819055503373ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167f5f7542858008eeb041631f30e6109ae94b83a58e9a58261dd2c42c508850f939856040516109359190611081565b60405180910390a4600190509392505050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806109d057508173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b6109d957600080fd5b6000600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555060019050919050565b600460009054906101000a900460ff1681565b6000600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16610aa557600080fd5b81600660008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254610af491906110d3565b925050819055508160056000828254610b0d91906110d3565b925050819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fab8530f87dc9b59234c4623bf917212bb2536d647574c8e7e5da92c2ede0c9f884604051610b719190611081565b60405180910390a36001905092915050565b60066020528060005260406000206000915090505481565b60038054610ba890611211565b80601f0160208091040260200160405190810160405280929190818152602001828054610bd490611211565b8015610c215780601f10610bf657610100808354040283529160200191610c21565b820191906000526020600020905b815481529060010190602001808311610c0457829003601f168201915b505050505081565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610c8457600080fd5b60018060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555060019050919050565b600081600660003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541015610d3257600080fd5b81600660003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254610d819190611129565b9250508190555081600660008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254610dd791906110d3565b925050819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051610e3b9190611081565b60405180910390a36001905092915050565b6007602052816000526040600020602052806000526040600020600091509150505481565b600081359050610e81816112b7565b92915050565b600081359050610e96816112ce565b92915050565b600081359050610eab816112e5565b92915050565b600060208284031215610ec757610ec66112a1565b5b6000610ed584828501610e72565b91505092915050565b60008060408385031215610ef557610ef46112a1565b5b6000610f0385828601610e72565b9250506020610f1485828601610e72565b9150509250929050565b600080600060608486031215610f3757610f366112a1565b5b6000610f4586828701610e72565b9350506020610f5686828701610e72565b9250506040610f6786828701610e9c565b9150509250925092565b60008060408385031215610f8857610f876112a1565b5b6000610f9685828601610e72565b9250506020610fa785828601610e9c565b9150509250929050565b600060208284031215610fc757610fc66112a1565b5b6000610fd584828501610e87565b91505092915050565b610fe78161116f565b82525050565b6000610ff8826110b7565b61100281856110c2565b93506110128185602086016111de565b61101b816112a6565b840191505092915050565b61102f816111c7565b82525050565b61103e816111d1565b82525050565b60006020820190506110596000830184610fde565b92915050565b600060208201905081810360008301526110798184610fed565b905092915050565b60006020820190506110966000830184611026565b92915050565b60006020820190506110b16000830184611035565b92915050565b600081519050919050565b600082825260208201905092915050565b60006110de826111c7565b91506110e9836111c7565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0382111561111e5761111d611243565b5b828201905092915050565b6000611134826111c7565b915061113f836111c7565b92508282101561115257611151611243565b5b828203905092915050565b6000611168826111a7565b9050919050565b60008115159050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600060ff82169050919050565b60005b838110156111fc5780820151818401526020810190506111e1565b8381111561120b576000848401525b50505050565b6000600282049050600182168061122957607f821691505b6020821081141561123d5761123c611272565b5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600080fd5b6000601f19601f8301169050919050565b6112c08161115d565b81146112cb57600080fd5b50565b6112d78161117b565b81146112e257600080fd5b50565b6112ee816111c7565b81146112f957600080fd5b5056fea264697066735822122025d7f4c78e8965d75a35f7520bb91ec41a9cb560b63fecde62a8939d87c3affb64736f6c63430008060033 +\ No newline at end of file diff --git a/python/giftable_erc20_token/factory.py b/python/giftable_erc20_token/factory.py @@ -38,7 +38,7 @@ class GiftableToken(TxFactory): @staticmethod def gas(code=None): - return 1500000 + return 2000000 @staticmethod @@ -71,6 +71,18 @@ class GiftableToken(TxFactory): return tx + def remove_minter(self, contract_address, sender_address, address, tx_format=TxFormat.JSONRPC): + enc = ABIContractEncoder() + enc.method('removeMinter') + enc.typ(ABIContractType.ADDRESS) + enc.address(address) + data = enc.get() + tx = self.template(sender_address, contract_address, use_nonce=True) + tx = self.set_code(tx, data) + tx = self.finalize(tx, tx_format) + return tx + + def mint_to(self, contract_address, sender_address, address, value, tx_format=TxFormat.JSONRPC): enc = ABIContractEncoder() enc.method('mintTo') diff --git a/python/giftable_erc20_token/runnable/deploy.py b/python/giftable_erc20_token/runnable/deploy.py @@ -17,17 +17,8 @@ import time from enum import Enum # external imports -from crypto_dev_signer.eth.signer import ReferenceSigner as EIP155Signer -from crypto_dev_signer.keystore.dict import DictKeystore +import chainlib.eth.cli 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.tx import receipt @@ -37,83 +28,47 @@ from giftable_erc20_token import GiftableToken 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='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('--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('--name', default='Giftable Token', type=str, help='Token name') -argparser.add_argument('--symbol', default='GFT', type=str, help='Token symbol') -argparser.add_argument('--decimals', default=18, type=int, help='Token decimals') -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('-v', action='store_true', help='Be verbose') -argparser.add_argument('-vv', action='store_true', help='Be more verbose') +arg_flags = chainlib.eth.cli.argflag_std_write +argparser = chainlib.eth.cli.ArgumentParser(arg_flags) +argparser.add_argument('--name', dest='token_name', required=True, type=str, help='Token name') +argparser.add_argument('--symbol', dest='token_symbol', required=True, type=str, help='Token symbol') +argparser.add_argument('--decimals', dest='token_decimals', default=18, type=int, help='Token decimals') args = argparser.parse_args() -if args.vv: - logg.setLevel(logging.DEBUG) -elif args.v: - logg.setLevel(logging.INFO) +extra_args = { + 'token_name': None, + 'token_symbol': None, + 'token_decimals': None, + } +config = chainlib.eth.cli.Config.from_args(args, arg_flags, extra_args=extra_args, default_fee_limit=GiftableToken.gas()) -block_all = args.ww -block_last = args.w or block_all +wallet = chainlib.eth.cli.Wallet() +wallet.from_config(config) -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='' +rpc = chainlib.eth.cli.Rpc(wallet=wallet) +conn = rpc.connect_by_config(config) -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(config.get('CHAIN_SPEC')) -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=GiftableToken.gas) -else: - gas_oracle = RPCGasOracle(rpc, code_callback=GiftableToken.gas) - -dummy = args.d +def main(): + signer = rpc.get_signer() + signer_address = rpc.get_sender_address() -token_name = args.name -token_symbol = args.symbol -token_decimals = args.decimals + token_name = config.get('_TOKEN_NAME') + token_symbol = config.get('_TOKEN_SYMBOL') + token_decimals = config.get('_TOKEN_DECIMALS') + gas_oracle = rpc.get_gas_oracle() + nonce_oracle = rpc.get_nonce_oracle() -def main(): c = GiftableToken(chain_spec, signer=signer, gas_oracle=gas_oracle, nonce_oracle=nonce_oracle) + (tx_hash_hex, o) = c.constructor(signer_address, token_name, token_symbol, token_decimals) - if dummy: - print(tx_hash_hex) - print(o) - else: - rpc.do(o) - if block_last: - r = rpc.wait(tx_hash_hex) + 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) @@ -123,6 +78,8 @@ def main(): print(address) else: print(tx_hash_hex) + else: + print(o) if __name__ == '__main__': diff --git a/python/giftable_erc20_token/runnable/gift.py b/python/giftable_erc20_token/runnable/gift.py @@ -15,20 +15,16 @@ import argparse import logging import time -# third-party imports -from crypto_dev_signer.eth.signer import ReferenceSigner as EIP155Signer -from crypto_dev_signer.keystore.dict import DictKeystore +# external imports +import chainlib.eth.cli from chainlib.eth.tx import receipt 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.address import to_checksum_address +from hexathon import ( + strip_0x, + add_0x, + ) # local imports from giftable_erc20_token import GiftableToken @@ -36,85 +32,50 @@ from giftable_erc20_token import GiftableToken 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('-e', action='store_true', help='Treat all transactions as essential') -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('-a', '--token-address', required='True', dest='a', type=str, help='Giftable token address') -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') -argparser.add_argument('--recipient', type=str, help='Recipient account address. If not set, tokens will be gifted to the keystore account') -argparser.add_argument('value', type=int, help='Value of tokens to mint and gift') +arg_flags = chainlib.eth.cli.argflag_std_write | chainlib.eth.cli.Flag.EXEC | chainlib.eth.cli.Flag.WALLET +argparser = chainlib.eth.cli.ArgumentParser(arg_flags) +argparser.add_positional('amount', type=int, help='Token amount to gift') args = argparser.parse_args() +extra_args = { + 'amount': None, + } +config = chainlib.eth.cli.Config.from_args(args, arg_flags, extra_args=extra_args, default_fee_limit=GiftableToken.gas()) + +wallet = chainlib.eth.cli.Wallet() +wallet.from_config(config) -if args.vv: - logg.setLevel(logging.DEBUG) -elif args.v: - logg.setLevel(logging.INFO) - -block_all = args.ww -block_last = args.w or block_all - -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) - -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=GiftableToken.gas) -else: - gas_oracle = RPCGasOracle(rpc, code_callback=GiftableToken.gas) - -dummy = args.d - -token_address = args.a -recipient_address = args.recipient -if recipient_address == None: - recipient_address = signer_address -token_value = args.value +rpc = chainlib.eth.cli.Rpc(wallet=wallet) +conn = rpc.connect_by_config(config) + +chain_spec = ChainSpec.from_chain_str(config.get('CHAIN_SPEC')) def main(): + signer = rpc.get_signer() + signer_address = rpc.get_sender_address() + + gas_oracle = rpc.get_gas_oracle() + nonce_oracle = rpc.get_nonce_oracle() + + recipient_address_input = config.get('_RECIPIENT') + if recipient_address_input == None: + recipient_address_input = signer_address + + recipient_address = add_0x(to_checksum_address(recipient_address_input)) + if not config.true('_UNSAFE') and recipient_address != add_0x(recipient_address_input): + raise ValueError('invalid checksum address for recipient') + + token_address = add_0x(to_checksum_address(config.get('_EXEC_ADDRESS'))) + if not config.true('_UNSAFE') and token_address != add_0x(config.get('_EXEC_ADDRESS')): + raise ValueError('invalid checksum address for contract') + + token_value = config.get('_AMOUNT') c = GiftableToken(chain_spec, signer=signer, gas_oracle=gas_oracle, nonce_oracle=nonce_oracle) (tx_hash_hex, o) = c.mint_to(token_address, signer_address, recipient_address, token_value) - if dummy: - print(tx_hash_hex) - print(o) - else: - rpc.do(o) - if block_last: - r = rpc.wait(tx_hash_hex) + 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. Wish I had more to tell you') sys.exit(1) @@ -122,6 +83,8 @@ def main(): logg.info('mint to {} tx {}'.format(recipient_address, tx_hash_hex)) print(tx_hash_hex) + else: + print(o) if __name__ == '__main__': diff --git a/python/giftable_erc20_token/runnable/minter.py b/python/giftable_erc20_token/runnable/minter.py @@ -16,19 +16,15 @@ import logging import time # external imports +import chainlib.eth.cli from chainlib.eth.connection import EthHTTPConnection -from crypto_dev_signer.eth.signer import ReferenceSigner as EIP155Signer -from crypto_dev_signer.keystore.dict import DictKeystore -from chainlib.eth.nonce import ( - RPCNonceOracle, - OverrideNonceOracle, - ) -from chainlib.eth.gas import ( - RPCGasOracle, - OverrideGasOracle, - ) from chainlib.chain import ChainSpec from chainlib.eth.tx import receipt +from chainlib.eth.address import to_checksum_address +from hexathon import ( + strip_0x, + add_0x, + ) # local imports from giftable_erc20_token import GiftableToken @@ -36,80 +32,56 @@ from giftable_erc20_token import GiftableToken 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='evm:ethereum:1', help='Chain specification string') -argparser.add_argument('-a', '--token-address', required='True', dest='a', type=str, help='Giftable token address') -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') -argparser.add_argument('minter_address', type=str, help='Minter address to add') +arg_flags = chainlib.eth.cli.argflag_std_write | chainlib.eth.cli.Flag.EXEC | chainlib.eth.cli.Flag.WALLET +argparser = chainlib.eth.cli.ArgumentParser(arg_flags) +argparser.add_argument('--rm', action='store_true', help='Remove entry') +argparser.add_positional('minter_address', type=str, help='Address to add or remove as minter') args = argparser.parse_args() +extra_args = { + 'rm': None, + 'minter_address': None, + } +config = chainlib.eth.cli.Config.from_args(args, arg_flags, extra_args=extra_args, default_fee_limit=GiftableToken.gas()) -if args.vv: - logg.setLevel(logging.DEBUG) -elif args.v: - logg.setLevel(logging.INFO) +wallet = chainlib.eth.cli.Wallet() +wallet.from_config(config) -block_all = args.ww -block_last = args.w or block_all +rpc = chainlib.eth.cli.Rpc(wallet=wallet) +conn = rpc.connect_by_config(config) -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='' +chain_spec = ChainSpec.from_chain_str(config.get('CHAIN_SPEC')) -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) - -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) +def main(): + signer = rpc.get_signer() + signer_address = rpc.get_sender_address() -gas_oracle = None -if args.gas_price !=None: - gas_oracle = OverrideGasOracle(price=args.gas_price, conn=rpc, code_callback=GiftableToken.gas) -else: - gas_oracle = RPCGasOracle(rpc, code_callback=GiftableToken.gas) + gas_oracle = rpc.get_gas_oracle() + nonce_oracle = rpc.get_nonce_oracle() -dummy = args.d + recipient_address_input = config.get('_RECIPIENT') + if recipient_address_input == None: + recipient_address_input = signer_address -token_address = args.a -minter_address = args.minter_address + recipient_address = add_0x(to_checksum_address(recipient_address_input)) + if not config.true('_UNSAFE') and recipient_address != add_0x(recipient_address_input): + raise ValueError('invalid checksum address for recipient') + token_address = add_0x(to_checksum_address(config.get('_EXEC_ADDRESS'))) + if not config.true('_UNSAFE') and token_address != add_0x(config.get('_EXEC_ADDRESS')): + raise ValueError('invalid checksum address for contract') -def main(): + minter_address = config.get('_MINTER_ADDRESS') c = GiftableToken(chain_spec, signer=signer, gas_oracle=gas_oracle, nonce_oracle=nonce_oracle) - (tx_hash_hex, o) = c.add_minter(token_address, signer_address, minter_address) - if dummy: - print(tx_hash_hex) - print(o) + if config.get('_RM'): + (tx_hash_hex, o) = c.remove_minter(token_address, signer_address, minter_address) else: - rpc.do(o) - if block_last: - r = rpc.wait(tx_hash_hex) + (tx_hash_hex, o) = c.add_minter(token_address, signer_address, minter_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. Wish I had more to tell you') sys.exit(1) @@ -117,6 +89,8 @@ def main(): logg.info('add minter {} to {} tx {}'.format(minter_address, token_address, tx_hash_hex)) print(tx_hash_hex) + else: + print(o) if __name__ == '__main__': diff --git a/python/requirements.txt b/python/requirements.txt @@ -1,4 +1,4 @@ -confini~=0.3.6rc3 -crypto-dev-signer~=0.4.14b6 -chainlib-eth~=0.0.5a1 +confini>=0.3.6rc3,<0.5.0 +crypto-dev-signer>=0.4.14b7,<=0.4.14 +chainlib-eth>=0.0.7a4,<=0.1.0 potaahto~=0.0.1a2 diff --git a/python/setup.cfg b/python/setup.cfg @@ -1,6 +1,6 @@ [metadata] name = eth-erc20 -version = 0.0.10a2 +version = 0.1.1a1 description = ERC20 interface and simple contract with deployment script that lets any address mint and gift itself tokens. author = Louis Holbrook author_email = dev@holbrook.no diff --git a/solidity/GiftableToken.bin b/solidity/GiftableToken.bin @@ -1 +1 @@ -60806040523480156200001157600080fd5b50604051620017a5380380620017a583398181016040528101906200003791906200025d565b336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555082600290805190602001906200008f92919062000124565b508160039080519060200190620000a892919062000124565b5080600460006101000a81548160ff021916908360ff16021790555060018060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055505050506200047c565b828054620001329062000387565b90600052602060002090601f016020900481019282620001565760008555620001a2565b82601f106200017157805160ff1916838001178555620001a2565b82800160010185558215620001a2579182015b82811115620001a157825182559160200191906001019062000184565b5b509050620001b19190620001b5565b5090565b5b80821115620001d0576000816000905550600101620001b6565b5090565b6000620001eb620001e5846200030e565b620002e5565b9050828152602081018484840111156200020457600080fd5b6200021184828562000351565b509392505050565b600082601f8301126200022b57600080fd5b81516200023d848260208601620001d4565b91505092915050565b600081519050620002578162000462565b92915050565b6000806000606084860312156200027357600080fd5b600084015167ffffffffffffffff8111156200028e57600080fd5b6200029c8682870162000219565b935050602084015167ffffffffffffffff811115620002ba57600080fd5b620002c88682870162000219565b9250506040620002db8682870162000246565b9150509250925092565b6000620002f162000304565b9050620002ff8282620003bd565b919050565b6000604051905090565b600067ffffffffffffffff8211156200032c576200032b62000422565b5b620003378262000451565b9050602081019050919050565b600060ff82169050919050565b60005b838110156200037157808201518184015260208101905062000354565b8381111562000381576000848401525b50505050565b60006002820490506001821680620003a057607f821691505b60208210811415620003b757620003b6620003f3565b5b50919050565b620003c88262000451565b810181811067ffffffffffffffff82111715620003ea57620003e962000422565b5b80604052505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000601f19601f8301169050919050565b6200046d8162000344565b81146200047957600080fd5b50565b611319806200048c6000396000f3fe608060405234801561001057600080fd5b50600436106100ec576000357c010000000000000000000000000000000000000000000000000000000090048063313ce567116100a957806395d89b411161008357806395d89b411461026b578063983b2d5614610289578063a9059cbb146102b9578063dd62ed3e146102e9576100ec565b8063313ce567146101ed578063449a52f81461020b57806370a082311461023b576100ec565b806301ffc9a7146100f157806306fdde0314610121578063095ea7b31461013f57806318160ddd1461016f57806323b872dd1461018d5780633092afd5146101bd575b600080fd5b61010b60048036038101906101069190610fa1565b610319565b6040516101189190611030565b60405180910390f35b61012961041e565b604051610136919061104b565b60405180910390f35b61015960048036038101906101549190610f65565b6104ac565b6040516101669190611030565b60405180910390f35b610177610630565b604051610184919061106d565b60405180910390f35b6101a760048036038101906101a29190610f16565b610636565b6040516101b49190611030565b60405180910390f35b6101d760048036038101906101d29190610eb1565b610948565b6040516101e49190611030565b60405180910390f35b6101f5610a3a565b6040516102029190611088565b60405180910390f35b61022560048036038101906102209190610f65565b610a4d565b6040516102329190611030565b60405180910390f35b61025560048036038101906102509190610eb1565b610b83565b604051610262919061106d565b60405180910390f35b610273610b9b565b604051610280919061104b565b60405180910390f35b6102a3600480360381019061029e9190610eb1565b610c29565b6040516102b09190611030565b60405180910390f35b6102d360048036038101906102ce9190610f65565b610ce4565b6040516102e09190611030565b60405180910390f35b61030360048036038101906102fe9190610eda565b610e4d565b604051610310919061106d565b60405180910390f35b600063c6bb4b707c010000000000000000000000000000000000000000000000000000000002827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916141561036e5760019050610419565b63449a52f87c010000000000000000000000000000000000000000000000000000000002827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614156103c15760019050610419565b6301ffc9a77c010000000000000000000000000000000000000000000000000000000002827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614156104145760019050610419565b600090505b919050565b6002805461042b906111fd565b80601f0160208091040260200160405190810160405280929190818152602001828054610457906111fd565b80156104a45780601f10610479576101008083540402835291602001916104a4565b820191906000526020600020905b81548152906001019060200180831161048757829003601f168201915b505050505081565b600080821115610540576000600760003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541461053f57600080fd5b5b81600760003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9258460405161061e919061106d565b60405180910390a36001905092915050565b60055481565b600081600760008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205410156106c157600080fd5b81600660008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054101561070d57600080fd5b81600760008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546107959190611115565b600760008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555081600660008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546108649190611115565b9250508190555081600660008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546108ba91906110bf565b925050819055503373ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167f5f7542858008eeb041631f30e6109ae94b83a58e9a58261dd2c42c508850f93985604051610935919061106d565b60405180910390a4600190509392505050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806109d057508173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b6109d957600080fd5b6000600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555060019050919050565b600460009054906101000a900460ff1681565b6000600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16610aa557600080fd5b81600660008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254610af491906110bf565b925050819055508160056000828254610b0d91906110bf565b925050819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fab8530f87dc9b59234c4623bf917212bb2536d647574c8e7e5da92c2ede0c9f884604051610b71919061106d565b60405180910390a36001905092915050565b60066020528060005260406000206000915090505481565b60038054610ba8906111fd565b80601f0160208091040260200160405190810160405280929190818152602001828054610bd4906111fd565b8015610c215780601f10610bf657610100808354040283529160200191610c21565b820191906000526020600020905b815481529060010190602001808311610c0457829003601f168201915b505050505081565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610c8457600080fd5b60018060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555060019050919050565b600081600660003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541015610d3257600080fd5b81600660003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254610d819190611115565b9250508190555081600660008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254610dd791906110bf565b925050819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051610e3b919061106d565b60405180910390a36001905092915050565b6007602052816000526040600020602052806000526040600020600091509150505481565b600081359050610e818161129e565b92915050565b600081359050610e96816112b5565b92915050565b600081359050610eab816112cc565b92915050565b600060208284031215610ec357600080fd5b6000610ed184828501610e72565b91505092915050565b60008060408385031215610eed57600080fd5b6000610efb85828601610e72565b9250506020610f0c85828601610e72565b9150509250929050565b600080600060608486031215610f2b57600080fd5b6000610f3986828701610e72565b9350506020610f4a86828701610e72565b9250506040610f5b86828701610e9c565b9150509250925092565b60008060408385031215610f7857600080fd5b6000610f8685828601610e72565b9250506020610f9785828601610e9c565b9150509250929050565b600060208284031215610fb357600080fd5b6000610fc184828501610e87565b91505092915050565b610fd38161115b565b82525050565b6000610fe4826110a3565b610fee81856110ae565b9350610ffe8185602086016111ca565b6110078161128d565b840191505092915050565b61101b816111b3565b82525050565b61102a816111bd565b82525050565b60006020820190506110456000830184610fca565b92915050565b600060208201905081810360008301526110658184610fd9565b905092915050565b60006020820190506110826000830184611012565b92915050565b600060208201905061109d6000830184611021565b92915050565b600081519050919050565b600082825260208201905092915050565b60006110ca826111b3565b91506110d5836111b3565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0382111561110a5761110961122f565b5b828201905092915050565b6000611120826111b3565b915061112b836111b3565b92508282101561113e5761113d61122f565b5b828203905092915050565b600061115482611193565b9050919050565b60008115159050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600060ff82169050919050565b60005b838110156111e85780820151818401526020810190506111cd565b838111156111f7576000848401525b50505050565b6000600282049050600182168061121557607f821691505b602082108114156112295761122861125e565b5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000601f19601f8301169050919050565b6112a781611149565b81146112b257600080fd5b50565b6112be81611167565b81146112c957600080fd5b50565b6112d5816111b3565b81146112e057600080fd5b5056fea264697066735822122081dda93f8f62cdd00d5a28d40736a4d2ce80f280f7c878ee8bc8ac6980493dbe64736f6c63430008040033 -\ No newline at end of file +60806040523480156200001157600080fd5b50604051620017f0380380620017f0833981810160405281019062000037919062000269565b336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555082600290805190602001906200008f92919062000124565b508160039080519060200190620000a892919062000124565b5080600460006101000a81548160ff021916908360ff16021790555060018060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550505050620004ae565b8280546200013290620003a5565b90600052602060002090601f016020900481019282620001565760008555620001a2565b82601f106200017157805160ff1916838001178555620001a2565b82800160010185558215620001a2579182015b82811115620001a157825182559160200191906001019062000184565b5b509050620001b19190620001b5565b5090565b5b80821115620001d0576000816000905550600101620001b6565b5090565b6000620001eb620001e5846200032c565b62000303565b9050828152602081018484840111156200020a576200020962000474565b5b620002178482856200036f565b509392505050565b600082601f8301126200023757620002366200046f565b5b815162000249848260208601620001d4565b91505092915050565b600081519050620002638162000494565b92915050565b6000806000606084860312156200028557620002846200047e565b5b600084015167ffffffffffffffff811115620002a657620002a562000479565b5b620002b4868287016200021f565b935050602084015167ffffffffffffffff811115620002d857620002d762000479565b5b620002e6868287016200021f565b9250506040620002f98682870162000252565b9150509250925092565b60006200030f62000322565b90506200031d8282620003db565b919050565b6000604051905090565b600067ffffffffffffffff8211156200034a576200034962000440565b5b620003558262000483565b9050602081019050919050565b600060ff82169050919050565b60005b838110156200038f57808201518184015260208101905062000372565b838111156200039f576000848401525b50505050565b60006002820490506001821680620003be57607f821691505b60208210811415620003d557620003d462000411565b5b50919050565b620003e68262000483565b810181811067ffffffffffffffff8211171562000408576200040762000440565b5b80604052505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b6200049f8162000362565b8114620004ab57600080fd5b50565b61133280620004be6000396000f3fe608060405234801561001057600080fd5b50600436106100ec576000357c010000000000000000000000000000000000000000000000000000000090048063313ce567116100a957806395d89b411161008357806395d89b411461026b578063983b2d5614610289578063a9059cbb146102b9578063dd62ed3e146102e9576100ec565b8063313ce567146101ed578063449a52f81461020b57806370a082311461023b576100ec565b806301ffc9a7146100f157806306fdde0314610121578063095ea7b31461013f57806318160ddd1461016f57806323b872dd1461018d5780633092afd5146101bd575b600080fd5b61010b60048036038101906101069190610fb1565b610319565b6040516101189190611044565b60405180910390f35b61012961041e565b604051610136919061105f565b60405180910390f35b61015960048036038101906101549190610f71565b6104ac565b6040516101669190611044565b60405180910390f35b610177610630565b6040516101849190611081565b60405180910390f35b6101a760048036038101906101a29190610f1e565b610636565b6040516101b49190611044565b60405180910390f35b6101d760048036038101906101d29190610eb1565b610948565b6040516101e49190611044565b60405180910390f35b6101f5610a3a565b604051610202919061109c565b60405180910390f35b61022560048036038101906102209190610f71565b610a4d565b6040516102329190611044565b60405180910390f35b61025560048036038101906102509190610eb1565b610b83565b6040516102629190611081565b60405180910390f35b610273610b9b565b604051610280919061105f565b60405180910390f35b6102a3600480360381019061029e9190610eb1565b610c29565b6040516102b09190611044565b60405180910390f35b6102d360048036038101906102ce9190610f71565b610ce4565b6040516102e09190611044565b60405180910390f35b61030360048036038101906102fe9190610ede565b610e4d565b6040516103109190611081565b60405180910390f35b600063c6bb4b707c010000000000000000000000000000000000000000000000000000000002827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916141561036e5760019050610419565b63449a52f87c010000000000000000000000000000000000000000000000000000000002827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614156103c15760019050610419565b6301ffc9a77c010000000000000000000000000000000000000000000000000000000002827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614156104145760019050610419565b600090505b919050565b6002805461042b90611211565b80601f016020809104026020016040519081016040528092919081815260200182805461045790611211565b80156104a45780601f10610479576101008083540402835291602001916104a4565b820191906000526020600020905b81548152906001019060200180831161048757829003601f168201915b505050505081565b600080821115610540576000600760003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541461053f57600080fd5b5b81600760003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9258460405161061e9190611081565b60405180910390a36001905092915050565b60055481565b600081600760008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205410156106c157600080fd5b81600660008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054101561070d57600080fd5b81600760008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546107959190611129565b600760008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555081600660008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546108649190611129565b9250508190555081600660008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546108ba91906110d3565b925050819055503373ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167f5f7542858008eeb041631f30e6109ae94b83a58e9a58261dd2c42c508850f939856040516109359190611081565b60405180910390a4600190509392505050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806109d057508173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b6109d957600080fd5b6000600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555060019050919050565b600460009054906101000a900460ff1681565b6000600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16610aa557600080fd5b81600660008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254610af491906110d3565b925050819055508160056000828254610b0d91906110d3565b925050819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fab8530f87dc9b59234c4623bf917212bb2536d647574c8e7e5da92c2ede0c9f884604051610b719190611081565b60405180910390a36001905092915050565b60066020528060005260406000206000915090505481565b60038054610ba890611211565b80601f0160208091040260200160405190810160405280929190818152602001828054610bd490611211565b8015610c215780601f10610bf657610100808354040283529160200191610c21565b820191906000526020600020905b815481529060010190602001808311610c0457829003601f168201915b505050505081565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610c8457600080fd5b60018060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555060019050919050565b600081600660003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541015610d3257600080fd5b81600660003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254610d819190611129565b9250508190555081600660008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254610dd791906110d3565b925050819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051610e3b9190611081565b60405180910390a36001905092915050565b6007602052816000526040600020602052806000526040600020600091509150505481565b600081359050610e81816112b7565b92915050565b600081359050610e96816112ce565b92915050565b600081359050610eab816112e5565b92915050565b600060208284031215610ec757610ec66112a1565b5b6000610ed584828501610e72565b91505092915050565b60008060408385031215610ef557610ef46112a1565b5b6000610f0385828601610e72565b9250506020610f1485828601610e72565b9150509250929050565b600080600060608486031215610f3757610f366112a1565b5b6000610f4586828701610e72565b9350506020610f5686828701610e72565b9250506040610f6786828701610e9c565b9150509250925092565b60008060408385031215610f8857610f876112a1565b5b6000610f9685828601610e72565b9250506020610fa785828601610e9c565b9150509250929050565b600060208284031215610fc757610fc66112a1565b5b6000610fd584828501610e87565b91505092915050565b610fe78161116f565b82525050565b6000610ff8826110b7565b61100281856110c2565b93506110128185602086016111de565b61101b816112a6565b840191505092915050565b61102f816111c7565b82525050565b61103e816111d1565b82525050565b60006020820190506110596000830184610fde565b92915050565b600060208201905081810360008301526110798184610fed565b905092915050565b60006020820190506110966000830184611026565b92915050565b60006020820190506110b16000830184611035565b92915050565b600081519050919050565b600082825260208201905092915050565b60006110de826111c7565b91506110e9836111c7565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0382111561111e5761111d611243565b5b828201905092915050565b6000611134826111c7565b915061113f836111c7565b92508282101561115257611151611243565b5b828203905092915050565b6000611168826111a7565b9050919050565b60008115159050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600060ff82169050919050565b60005b838110156111fc5780820151818401526020810190506111e1565b8381111561120b576000848401525b50505050565b6000600282049050600182168061122957607f821691505b6020821081141561123d5761123c611272565b5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600080fd5b6000601f19601f8301169050919050565b6112c08161115d565b81146112cb57600080fd5b50565b6112d78161117b565b81146112e257600080fd5b50565b6112ee816111c7565b81146112f957600080fd5b5056fea264697066735822122025d7f4c78e8965d75a35f7520bb91ec41a9cb560b63fecde62a8939d87c3affb64736f6c63430008060033 +\ No newline at end of file