def deploy_set(context, client, project_dir, data_dir=None, record=True, contracts_by_name=[]): """ Re-Deploy a set of contracts by name or all contracts @param context local context for the attach python interpreter. @param client RPC client for accessing the ethereum chain @param project_dir absolute file path of the project that will be interrogated to determine the contracts that can be deployed @param data_dir directory of the test chain if not None @param contracts_by_name Optional argument, this must be an iterable of strings indicating the names of the contracts to deploy. An empty list deploys all the contracts. """ contracts = package_contracts(utils.load_contracts(project_dir)) deployed_contracts = deploy_contracts( deploy_client=client, contracts=contracts, deploy_at_block=1, max_wait_for_deploy=120, from_address=None, max_wait=120, contracts_to_deploy=contracts_by_name, dependencies=None, constructor_args=None, deploy_gas=None, ) validate_deployed_contracts(client, deployed_contracts) echo_post_deploy_message(client, deployed_contracts) if data_dir is not None and record: add_to_known_contracts(deployed_contracts, data_dir) # Update the attach shell's context with the latest contracts # objects context["contracts"] = contracts if data_dir is not None: setup_known_instances(context, data_dir) return(deployed_contracts)
def contracts(request, populus_config): from populus.utils import load_contracts from populus.contracts import package_contracts project_dir = populus_config.get_value(request, "project_dir") contracts = load_contracts(project_dir) return package_contracts(contracts)
def test_extracting_linker_dependencies(): contracts = package_contracts(load_contracts(project_dir)) linker_deps = get_linker_dependencies(contracts) actual = { "PiggyBank": set(("AccountingLib",)), } assert linker_deps == actual
def test_extracting_linker_dependencies(): contracts = package_contracts(load_contracts(project_dir)) linker_deps = get_linker_dependencies(contracts) actual = { "PiggyBank": set(("AccountingLib", )), } assert linker_deps == actual
def deploy(): """ Deploy contracts. """ contracts = utils.load_contracts(os.getcwd()) client = Client('127.0.0.1', '8545') deployed_contracts = utils.deploy_contracts(client, contracts) name_padding = max(len(n) + 1 for n in deployed_contracts.keys()) for name, info in deployed_contracts.items(): click.echo("{name} @ {addr} via txn:{txn_hash}".format( name=name.ljust(name_padding), addr=(info.get('addr') or '<pending>').ljust(42), txn_hash=info['txn'].ljust(66), ))
def contracts(request, rpc_client): from populus.utils import load_contracts from populus.contracts import Contract project_dir = getattr(request.module, "project_dir", os.getcwd()) contracts = load_contracts(project_dir) contract_classes = { name: Contract(rpc_client, name, contract) for name, contract in contracts.items() } _dict = { '__iter__': lambda s: iter(contract_classes.items()), '__getitem__': lambda s, k: contract_classes.__getitem__[k], } _dict.update(contract_classes) return type('contracts', (object,), _dict)()
def attach(): """ Enter a python shell with contracts and blockchain client available. """ project_dir = os.path.abspath(os.getcwd()) contracts_meta = utils.load_contracts(project_dir) context = { 'contracts': package_contracts(contracts_meta), 'client': Client('127.0.0.1', '8545'), } contract_names = ', '.join(sorted(contracts_meta.keys())) banner = textwrap.dedent( """ Python: {python_version} Populus: v{populus_version} Project Path: {project_dir} contracts -> Contract classes client -> Blockchain client ({client_type}) Contracts: {contracts} """ ).format( python_version=sys.version.partition('\n')[0], populus_version=populus.__version__, project_dir=project_dir, client_type="json-rpc", contracts=click.wrap_text( contract_names, initial_indent='', subsequent_indent=' ' * 4, ), ).strip() if is_ipython: shell = InteractiveConsole(user_ns=context) else: shell = InteractiveConsole(context) shell.interact(banner)
def contracts(request, rpc_client): from populus.utils import load_contracts from populus.contracts import Contract project_dir = getattr(request.module, "project_dir", os.getcwd()) contracts = load_contracts(project_dir) contract_classes = { name: Contract(rpc_client, name, contract) for name, contract in contracts.items() } _dict = { '__iter__': lambda s: iter(contract_classes.items()), '__getitem__': lambda s, k: contract_classes.__getitem__[k], } _dict.update(contract_classes) return type('contracts', (object, ), _dict)()
def test_linking_contract_dependencies(): deployed_addr = '0x3abbae0d139b953491f292dc5c49a350bcb18f8d' contracts = package_contracts(load_contracts(project_dir)) PiggyBank = contracts.PiggyBank ledger_lib = contracts.AccountingLib(deployed_addr, 'PLACEHOLDER') pre_length = len(contracts.PiggyBank._config.code) assert deployed_addr not in PiggyBank._config.code assert '__AccountingLib_________________________' in PiggyBank._config.code link_contract_dependency(PiggyBank, ledger_lib) assert '__AccountingLib_________________________' not in PiggyBank._config.code assert '_' not in PiggyBank._config.code # 0x prefixed version shouldn't be there. assert deployed_addr not in PiggyBank._config.code assert strip_0x_prefix(deployed_addr) in PiggyBank._config.code assert len(contracts.PiggyBank._config.code) == pre_length
def deploy_set(context, client, project_dir, data_dir=None, record=True, contracts_by_name=[]): """ Re-Deploy a set of contracts by name or all contracts @param context local context for the attach python interpreter. @param client RPC client for accessing the ethereum chain @param project_dir absolute file path of the project that will be interrogated to determine the contracts that can be deployed @param data_dir directory of the test chain if not None @param contracts_by_name Optional argument, this must be an iterable of strings indicating the names of the contracts to deploy. An empty list deploys all the contracts. """ contracts = package_contracts(utils.load_contracts(project_dir)) deployed_contracts = deploy_contracts( deploy_client=client, contracts=contracts, deploy_at_block=1, max_wait_for_deploy=120, from_address=None, max_wait=120, contracts_to_deploy=contracts_by_name, dependencies=None, constructor_args=None, deploy_gas=None, ) validate_deployed_contracts(client, deployed_contracts) echo_post_deploy_message(client, deployed_contracts) if data_dir is not None and record: add_to_known_contracts(deployed_contracts, data_dir) # Update the attach shell's context with the latest contracts # objects context["contracts"] = contracts if data_dir is not None: setup_known_instances(context, data_dir) return (deployed_contracts)
def deploy(dry_run, dry_run_chain_name, production, confirm, record, contracts_to_deploy): """ Deploys the specified contracts via the RPC client. """ if dry_run is None: # If we are doing a production deploy and dry_run was not specified, # then default to True dry_run = production client = Client("127.0.0.1", "8545") project_dir = os.getcwd() deploy_gas = None contracts = package_contracts(utils.load_contracts(project_dir)) if dry_run: dry_run_data_dir = get_geth_data_dir(project_dir, dry_run_chain_name) logfile_path = get_geth_logfile_path( dry_run_data_dir, logfile_name_fmt="deploy-dry-run-{0}.log", ) ensure_account_exists(dry_run_data_dir) _, dry_run_proc = run_geth_node(dry_run_data_dir, logfile=logfile_path) wait_for_geth_to_start(dry_run_proc) message = ("======= Executing Dry Run Deploy ========\n" "Chain Name : {chain_name}\n" "Data Directory : {data_dir}\n" "Geth Logfile : {logfile_path}\n\n" "... (deploying)\n").format( chain_name=dry_run_chain_name, data_dir=dry_run_data_dir, logfile_path=logfile_path, ) click.echo(message) # Dry run deploy uses max_gas dry_run_contracts = deploy_contracts( deploy_client=client, contracts=contracts, deploy_at_block=1, max_wait_for_deploy=60, from_address=None, max_wait=60, contracts_to_deploy=contracts_to_deploy, dependencies=None, constructor_args=None, deploy_gas=None, ) validate_deployed_contracts(client, dry_run_contracts) echo_post_deploy_message(client, dry_run_contracts) dry_run_proc.send_signal(signal.SIGINT) # Give the subprocess a SIGINT and give it a few seconds to # cleanup. utils.wait_for_popen(dry_run_proc) def get_deploy_gas(contract_name, contract_class): max_gas = int(client.get_max_gas() * 0.98) receipt = dry_run_contracts._deploy_receipts.get(contract_name) if receipt is None: return max_gas gas_used = int(receipt['gasUsed'], 16) return min(max_gas, int(gas_used * 1.1)) deploy_gas = get_deploy_gas contracts = package_contracts(utils.load_contracts(project_dir)) if not production: data_dir = get_geth_data_dir(project_dir, "default") logfile_path = get_geth_logfile_path( data_dir, logfile_name_fmt="deploy-dry-run-{0}.log", ) ensure_account_exists(data_dir) _, deploy_proc = run_geth_node(data_dir, logfile=logfile_path) wait_for_geth_to_start(deploy_proc) elif confirm: message = ( "You are about to deploy contracts to a production environment. " "You must have an RPC server that is unlocked running for this to " "work.\n\n" "Would you like to proceed?") if not click.confirm(message): raise click.Abort() if not dry_run: message = ( "You are about to do a production deploy with no dry run. Without " "a dry run, it isn't feasible to know gas costs and thus deployment " "may fail due to long transaction times.\n\n" "Are you sure you would like to proceed?") if confirm and not click.confirm(message): raise click.Abort() message = ("========== Executing Deploy ===========\n" "... (deploying)\n" "Chain Name : {chain_name}\n" "Data Directory : {data_dir}\n" "Geth Logfile : {logfile_path}\n\n" "... (deploying)\n").format( chain_name="production" if production else "default", data_dir="N/A" if production else data_dir, logfile_path="N/A" if production else logfile_path, ) click.echo(message) deployed_contracts = deploy_contracts( deploy_client=client, contracts=contracts, deploy_at_block=1, max_wait_for_deploy=120, from_address=None, max_wait=120, contracts_to_deploy=contracts_to_deploy, dependencies=None, constructor_args=None, deploy_gas=deploy_gas, ) validate_deployed_contracts(client, deployed_contracts) echo_post_deploy_message(client, deployed_contracts) if not production: if record: add_to_known_contracts(deployed_contracts, data_dir) deploy_proc.send_signal(signal.SIGINT) # Give the subprocess a SIGINT and give it a few seconds to # cleanup. utils.wait_for_popen(deploy_proc)
def deploy(dry_run, dry_run_chain_name, production, confirm, contracts_to_deploy): """ Deploys the specified contracts via the RPC client. """ if dry_run is None: # If we are doing a production deploy and dry_run was not specified, # then default to True dry_run = production client = Client("127.0.0.1", "8545") project_dir = os.getcwd() deploy_gas = None contracts = package_contracts(utils.load_contracts(project_dir)) if dry_run: dry_run_data_dir = get_geth_data_dir(project_dir, dry_run_chain_name) logfile_path = get_geth_logfile_path( dry_run_data_dir, logfile_name_fmt="deploy-dry-run-{0}.log", ) ensure_account_exists(dry_run_data_dir) _, dry_run_proc = run_geth_node(dry_run_data_dir, logfile=logfile_path) wait_for_geth_to_start(dry_run_proc) message = ( "======= Executing Dry Run Deploy ========\n" "Chain Name : {chain_name}\n" "Data Directory : {data_dir}\n" "Geth Logfile : {logfile_path}\n\n" "... (deploying)\n" ).format( chain_name=dry_run_chain_name, data_dir=dry_run_data_dir, logfile_path=logfile_path, ) click.echo(message) # Dry run deploy uses max_gas dry_run_contracts = deploy_contracts( deploy_client=client, contracts=contracts, deploy_at_block=1, max_wait_for_deploy=60, from_address=None, max_wait=60, contracts_to_deploy=contracts_to_deploy, dependencies=None, constructor_args=None, deploy_gas=None, ) validate_deployed_contracts(client, dry_run_contracts) echo_post_deploy_message(client, dry_run_contracts) dry_run_proc.send_signal(signal.SIGINT) # Give the subprocess a SIGINT and give it a few seconds to # cleanup. utils.wait_for_popen(dry_run_proc) def get_deploy_gas(contract_name, contract_class): max_gas = int(client.get_max_gas() * 0.98) receipt = dry_run_contracts._deploy_receipts.get(contract_name) if receipt is None: return max_gas gas_used = int(receipt['gasUsed'], 16) return min(max_gas, int(gas_used * 1.1)) deploy_gas = get_deploy_gas contracts = package_contracts(utils.load_contracts(project_dir)) if not production: data_dir = get_geth_data_dir(project_dir, "default") logfile_path = get_geth_logfile_path( data_dir, logfile_name_fmt="deploy-dry-run-{0}.log", ) ensure_account_exists(data_dir) _, deploy_proc = run_geth_node(data_dir, logfile=logfile_path) wait_for_geth_to_start(deploy_proc) elif confirm: message = ( "You are about to deploy contracts to a production environment. " "You must have an RPC server that is unlocked running for this to " "work.\n\n" "Would you like to proceed?" ) if not click.confirm(message): raise click.Abort() if not dry_run: message = ( "You are about to do a production deploy with no dry run. Without " "a dry run, it isn't feasible to know gas costs and thus deployment " "may fail due to long transaction times.\n\n" "Are you sure you would like to proceed?" ) if confirm and not click.confirm(message): raise click.Abort() message = ( "========== Executing Deploy ===========\n" "... (deploying)\n" "Chain Name : {chain_name}\n" "Data Directory : {data_dir}\n" "Geth Logfile : {logfile_path}\n\n" "... (deploying)\n" ).format( chain_name="production" if production else "default", data_dir="N/A" if production else data_dir, logfile_path="N/A" if production else logfile_path, ) click.echo(message) deployed_contracts = deploy_contracts( deploy_client=client, contracts=contracts, deploy_at_block=1, max_wait_for_deploy=120, from_address=None, max_wait=120, contracts_to_deploy=contracts_to_deploy, dependencies=None, constructor_args=None, deploy_gas=deploy_gas, ) validate_deployed_contracts(client, deployed_contracts) echo_post_deploy_message(client, deployed_contracts) if not production: deploy_proc.send_signal(signal.SIGINT) # Give the subprocess a SIGINT and give it a few seconds to # cleanup. utils.wait_for_popen(deploy_proc)
def attach(active): """ Enter a python shell with contracts and blockchain client available. """ project_dir = os.path.abspath(os.getcwd()) contracts_meta = utils.load_contracts(project_dir) client = Client('127.0.0.1', '8545') context = { 'contracts': package_contracts(contracts_meta), 'client': client, } data_dir = None if active: data_dir = get_active_data_dir(project_dir) if os.path.islink(data_dir): setup_known_instances(context, data_dir) else: click.echo( click.style("No Valid Active Chain Data Directory Found!", fg="red")) def redeploy(contracts=[], record=True): return (deploy_set(context, client, project_dir, data_dir=data_dir, record=record, contracts_by_name=contracts)) context["redeploy"] = redeploy contract_names = ', '.join(sorted(contracts_meta.keys())) banner = textwrap.dedent(""" Python: {python_version} Populus: v{populus_version} Project Path: {project_dir} contracts -> Contract classes client -> Blockchain client ({client_type}) redeploy -> Method to re-deploy project contracts Example: deployed_cts = redeploy() deployed_cts = redeploy(record = False) deployed_cts = redeploy(contracts = ["Example"]) Contracts: {contracts} Check contracts.<type>.known for deployed contracts. """).format( python_version=sys.version.partition('\n')[0], populus_version=populus.__version__, project_dir=project_dir, client_type="json-rpc", contracts=click.wrap_text( contract_names, initial_indent='', subsequent_indent=' ' * 4, ), ).strip() if is_ipython: shell = InteractiveConsole(user_ns=context) else: shell = InteractiveConsole(context) # Start the active directory link observer event_handler = ActiveDataDirChangedEventHandler( project_dir=project_dir, context=context, ) observer = get_active_dir_observer(project_dir, event_handler) observer.start() shell.interact(banner) observer.stop() observer.join()
def attach(active): """ Enter a python shell with contracts and blockchain client available. """ project_dir = os.path.abspath(os.getcwd()) contracts_meta = utils.load_contracts(project_dir) client = Client('127.0.0.1', '8545') context = { 'contracts': package_contracts(contracts_meta), 'client': client, } data_dir = None if active: data_dir = get_active_data_dir(project_dir) if os.path.islink(data_dir): setup_known_instances(context, data_dir) else: click.echo(click.style("No Valid Active Chain Data Directory Found!", fg="red")) def redeploy(contracts=[], record=True): return(deploy_set( context, client, project_dir, data_dir=data_dir, record=record, contracts_by_name=contracts )) context["redeploy"] = redeploy contract_names = ', '.join(sorted(contracts_meta.keys())) banner = textwrap.dedent( """ Python: {python_version} Populus: v{populus_version} Project Path: {project_dir} contracts -> Contract classes client -> Blockchain client ({client_type}) redeploy -> Method to re-deploy project contracts Example: deployed_cts = redeploy() deployed_cts = redeploy(record = False) deployed_cts = redeploy(contracts = ["Example"]) Contracts: {contracts} Check contracts.<type>.known for deployed contracts. """ ).format( python_version=sys.version.partition('\n')[0], populus_version=populus.__version__, project_dir=project_dir, client_type="json-rpc", contracts=click.wrap_text( contract_names, initial_indent='', subsequent_indent=' ' * 4, ), ).strip() if is_ipython: shell = InteractiveConsole(user_ns=context) else: shell = InteractiveConsole(context) # Start the active directory link observer event_handler = ActiveDataDirChangedEventHandler( project_dir=project_dir, context=context, ) observer = get_active_dir_observer(project_dir, event_handler) observer.start() shell.interact(banner) observer.stop() observer.join()