Esempio n. 1
0
def verify_upgrade_details(blockchain: Union[BlockchainDeployerInterface, BlockchainInterface],
                           registry: LocalContractRegistry,
                           deployer: Type[BaseContractDeployer],
                           ) -> None:
    """
    Compares the versions of two 'implementation' contracts using a local and source registry.
    """

    old_contract: VersionedContract = blockchain.get_contract_by_name(
        registry=registry,
        contract_name=deployer.contract_name,
        proxy_name=deployer.agency._proxy_name,
        use_proxy_address=False
    )

    new_contract = blockchain.find_raw_contract_data(contract_name=deployer.contract_name)
    new_version = new_contract[0]  # Handle index error?

    click.confirm(CONFIRM_VERSIONED_UPGRADE.format(contract_name=deployer.contract_name,
                                                   old_version=old_contract.version,
                                                   new_version=new_version), abort=True)
Esempio n. 2
0
def upgrade(general_config, actor_options, retarget, target_address,
            ignore_deployed, multisig, confirmations):
    """Upgrade NuCypher existing proxy contract deployments."""

    #
    # Setup
    #

    emitter = general_config.emitter
    ADMINISTRATOR, deployer_address, blockchain, local_registry = actor_options.create_actor(
        emitter, is_multisig=bool(
            multisig))  # FIXME: Workaround for building MultiSig TXs | NRN

    contract_name = actor_options.contract_name
    if not contract_name:
        raise click.BadArgumentUsage(
            message="--contract-name is required when using --upgrade")

    github_registry = establish_deployer_registry(
        emitter=emitter, download_registry=True, network=actor_options.network)
    try:
        Deployer = ADMINISTRATOR.deployers[contract_name]
    except KeyError:
        message = UNKNOWN_CONTRACT_NAME.format(
            contract_name=contract_name,
            constants=ADMINISTRATOR.deployers.keys())
        emitter.echo(message, color='red', bold=True)
        raise click.Abort()
    deployer = Deployer(registry=local_registry)

    #
    # Pre-flight
    #

    # Check deployer address is owner
    if Deployer._ownable and deployer_address != deployer.owner:  # blockchain read
        emitter.echo(
            DEPLOYER_IS_NOT_OWNER.format(deployer_address=deployer_address,
                                         contract_name=contract_name,
                                         agent=deployer.make_agent()))
        raise click.Abort()
    else:
        emitter.echo('✓ Verified deployer address as contract owner',
                     color='green')

    # Check registry ID has changed locally compared to remote source
    if (github_registry.id == local_registry.id) and not actor_options.force:
        emitter.echo(IDENTICAL_REGISTRY_WARNING.format(
            github_registry=github_registry, local_registry=local_registry),
                     color='red')
        raise click.Abort()
    else:
        emitter.echo('✓ Verified local registry contains updates',
                     color='green')

    #
    # Business
    #

    if multisig:
        if not target_address:
            raise click.BadArgumentUsage(
                message="--multisig requires using --target-address.")
        if not actor_options.force:
            click.confirm(CONFIRM_BUILD_RETARGET_TRANSACTION.format(
                contract_name=contract_name, target_address=target_address),
                          abort=True)
        transaction = ADMINISTRATOR.retarget_proxy(
            contract_name=contract_name,
            target_address=target_address,
            just_build_transaction=True,
            confirmations=confirmations)

        trustee_address = select_client_account(
            emitter=emitter,
            prompt="Select trustee address",
            provider_uri=actor_options.provider_uri,
            show_eth_balance=False,
            show_nu_balance=False,
            show_staking=False)

        if not actor_options.force:
            click.confirm(
                CONFIRM_SELECTED_ACCOUNT.format(address=trustee_address),
                abort=True)

        trustee = Trustee(registry=local_registry,
                          checksum_address=trustee_address)
        transaction_proposal = trustee.create_transaction_proposal(transaction)

        message = SUCCESSFUL_RETARGET_TX_BUILT.format(
            contract_name=contract_name, target_address=target_address)
        emitter.message(message, color='green')
        paint_multisig_proposed_transaction(
            emitter, transaction_proposal)  # TODO: Show decoded function too

        filepath = f'proposal-{trustee.multisig_agent.contract_address[:8]}-TX-{transaction_proposal.nonce}.json'
        transaction_proposal.write(filepath=filepath)
        emitter.echo(
            SUCCESSFUL_SAVE_MULTISIG_TX_PROPOSAL.format(filepath=filepath),
            color='blue',
            bold=True)

    elif retarget:
        if not target_address:
            raise click.BadArgumentUsage(
                message="--target-address is required when using --retarget")
        if not actor_options.force:
            click.confirm(CONFIRM_RETARGET.format(
                contract_name=contract_name, target_address=target_address),
                          abort=True)
        receipt = ADMINISTRATOR.retarget_proxy(contract_name=contract_name,
                                               target_address=target_address,
                                               confirmations=confirmations)
        message = SUCCESSFUL_RETARGET.format(contract_name=contract_name,
                                             target_address=target_address)
        emitter.message(message, color='green')
        paint_receipt_summary(emitter=emitter, receipt=receipt)

    else:
        if not actor_options.force:
            # Check for human verification of versioned upgrade details
            click.confirm(
                CONFIRM_BEGIN_UPGRADE.format(contract_name=contract_name),
                abort=True)
            if deployer._ownable:  # Only ownable + upgradeable contracts apply
                old_contract = github_registry.search(
                    contract_name=contract_name)[-1]  # latest GH version
                new_contract = local_registry.search(
                    contract_name=contract_name)[-1]  # latest local version
                click.confirm(CONFIRM_VERSIONED_UPGRADE.format(
                    contract_name=contract_name,
                    old_contract=old_contract,
                    new_contract=new_contract),
                              abort=True)

        receipts = ADMINISTRATOR.upgrade_contract(
            contract_name=contract_name,
            ignore_deployed=ignore_deployed,
            confirmations=confirmations)
        emitter.message(SUCCESSFUL_UPGRADE.format(contract_name=contract_name),
                        color='green')
        for name, receipt in receipts.items():
            paint_receipt_summary(emitter=emitter, receipt=receipt)