def chain_init(ctx, chain_name): """ Prepare the current chain for migrations. contract onto this chain as well as """ project = ctx.obj['PROJECT'] ensure_path_exists(project.migrations_dir) # Determine which chain should be used. if not chain_name: chain_name = select_chain(project) chain_section_name = "chain:{0}".format(chain_name) if chain_name == 'testrpc': ctx.abort("Cannot initialize the {0!r} chain".format(chain_name)) # The `mainnet` and `morden` chains have default configurations. If the # user is working on one of these chains then we need to add the section # header so that we can write new config to it. if not project.config.has_section(chain_section_name): project.config.add_section(chain_section_name) chain = project.get_chain(chain_name) if 'registrar' not in chain.chain_config: # We need to deploy the registrar with chain: web3 = chain.web3 if chain_name in {'mainnet', 'morden'}: show_chain_sync_progress(chain) account = get_unlocked_deploy_from_address(chain) # Configure web3 to now send from our chosen account by default web3.eth.defaultAccount = account # Deploy the registrar RegistrarFactory = chain.RegistrarFactory registrar = deploy_contract_and_verify( chain, contract_name='Registrar', base_contract_factory=RegistrarFactory) # TODO: set the value in the registrar. # Write the registrar address to the chain config project.config.set(chain_section_name, 'registrar', registrar.address) config_file_path = project.write_config() click.echo("Wrote updated chain configuration to {0!r}".format( config_file_path, )) click.echo( "The '{0}' blockchain is ready for migrations.".format(chain_name))
def chain_init(ctx, chain_name): """ Prepare the current chain for migrations. contract onto this chain as well as """ project = ctx.obj['PROJECT'] ensure_path_exists(project.migrations_dir) # Determine which chain should be used. if not chain_name: chain_name = select_chain(project) chain_section_name = "chain:{0}".format(chain_name) if chain_name == 'testrpc': ctx.abort("Cannot initialize the {0!r} chain".format(chain_name)) # The `mainnet` and `morden` chains have default configurations. If the # user is working on one of these chains then we need to add the section # header so that we can write new config to it. if not project.config.has_section(chain_section_name): project.config.add_section(chain_section_name) chain = project.get_chain(chain_name) if 'registrar' not in chain.chain_config: # We need to deploy the registrar with chain: web3 = chain.web3 if chain_name in {'mainnet', 'morden'}: show_chain_sync_progress(chain) account = get_unlocked_deploy_from_address(chain) # Configure web3 to now send from our chosen account by default web3.eth.defaultAccount = account # Deploy the registrar RegistrarFactory = chain.RegistrarFactory registrar = deploy_contract_and_verify(chain, contract_name='Registrar', base_contract_factory=RegistrarFactory) # TODO: set the value in the registrar. # Write the registrar address to the chain config project.config.set(chain_section_name, 'registrar', registrar.address) config_file_path = project.write_config() click.echo("Wrote updated chain configuration to {0!r}".format( config_file_path, )) click.echo("The '{0}' blockchain is ready for migrations.".format( chain_name ))
def deploy(project, logger, chain_name, wait_for_sync, contracts_to_deploy): """ Deploys the specified contracts to a chain. """ # Determine which chain should be used. if not chain_name: chain_name = select_chain(project) compiled_contracts = project.compiled_contract_data if contracts_to_deploy: # validate that we *know* about all of the contracts unknown_contracts = set(contracts_to_deploy).difference( compiled_contracts.keys() ) if unknown_contracts: unknown_contracts_message = ( "Some contracts specified for deploy were not found in the " "compiled project contracts. These contracts could not be found " "'{0}'. Searched these known contracts '{1}'".format( ', '.join(sorted(unknown_contracts)), ', '.join(compiled_contracts.keys()), ) ) raise click.ClickException(unknown_contracts_message) else: # prompt the user to select the desired contracts they want to deploy. # Potentially display the currently deployed status. contracts_to_deploy = [select_project_contract(project)] with project.get_chain(chain_name) as chain: provider = chain.provider registrar = chain.registrar # wait for the chain to start syncing. if wait_for_sync: logger.info("Waiting for chain to start syncing....") while chain.wait.for_syncing() and is_synced(chain.web3): time.sleep(1) logger.info("Chain sync complete") # Get the deploy order. deploy_order = get_deploy_order( contracts_to_deploy, compiled_contracts, ) # Display Start Message Info. starting_msg = ( "Beginning contract deployment. Deploying {0} total contracts ({1} " "Specified, {2} because of library dependencies)." "\n\n" + (" > ".join(deploy_order)) ).format( len(deploy_order), len(contracts_to_deploy), len(deploy_order) - len(contracts_to_deploy), ) logger.info(starting_msg) for contract_name in deploy_order: if not provider.are_contract_dependencies_available(contract_name): raise ValueError( "Something is wrong with the deploy order. Some " "dependencies for {0} are not " "available.".format(contract_name) ) # Check if we already have an existing deployed version of that # contract (via the registry). For each of these, prompt the user # if they would like to use the existing version. if provider.is_contract_available(contract_name): # TODO: this block should be a standalone cli util. # TODO: this block needs to use the `Provider` API existing_contract_instance = provider.get_contract(contract_name) found_existing_contract_prompt = ( "Found existing version of {name} in registrar. " "Would you like to use the previously deployed " "contract @ {address}?".format( name=contract_name, address=existing_contract_instance.address, ) ) if click.prompt(found_existing_contract_prompt, default=True): continue # We don't have an existing version of this contract available so # deploy it. contract_instance = deploy_contract_and_verify( chain, contract_name=contract_name, ) # Store the contract address for linking of subsequent deployed contracts. registrar.set_contract_address(contract_name, contract_instance.address) # TODO: fix this message. success_msg = ( "Deployment Successful." ) logger.info(success_msg)
def migrate(ctx, chain_name): """ Run project migrations """ project = ctx.obj['PROJECT'] if not project.migrations: raise click.ClickException(( "The project does not appear to have any migrations. You can use " "the `populus makemigration` command to generate project migrations" )) # Validate the project migrations validate_migration_classes(project.migrations) # Determine which chain should be used. if not chain_name: chain_name = select_chain(project) chain_config = project.config.chains[chain_name] # Determine if the chain is *migratable* if 'registrar' not in chain_config: # TODO: this should be a property of the chain object itself. # Something like `chain.is_ready_for_migrations`. if chain_name not in {'testrpc', 'temp'}: # ignore `testrpc` and `temp` because they lazily create their # registrar contracts. # TODO: We can present the use with the option to just initialize # the chain right here rather than throwing an error. initialize_chain_prompt = ( "The chain '{0}' is not configured with a registrar contract " "address. Would you like to deploy one now?".format( chain_name, ) ) if click.confirm(initialize_chain_prompt, default=True): from .chain_cmd import chain_init ctx.invoke(chain_init, chain_name=chain_name) else: no_registrar_message = ( "In order to use the migrations functionality, a registrar " "contract is required. You can initialize this chain with a " "registrar using the command `$ populus chain init " "{name}`".format(name=chain_name) ) click.echo(no_registrar_message, err=True) click.exit(1) with project.get_chain(chain_name) as chain: if chain_name in {'mainnet', 'morden'}: show_chain_sync_progress(chain) account = get_unlocked_deploy_from_address(chain) chain.web3.eth.defaultAccount = account # Wait for chain sync if this is a public network. if chain_name in {'mainnet', 'morden'}: show_chain_sync_progress(chain) # Determine if we have any migrations to run. migrations_to_execute = get_migration_classes_for_execution( project.migrations, chain, ) if not migrations_to_execute: click.echo("All migrations have been run.") ctx.exit(0) click.echo("Migration operations to perform:") for migration in migrations_to_execute: click.echo(''.join(( " ", migration.migration_id, " ({0} operations)".format(len(migration.operations)), ":", ))) for operation_index, operation in enumerate(migration.operations): click.echo(''.join(( " ", str(operation_index), " - ", str(operation), ))) click.echo("Executing migrations:") for migration in migrations_to_execute: click.echo(''.join(( " ", migration.migration_id, "... ", )), nl=False) migration.execute() click.echo(" DONE")
def wrapper(): chain_name = select_chain(project) print("~~{0}~~".format(chain_name))
def deploy(ctx, chain_name, contracts_to_deploy): """ Deploys the specified contracts to a chain. """ project = ctx.obj['PROJECT'] # Determine which chain should be used. if not chain_name: chain_name = select_chain(project) compiled_contracts = project.compiled_contracts if contracts_to_deploy: # validate that we *know* about all of the contracts unknown_contracts = set(contracts_to_deploy).difference( compiled_contracts.keys()) if unknown_contracts: unknown_contracts_message = ( "Some contracts specified for deploy were not found in the " "compiled project contracts. These contracts could not be found " "'{0}'. Searched these known contracts '{1}'".format( ', '.join(sorted(unknown_contracts)), ', '.join(sorted(compiled_contracts.keys())), )) raise click.ClickException(unknown_contracts_message) else: # prompt the user to select the desired contracts they want to deploy. # Potentially display the currently deployed status. contracts_to_deploy = [select_project_contract(project)] chain = project.get_chain(chain_name) deployed_contracts = OrderedDict() with chain: if chain_name in {'mainnet', 'morden'}: show_chain_sync_progress(chain) # Get the deploy order. deploy_order = get_deploy_order( contracts_to_deploy, compiled_contracts, ) # Display Start Message Info. starting_msg = ( "Beginning contract deployment. Deploying {0} total contracts ({1} " "Specified, {2} because of library dependencies)." "\n\n" + (" > ".join(deploy_order.keys()))).format( len(deploy_order), len(contracts_to_deploy), len(deploy_order) - len(contracts_to_deploy), ) click.echo(starting_msg) for contract_name, _ in deploy_order.items(): link_dependencies = { contract_name: contract.address for contract_name, contract in deployed_contracts.items() } contract_factory = chain.contract_factories[contract_name] # Check if we already have an existing deployed version of that # contract (via the registry). For each of these, prompt the user # if they would like to use the existing version. if contract_name not in contracts_to_deploy and chain.has_registrar: # TODO: this block should be a standalone cli util. existing_contract = get_contract_from_registrar( chain=chain, contract_name=contract_name, contract_factory=contract_factory, link_dependencies=link_dependencies, ) if existing_contract: found_existing_contract_prompt = ( "Found existing version of {name} in registrar. " "Would you like to use the previously deployed " "contract @ {address}?".format( name=contract_name, address=existing_contract.address, )) if click.prompt(found_existing_contract_prompt): deployed_contracts[contract_name] = existing_contract continue # We don't have an existing version of this contract available so # deploy it. contract = deploy_contract_and_verify( chain, contract_name=contract_name, link_dependencies=link_dependencies, ) if chain.has_registrar: # TODO: this block should be a standalone cli util. contract_key = 'contract/{name}'.format(name=contract_name) register_txn_hash = chain.registrar.transact().setAddress( contract_key, contract.address) register_msg = ("Registering contract '{name}' @ {address} " "in registrar in txn: {txn_hash} ...".format( name=contract_name, address=contract.address, txn_hash=register_txn_hash, )) click.echo(register_msg, nl=False) chain.wait.for_receipt(register_txn_hash, timeout=180) click.echo(' DONE') deployed_contracts[contract_name] = contract # TODO: fix this message. success_msg = ("Deployment Successful.") click.echo(success_msg)
def deploy(ctx, chain_name, deploy_from, contracts_to_deploy): """ Deploys the specified contracts to a chain. """ project = ctx.obj['PROJECT'] # Determine which chain should be used. if not chain_name: chain_name = select_chain(project) compiled_contracts = project.compiled_contracts if contracts_to_deploy: # validate that we *know* about all of the contracts unknown_contracts = set(contracts_to_deploy).difference( compiled_contracts.keys() ) if unknown_contracts: unknown_contracts_message = ( "Some contracts specified for deploy were not found in the " "compiled project contracts. These contracts could not be found " "'{0}'. Searched these known contracts '{1}'".format( ', '.join(sorted(unknown_contracts)), ', '.join(sorted(compiled_contracts.keys())), ) ) raise click.ClickException(unknown_contracts_message) else: # prompt the user to select the desired contracts they want to deploy. # Potentially display the currently deployed status. contracts_to_deploy = [select_project_contract(project)] chain = project.get_chain(chain_name) deployed_contracts = OrderedDict() with chain: web3 = chain.web3 if chain_name in {'mainnet', 'morden'}: show_chain_sync_progress(chain) if deploy_from is None: deploy_from = get_unlocked_deploy_from_address(chain) elif deploy_from not in web3.eth.accounts: try: deploy_from = web3.eth.accounts[int(deploy_from)] except IndexError: raise click.ClickException( "Unknown deploy_from account: {0}".format(deploy_from) ) web3.eth.defaultAccount = deploy_from # Get the deploy order. deploy_order = get_deploy_order( contracts_to_deploy, compiled_contracts, ) # Display Start Message Info. starting_msg = ( "Beginning contract deployment. Deploying {0} total contracts ({1} " "Specified, {2} because of library dependencies)." "\n\n" + (" > ".join(deploy_order.keys())) ).format( len(deploy_order), len(contracts_to_deploy), len(deploy_order) - len(contracts_to_deploy), ) click.echo(starting_msg) for contract_name, _ in deploy_order.items(): link_dependencies = { contract_name: contract.address for contract_name, contract in deployed_contracts.items() } contract_factory = chain.contract_factories[contract_name] # Check if we already have an existing deployed version of that # contract (via the registry). For each of these, prompt the user # if they would like to use the existing version. if contract_name not in contracts_to_deploy and chain.has_registrar: # TODO: this block should be a standalone cli util. existing_contract = get_contract_from_registrar( chain=chain, contract_name=contract_name, contract_factory=contract_factory, link_dependencies=link_dependencies, ) if existing_contract: found_existing_contract_prompt = ( "Found existing version of {name} in registrar. " "Would you like to use the previously deployed " "contract @ {address}?".format( name=contract_name, address=existing_contract.address, ) ) if click.prompt(found_existing_contract_prompt): deployed_contracts[contract_name] = existing_contract continue # We don't have an existing version of this contract available so # deploy it. contract = deploy_contract_and_verify( chain, contract_name=contract_name, link_dependencies=link_dependencies, ) if chain.has_registrar: # TODO: this block should be a standalone cli util. contract_key = 'contract/{name}'.format(name=contract_name) register_txn_hash = chain.registrar.transact().setAddress( contract_key, contract.address ) register_msg = ( "Registering contract '{name}' @ {address} " "in registrar in txn: {txn_hash} ...".format( name=contract_name, address=contract.address, txn_hash=register_txn_hash, ) ) click.echo(register_msg, nl=False) chain.wait.for_receipt(register_txn_hash, timeout=180) click.echo(' DONE') deployed_contracts[contract_name] = contract # TODO: fix this message. success_msg = ( "Deployment Successful." ) click.echo(success_msg)
def deploy(project, logger, chain_name, wait_for_sync, contracts_to_deploy): """ Deploys the specified contracts to a chain. """ # Determine which chain should be used. if not chain_name: chain_name = select_chain(project) compiled_contracts = project.compiled_contract_data if contracts_to_deploy: # validate that we *know* about all of the contracts unknown_contracts = set(contracts_to_deploy).difference( compiled_contracts.keys()) if unknown_contracts: unknown_contracts_message = ( "Some contracts specified for deploy were not found in the " "compiled project contracts. These contracts could not be found " "'{0}'. Searched these known contracts '{1}'".format( ', '.join(sorted(unknown_contracts)), ', '.join(compiled_contracts.keys()), )) raise click.ClickException(unknown_contracts_message) else: # prompt the user to select the desired contracts they want to deploy. # Potentially display the currently deployed status. contracts_to_deploy = [select_project_contract(project)] with project.get_chain(chain_name) as chain: provider = chain.provider registrar = chain.registrar # wait for the chain to start syncing. if wait_for_sync: logger.info("Waiting for chain to start syncing....") while chain.wait.for_syncing() and is_synced(chain.web3): time.sleep(1) logger.info("Chain sync complete") # Get the deploy order. deploy_order = get_deploy_order( contracts_to_deploy, compiled_contracts, ) # Display Start Message Info. starting_msg = ( "Beginning contract deployment. Deploying {0} total contracts ({1} " "Specified, {2} because of library dependencies)." "\n\n" + (" > ".join(deploy_order))).format( len(deploy_order), len(contracts_to_deploy), len(deploy_order) - len(contracts_to_deploy), ) logger.info(starting_msg) for contract_name in deploy_order: if not provider.are_contract_dependencies_available(contract_name): raise ValueError( "Something is wrong with the deploy order. Some " "dependencies for {0} are not " "available.".format(contract_name)) # Check if we already have an existing deployed version of that # contract (via the registry). For each of these, prompt the user # if they would like to use the existing version. if provider.is_contract_available(contract_name): # TODO: this block should be a standalone cli util. # TODO: this block needs to use the `Provider` API existing_contract_instance = provider.get_contract( contract_name) found_existing_contract_prompt = ( "Found existing version of {name} in registrar. " "Would you like to use the previously deployed " "contract @ {address}?".format( name=contract_name, address=existing_contract_instance.address, )) if click.prompt(found_existing_contract_prompt, default=True): continue # We don't have an existing version of this contract available so # deploy it. contract_instance = deploy_contract_and_verify( chain, contract_name=contract_name, ) # Store the contract address for linking of subsequent deployed contracts. registrar.set_contract_address(contract_name, contract_instance.address) # TODO: fix this message. success_msg = ("Deployment Successful.") logger.info(success_msg)