コード例 #1
0
ファイル: deploy.py プロジェクト: y3v63n/nucypher
def upgrade(general_config, actor_options, retarget, target_address, ignore_deployed, multisig):
    """
    Upgrade NuCypher existing proxy contract deployments.
    """
    # Init
    emitter = general_config.emitter

    ADMINISTRATOR, _, _, registry = actor_options.create_actor(emitter, is_multisig=bool(multisig))  # FIXME: Workaround for building MultiSig TXs

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

    if multisig:
        if not target_address:
            raise click.BadArgumentUsage(message="--multisig requires using --target-address.")
        if not actor_options.force:
            click.confirm(f"Confirm building a re-target transaction for {contract_name}'s proxy to {target_address}?",
                          abort=True)
        transaction = ADMINISTRATOR.retarget_proxy(contract_name=contract_name,
                                                   target_address=target_address,
                                                   just_build_transaction=True)

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

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

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

        emitter.message(f"Transaction to retarget {contract_name} proxy to {target_address} was built:", 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(f"Saved proposal to {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(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)
        emitter.message(f"Successfully re-targeted {contract_name} proxy to {target_address}", color='green')
        paint_receipt_summary(emitter=emitter, receipt=receipt)
    else:
        if not actor_options.force:
            click.confirm(f"Confirm deploy new version of {contract_name} and retarget proxy?", abort=True)
        receipts = ADMINISTRATOR.upgrade_contract(contract_name=contract_name,
                                                  ignore_deployed=ignore_deployed)
        emitter.message(f"Successfully deployed and upgraded {contract_name}", color='green')
        for name, receipt in receipts.items():
            paint_receipt_summary(emitter=emitter, receipt=receipt)
コード例 #2
0
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(actor_options.poa,
                                        actor_options.provider_uri, emitter)
    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
コード例 #3
0
def execute(general_config, blockchain_options, multisig_options, proposal):
    """
    Collect authorizations from executives and execute transaction through MultiSig contract
    """
    # Init
    emitter = general_config.emitter
    #_ensure_config_root(actor_options.config_root)
    blockchain = blockchain_options.connect_blockchain(emitter,
                                                       general_config.debug)
    registry = blockchain_options.get_registry()

    proposal = Proposal.from_file(proposal)

    if not multisig_options.checksum_address:
        multisig_options.checksum_address = select_client_account(
            emitter=emitter,
            provider_uri=blockchain_options.provider_uri,
            poa=blockchain_options.poa,
            network=blockchain_options.network,
            registry=registry,
            show_balances=True)

    name, version, address, abi = registry.search(
        contract_address=proposal.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)

    trustee = multisig_options.create_trustee(registry)
    threshold = trustee.multisig_agent.threshold

    while len(trustee.authorizations) < threshold:
        auth_hex = click.prompt("Signature", type=click.STRING)
        authorization = Authorization.from_hex(auth_hex)
        executive_address = trustee.add_authorization(authorization, proposal)
        emitter.echo(f"Added authorization from executive {executive_address}",
                     color='green')

    click.confirm(
        "\nCollected required authorizations. Proceed with execution?",
        abort=True)

    receipt = trustee.execute(proposal)
    paint_receipt_summary(emitter, receipt)
コード例 #4
0
def propose(general_config, blockchain_options, multisig_options):
    """
    Create a proposal of MultiSig transaction
    """
    # TODO: Extend this command to cover this list of proposals
    #  - Add new MultiSig owner
    #  - Remove MultiSig owner
    #  - Change threshold of MultiSig
    #  - Upgrade contract (in particular, retarget to a deployed one)
    #  - Transfer ownership of contract
    #  - Send ETH from MultiSig
    #  - Send tokens from MultiSig
    #  - Change min reward rate range in PolicyManager
    #  - Send raw transaction

    # Init
    emitter = general_config.emitter
    #_ensure_config_root(actor_options.config_root)
    blockchain = blockchain_options.connect_blockchain(emitter,
                                                       general_config.debug)
    registry = blockchain_options.get_registry()

    if not multisig_options.checksum_address:
        multisig_options.checksum_address = select_client_account(
            emitter=emitter,
            provider_uri=blockchain_options.provider_uri,
            poa=blockchain_options.poa,
            network=blockchain_options.network,
            registry=registry,
            show_balances=True)

    trustee = multisig_options.create_transactingless_trustee(registry)

    # As a PoC, this command only allows to change the threshold
    # TODO: Think in the UX for choosing between different types of proposals

    new_threshold = click.prompt("New threshold", type=click.INT)
    proposal = trustee.propose_changing_threshold(new_threshold)

    paint_multisig_proposed_transaction(emitter=emitter,
                                        proposal=proposal,
                                        registry=registry)

    filepath = f'proposal-changeThreshold-{trustee.multisig_agent.contract_address[:8]}-TX-{proposal.nonce}.json'
    proposal.write(filepath=filepath)
    emitter.echo(f"✅ Saved proposal to {filepath}", color='blue', bold=True)
コード例 #5
0
def sign(general_config, blockchain_options, multisig_options, proposal):
    """
    Sign a proposed transaction before being sent to the MultiSig contract for execution
    """
    # Init
    emitter = general_config.emitter
    #_ensure_config_root(actor_options.config_root)
    blockchain = blockchain_options.connect_blockchain(emitter,
                                                       general_config.debug)
    registry = blockchain_options.get_registry()

    proposal = Proposal.from_file(proposal)

    if not multisig_options.checksum_address:
        multisig_options.checksum_address = select_client_account(
            emitter=emitter,
            provider_uri=blockchain_options.provider_uri,
            poa=blockchain_options.poa,
            network=blockchain_options.network,
            registry=registry,
            show_balances=True)

    name, version, address, abi = registry.search(
        contract_address=proposal.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)

    executive = multisig_options.create_transactingless_executive(
        registry)  # FIXME: Since we use a signer, don't ask for PW
    authorization = executive.authorize_proposal(proposal)
    emitter.echo(
        f"\nSignature received from {authorization.recover_executive_address(proposal)}:\n"
    )
    emitter.echo(f"{authorization.serialize().hex()}\n",
                 bold=True,
                 color='green')
コード例 #6
0
def upgrade(general_config, actor_options, retarget, target_address,
            ignore_deployed, multisig):
    """
    Upgrade NuCypher existing proxy contract deployments.
    """
    # Init
    emitter = general_config.emitter
    ADMINISTRATOR, _, _, registry = actor_options.create_actor(emitter)

    contract_name = actor_options.contract_name
    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 multisig:
        if not target_address:
            raise click.BadArgumentUsage(
                message="--multisig requires using --target-address.")
        if not actor_options.force:
            click.confirm(
                f"Confirm building a re-target transaction for {contract_name}'s proxy to {target_address}?",
                abort=True)
        transaction = ADMINISTRATOR.retarget_proxy(
            contract_name=contract_name,
            target_address=target_address,
            existing_plaintext_secret=existing_secret,
            new_plaintext_secret=new_secret,
            just_build_transaction=True)

        trustee = Trustee(registry=registry,
                          checksum_address=ADMINISTRATOR.deployer_address)
        data_for_multisig_executives = trustee.produce_data_to_sign(
            transaction)

        emitter.message(
            f"Transaction to retarget {contract_name} proxy to {target_address} was built:",
            color='green')
        paint_multisig_proposed_transaction(emitter,
                                            data_for_multisig_executives)

        # TODO: Move this logic to a better place
        nonce = data_for_multisig_executives['parameters']['nonce']
        filepath = f'proposal-{nonce}.json'
        with open(filepath, 'w') as outfile:
            json.dump(data_for_multisig_executives, outfile)
        emitter.echo(f"Saved proposal to {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(
                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)
    else:
        if not actor_options.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,
            ignore_deployed=ignore_deployed)
        emitter.message(f"Successfully deployed and upgraded {contract_name}",
                        color='green')
        for name, receipt in receipts.items():
            paint_receipt_summary(emitter=emitter, receipt=receipt)