예제 #1
0
파일: deploy.py 프로젝트: drae12/nucypher
def multisig(general_config, actor_options, action, proposal):
    """
    Perform operations via a MultiSig contract
    """
    # Init
    emitter = general_config.emitter
    _ensure_config_root(actor_options.config_root)
    blockchain = _initialize_blockchain(poa=actor_options.poa,
                                        provider_uri=actor_options.provider_uri,
                                        emitter=emitter,
                                        ignore_solidity_check=actor_options.ignore_solididty_check,
                                        gas_strategy=actor_options.gas_strategy)
    local_registry = establish_deployer_registry(emitter=emitter,
                                                 use_existing_registry=True,
                                                 )

    # Warnings
    # _pre_launch_warnings(emitter, etherscan, hw_wallet)

    multisig_agent = ContractAgency.get_agent(MultiSigAgent,
                                              registry=local_registry,
                                              provider_uri=actor_options.provider_uri)
    token_agent = ContractAgency.get_agent(NucypherTokenAgent, registry=local_registry)

    if action == 'inspect':
        paint_multisig_contract_info(emitter, multisig_agent, token_agent)
    elif action == 'sign':
        if not proposal:
            raise ValueError("multisig sign requires the use of --proposal")

        with open(proposal) as json_file:
            proposal = json.load(json_file)

        executive_summary = proposal['parameters']

        name, version, address, abi = local_registry.search(contract_address=executive_summary['target_address'])
        # TODO: This assumes that we're always signing proxy retargetting. For the moment is true.
        proxy_contract = blockchain.client.w3.eth.contract(abi=abi,
                                                           address=address,
                                                           version=version,
                                                           ContractFactoryClass=blockchain._contract_factory)
        paint_multisig_proposed_transaction(emitter, proposal, proxy_contract)

        click.confirm("Proceed with signing?", abort=True)

        # TODO: Blocked by lack of support to EIP191 - #1566

    elif action == 'execute':
        pass  # TODO
예제 #2
0
파일: deploy.py 프로젝트: drae12/nucypher
    def create_actor(self, emitter):

        _ensure_config_root(self.config_root)
        deployer_interface = _initialize_blockchain(poa=self.poa,
                                                    provider_uri=self.provider_uri,
                                                    emitter=emitter,
                                                    ignore_solidity_check=self.ignore_solidity_check,
                                                    gas_strategy=self.gas_strategy)

        # Warnings
        _pre_launch_warnings(emitter, self.etherscan, self.hw_wallet)

        #
        # Establish Registry
        #
        local_registry = establish_deployer_registry(emitter=emitter,
                                                     use_existing_registry=bool(self.contract_name),
                                                     registry_infile=self.registry_infile,
                                                     registry_outfile=self.registry_outfile,
                                                     dev=self.dev)
        #
        # Make Authenticated Deployment Actor
        #
        # Verify Address & collect password
        deployer_address = self.deployer_address
        if not deployer_address:
            prompt = "Select deployer account"
            deployer_address = select_client_account(emitter=emitter,
                                                     prompt=prompt,
                                                     provider_uri=self.provider_uri,
                                                     show_balances=False)

        if not self.force:
            click.confirm("Selected {} - Continue?".format(deployer_address), abort=True)

        password = None
        if not self.hw_wallet and not deployer_interface.client.is_local:
            password = get_client_password(checksum_address=deployer_address)
        # Produce Actor
        ADMINISTRATOR = ContractAdministrator(registry=local_registry,
                                              client_password=password,
                                              deployer_address=deployer_address,
                                              staking_escrow_test_mode=self.se_test_mode)
        # Verify ETH Balance
        emitter.echo(f"\n\nDeployer ETH balance: {ADMINISTRATOR.eth_balance}")
        if ADMINISTRATOR.eth_balance == 0:
            emitter.echo("Deployer address has no ETH.", color='red', bold=True)
            raise click.Abort()
        return ADMINISTRATOR, deployer_address, deployer_interface, local_registry
예제 #3
0
def inspect(general_config, provider_uri, config_root, registry_infile, deployer_address, poa):
    """
    Echo owner information and bare contract metadata.
    """
    # Init
    emitter = general_config.emitter
    _ensure_config_root(config_root)
    _initialize_blockchain(poa, provider_uri, emitter)

    local_registry = establish_deployer_registry(emitter=emitter,
                                                 registry_infile=registry_infile,
                                                 download_registry=not bool(registry_infile))
    paint_deployer_contract_inspection(emitter=emitter,
                                       registry=local_registry,
                                       deployer_address=deployer_address)
