Пример #1
0
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))
Пример #2
0
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
    ))
Пример #3
0
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)
Пример #4
0
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))
Пример #6
0
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)
Пример #7
0
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)
Пример #8
0
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)
Пример #9
0
 def wrapper():
     chain_name = select_chain(project)
     print("~~{0}~~".format(chain_name))