예제 #4
0
파일: deploy.py 프로젝트: gs455/nucypher
def _make_authenticated_deployment_actor(emitter, provider_uri,
                                         deployer_address, deployer_interface,
                                         contract_name, registry_infile,
                                         registry_outfile, hw_wallet, dev,
                                         force, se_test_mode):
    #
    # Establish Registry
    #
    local_registry = establish_deployer_registry(
        emitter=emitter,
        use_existing_registry=bool(contract_name),
        registry_infile=registry_infile,
        registry_outfile=registry_outfile,
        dev=dev)
    #
    # Make Authenticated Deployment Actor
    #
    # Verify Address & collect password
    if not deployer_address:
        prompt = "Select deployer account"
        deployer_address = select_client_account(emitter=emitter,
                                                 prompt=prompt,
                                                 provider_uri=provider_uri,
                                                 show_balances=False)
    if not force:
        click.confirm("Selected {} - Continue?".format(deployer_address),
                      abort=True)
    password = None
    if not hw_wallet and not deployer_interface.client.is_local:
        password = get_client_password(checksum_address=deployer_address)
    # Produce Actor
    ADMINISTRATOR = ContractAdministrator(
        registry=local_registry,
        client_password=password,
        deployer_address=deployer_address,
        staking_escrow_test_mode=se_test_mode)
    # Verify ETH Balance
    emitter.echo(f"\n\nDeployer ETH balance: {ADMINISTRATOR.eth_balance}")
    if ADMINISTRATOR.eth_balance == 0:
        emitter.echo("Deployer address has no ETH.", color='red', bold=True)
        raise click.Abort()
    return ADMINISTRATOR, deployer_address, local_registry
예제 #5
0
def deploy(action, poa, etherscan, provider_uri, gas, deployer_address,
           contract_name, allocation_infile, allocation_outfile,
           registry_infile, registry_outfile, value, target_address, retarget,
           bare, config_root, hw_wallet, force, dev):
    """
    Manage contract and registry deployment.

    \b
    Actions
    -----------------------------------------------------------------------------
    contracts              Compile and deploy contracts.
    allocations            Deploy pre-allocation contracts.
    upgrade                Upgrade NuCypher existing proxy contract deployments.
    rollback               Rollback a proxy contract's target.
    inspect                Echo owner information and bare contract metadata.
    transfer-tokens        Transfer tokens from a contract to another address using the owner's address.
    transfer-ownership     Transfer ownership of contracts to another address.
    """

    emitter = StdoutEmitter()

    #
    # Validate
    #

    # Ensure config root exists, because we need a default place to put output files.
    config_root = config_root or DEFAULT_CONFIG_ROOT
    if not os.path.exists(config_root):
        os.makedirs(config_root)

    #
    # Pre-Launch Warnings
    #

    if not hw_wallet:
        emitter.echo("WARNING: --no-hw-wallet is enabled.", color='yellow')

    if etherscan:
        emitter.echo(
            "WARNING: --etherscan is enabled. "
            "A browser tab will be opened with deployed contracts and TXs as provided by Etherscan.",
            color='yellow')
    else:
        emitter.echo(
            "WARNING: --etherscan is disabled. "
            "If you want to see deployed contracts and TXs in your browser, activate --etherscan.",
            color='yellow')

    if action == "download-registry":
        if not force:
            prompt = f"Fetch and download latest registry from {BaseContractRegistry.PUBLICATION_ENDPOINT}?"
            click.confirm(prompt, abort=True)
        registry = InMemoryContractRegistry.from_latest_publication()
        output_filepath = registry.commit(filepath=registry_outfile,
                                          overwrite=force)
        emitter.message(
            f"Successfully downloaded latest registry to {output_filepath}")
        return  # Exit

    #
    # Connect to Blockchain
    #

    if not provider_uri:
        raise click.BadOptionUsage(
            message=f"--provider is required to deploy.",
            option_name="--provider")

    if not BlockchainInterfaceFactory.is_interface_initialized(
            provider_uri=provider_uri):
        # Note: For test compatibility.
        deployer_interface = BlockchainDeployerInterface(
            provider_uri=provider_uri, poa=poa)
        BlockchainInterfaceFactory.register_interface(
            interface=deployer_interface, sync=False, show_sync_progress=False)
    else:
        deployer_interface = BlockchainInterfaceFactory.get_interface(
            provider_uri=provider_uri)

    if action == "inspect":
        if registry_infile:
            registry = LocalContractRegistry(filepath=registry_infile)
        else:
            registry = InMemoryContractRegistry.from_latest_publication()
        administrator = ContractAdministrator(
            registry=registry, deployer_address=deployer_address)
        paint_deployer_contract_inspection(emitter=emitter,
                                           administrator=administrator)
        return  # Exit

    #
    # Establish Registry
    #
    local_registry = establish_deployer_registry(
        emitter=emitter,
        use_existing_registry=bool(contract_name),
        registry_infile=registry_infile,
        registry_outfile=registry_outfile,
        dev=dev)

    #
    # Make Authenticated Deployment Actor
    #

    # Verify Address & collect password
    if not deployer_address:
        prompt = "Select deployer account"
        deployer_address = select_client_account(emitter=emitter,
                                                 prompt=prompt,
                                                 provider_uri=provider_uri,
                                                 show_balances=False)

    if not force:
        click.confirm("Selected {} - Continue?".format(deployer_address),
                      abort=True)

    password = None
    if not hw_wallet and not deployer_interface.client.is_local:
        password = get_client_password(checksum_address=deployer_address)

    # Produce Actor
    ADMINISTRATOR = ContractAdministrator(registry=local_registry,
                                          client_password=password,
                                          deployer_address=deployer_address)

    # Verify ETH Balance
    emitter.echo(f"\n\nDeployer ETH balance: {ADMINISTRATOR.eth_balance}")
    if ADMINISTRATOR.eth_balance == 0:
        emitter.echo("Deployer address has no ETH.", color='red', bold=True)
        raise click.Abort()

    #
    # Action switch
    #

    if action == 'upgrade':
        if not contract_name:
            raise click.BadArgumentUsage(
                message="--contract-name is required when using --upgrade")
        existing_secret = click.prompt(
            'Enter existing contract upgrade secret', hide_input=True)
        new_secret = click.prompt('Enter new contract upgrade secret',
                                  hide_input=True,
                                  confirmation_prompt=True)

        if retarget:
            if not target_address:
                raise click.BadArgumentUsage(
                    message="--target-address is required when using --retarget"
                )
            if not force:
                click.confirm(
                    f"Confirm re-target {contract_name}'s proxy to {target_address}?",
                    abort=True)
            receipt = ADMINISTRATOR.retarget_proxy(
                contract_name=contract_name,
                target_address=target_address,
                existing_plaintext_secret=existing_secret,
                new_plaintext_secret=new_secret)
            emitter.message(
                f"Successfully re-targeted {contract_name} proxy to {target_address}",
                color='green')
            paint_receipt_summary(emitter=emitter, receipt=receipt)
            return  # Exit
        else:
            if not force:
                click.confirm(
                    f"Confirm deploy new version of {contract_name} and retarget proxy?",
                    abort=True)
            receipts = ADMINISTRATOR.upgrade_contract(
                contract_name=contract_name,
                existing_plaintext_secret=existing_secret,
                new_plaintext_secret=new_secret)
            emitter.message(
                f"Successfully deployed and upgraded {contract_name}",
                color='green')
            for name, receipt in receipts.items():
                paint_receipt_summary(emitter=emitter, receipt=receipt)
            return  # Exit

    elif action == 'rollback':
        if not contract_name:
            raise click.BadArgumentUsage(
                message="--contract-name is required when using --rollback")
        existing_secret = click.prompt(
            'Enter existing contract upgrade secret', hide_input=True)
        new_secret = click.prompt('Enter new contract upgrade secret',
                                  hide_input=True,
                                  confirmation_prompt=True)
        ADMINISTRATOR.rollback_contract(
            contract_name=contract_name,
            existing_plaintext_secret=existing_secret,
            new_plaintext_secret=new_secret)
        return  # Exit

    elif action == "contracts":

        #
        # Deploy Single Contract (Amend Registry)
        #

        if contract_name:
            try:
                contract_deployer = ADMINISTRATOR.deployers[contract_name]
            except KeyError:
                message = f"No such contract {contract_name}. Available contracts are {ADMINISTRATOR.deployers.keys()}"
                emitter.echo(message, color='red', bold=True)
                raise click.Abort()

            # Deploy
            emitter.echo(f"Deploying {contract_name}")
            if contract_deployer._upgradeable and not bare:
                # NOTE: Bare deployments do not engage the proxy contract
                secret = ADMINISTRATOR.collect_deployment_secret(
                    deployer=contract_deployer)
                receipts, agent = ADMINISTRATOR.deploy_contract(
                    contract_name=contract_name,
                    plaintext_secret=secret,
                    gas_limit=gas,
                    bare=bare)
            else:
                # Non-Upgradeable or Bare
                receipts, agent = ADMINISTRATOR.deploy_contract(
                    contract_name=contract_name, gas_limit=gas, bare=bare)

            # Report
            paint_contract_deployment(
                contract_name=contract_name,
                contract_address=agent.contract_address,
                receipts=receipts,
                emitter=emitter,
                chain_name=deployer_interface.client.chain_name,
                open_in_browser=etherscan)
            return  # Exit

        #
        # Deploy Automated Series (Create Registry)
        #

        # Confirm filesystem registry writes.
        if os.path.isfile(local_registry.filepath):
            emitter.echo(
                f"\nThere is an existing contract registry at {local_registry.filepath}.\n"
                f"Did you mean 'nucypher-deploy upgrade'?\n",
                color='yellow')
            click.confirm("*DESTROY* existing local registry and continue?",
                          abort=True)
            os.remove(local_registry.filepath)

        # Stage Deployment
        secrets = ADMINISTRATOR.collect_deployment_secrets()
        paint_staged_deployment(deployer_interface=deployer_interface,
                                administrator=ADMINISTRATOR,
                                emitter=emitter)

        # Confirm Trigger Deployment
        if not confirm_deployment(emitter=emitter,
                                  deployer_interface=deployer_interface):
            raise click.Abort()

        # Delay - Last chance to abort via KeyboardInterrupt
        paint_deployment_delay(emitter=emitter)

        # Execute Deployment
        deployment_receipts = ADMINISTRATOR.deploy_network_contracts(
            secrets=secrets,
            emitter=emitter,
            interactive=not force,
            etherscan=etherscan)

        # Paint outfile paths
        registry_outfile = local_registry.filepath
        emitter.echo('Generated registry {}'.format(registry_outfile),
                     bold=True,
                     color='blue')

        # Save transaction metadata
        receipts_filepath = ADMINISTRATOR.save_deployment_receipts(
            receipts=deployment_receipts)
        emitter.echo(f"Saved deployment receipts to {receipts_filepath}",
                     color='blue',
                     bold=True)
        return  # Exit

    elif action == "allocations":
        if not allocation_infile:
            allocation_infile = click.prompt("Enter allocation data filepath")
        click.confirm("Continue deploying and allocating?", abort=True)
        ADMINISTRATOR.deploy_beneficiaries_from_file(
            allocation_data_filepath=allocation_infile,
            allocation_outfile=allocation_outfile)
        return  # Exit

    elif action == "transfer-tokens":
        token_agent = ContractAgency.get_agent(NucypherTokenAgent,
                                               registry=local_registry)
        if not target_address:
            target_address = click.prompt("Enter recipient's checksum address",
                                          type=EIP55_CHECKSUM_ADDRESS)
        if not value:
            stake_value_range = click.FloatRange(min=0, clamp=False)
            value = NU.from_tokens(
                click.prompt(f"Enter value in NU", type=stake_value_range))

        click.confirm(
            f"Transfer {value} from {deployer_address} to {target_address}?",
            abort=True)
        receipt = token_agent.transfer(amount=value,
                                       sender_address=deployer_address,
                                       target_address=target_address)
        emitter.echo(f"OK | Receipt: {receipt['transactionHash'].hex()}")
        return  # Exit

    elif action == "transfer-ownership":
        if not target_address:
            target_address = click.prompt("Enter new owner's checksum address",
                                          type=EIP55_CHECKSUM_ADDRESS)

        if contract_name:
            try:
                contract_deployer_class = ADMINISTRATOR.deployers[
                    contract_name]
            except KeyError:
                message = f"No such contract {contract_name}. Available contracts are {ADMINISTRATOR.deployers.keys()}"
                emitter.echo(message, color='red', bold=True)
                raise click.Abort()
            else:
                contract_deployer = contract_deployer_class(
                    registry=ADMINISTRATOR.registry,
                    deployer_address=ADMINISTRATOR.deployer_address)
                receipt = contract_deployer.transfer_ownership(
                    new_owner=target_address, transaction_gas_limit=gas)
                emitter.ipc(receipt, request_id=0, duration=0)  # TODO: #1216
                return  # Exit
        else:
            receipts = ADMINISTRATOR.relinquish_ownership(
                new_owner=target_address, transaction_gas_limit=gas)
            emitter.ipc(receipts, request_id=0, duration=0)  # TODO: #1216
            return  # Exit

    else:
        raise click.BadArgumentUsage(message=f"Unknown action '{action}'")