示例#1
0
def init(click_config,

         # Admin Options
         geth, provider_uri, network, registry_filepath, staker_address, worker_address, federated_only, rest_host,
         rest_port, db_filepath, poa, light,

         # Other
         force, config_root):
    """
    Create a new Ursula node configuration.
    """

    ### Setup ###
    _validate_args(geth, federated_only, staker_address, registry_filepath)

    emitter = _setup_emitter(click_config, worker_address)

    _pre_launch_warnings(emitter, dev=None, force=force)

    ETH_NODE = NO_BLOCKCHAIN_CONNECTION
    if geth:
        ETH_NODE = actions.get_provider_process()
        provider_uri = ETH_NODE.provider_uri(scheme='file')
    #############

    if (not staker_address or not worker_address) and not federated_only:
        if not staker_address:
            prompt = "Select staker account"
            staker_address = select_client_account(emitter=emitter, prompt=prompt, provider_uri=provider_uri)

        if not worker_address:
            prompt = "Select worker account"
            worker_address = select_client_account(emitter=emitter, prompt=prompt, provider_uri=provider_uri)
    if not config_root:  # Flag
        config_root = click_config.config_file  # Envvar
    if not rest_host:
        rest_host = actions.determine_external_ip_address(emitter, force=force)
    ursula_config = UrsulaConfiguration.generate(password=get_nucypher_password(confirm=True),
                                                 config_root=config_root,
                                                 rest_host=rest_host,
                                                 rest_port=rest_port,
                                                 db_filepath=db_filepath,
                                                 domains={network} if network else None,
                                                 federated_only=federated_only,
                                                 checksum_address=staker_address,
                                                 worker_address=worker_address,
                                                 registry_filepath=registry_filepath,
                                                 provider_process=ETH_NODE,
                                                 provider_uri=provider_uri,
                                                 poa=poa,
                                                 light=light)
    painting.paint_new_installation_help(emitter, new_configuration=ursula_config)
示例#2
0
def init(
        click_config,

        # Admin Options
        provider_uri,
        network,
        registry_filepath,
        checksum_address,

        # Other
        federated_only,
        config_root):
    """
    Create a brand new persistent Bob.
    """
    emitter = _setup_emitter(click_config)

    if not config_root:  # Flag
        config_root = click_config.config_file  # Envvar
    if not checksum_address and not federated_only:
        checksum_address = select_client_account(emitter=emitter,
                                                 provider_uri=provider_uri)

    new_bob_config = BobConfiguration.generate(
        password=get_nucypher_password(confirm=True),
        config_root=config_root or DEFAULT_CONFIG_ROOT,
        checksum_address=checksum_address,
        domains={network} if network else None,
        federated_only=federated_only,
        registry_filepath=registry_filepath,
        provider_uri=provider_uri)
    return painting.paint_new_installation_help(
        emitter, new_configuration=new_bob_config)
示例#3
0
文件: alice.py 项目: xbee/nucypher
    def generate_config(self, emitter, config_root):

        opts = self.config_options

        if opts.dev:
            raise click.BadArgumentUsage(
                "Cannot create a persistent development character")

        if not opts.provider_uri and not opts.federated_only:
            raise click.BadOptionUsage(
                option_name='--provider',
                message=
                "--provider is required to create a new decentralized alice.")

        pay_with = opts.pay_with
        if not pay_with and not opts.federated_only:
            pay_with = select_client_account(emitter=emitter,
                                             provider_uri=opts.provider_uri,
                                             show_eth_balance=True)

        return AliceConfiguration.generate(
            password=get_nucypher_password(confirm=True),
            config_root=config_root,
            checksum_address=pay_with,
            domains=opts.domains,
            federated_only=opts.federated_only,
            provider_uri=opts.provider_uri,
            signer_uri=opts.signer_uri,
            provider_process=opts.eth_node,
            registry_filepath=opts.registry_filepath,
            poa=self.poa,
            light=self.light,
            m=self.m,
            n=self.n,
            duration_periods=self.duration_periods)
示例#4
0
def allocations(general_config, actor_options, allocation_infile, allocation_outfile, sidekick_account):
    """
    Deploy pre-allocation contracts.
    """
    emitter = general_config.emitter
    ADMINISTRATOR, _, deployer_interface, local_registry = actor_options.create_actor(emitter)

    if not sidekick_account and click.confirm('Do you want to use a sidekick account to assist during deployment?'):
        prompt = "Select sidekick account"
        sidekick_account = select_client_account(emitter=emitter,
                                                 prompt=prompt,
                                                 provider_uri=actor_options.provider_uri,
                                                 registry=local_registry,
                                                 show_balances=True)
        if not actor_options.force:
            click.confirm(f"Selected {sidekick_account} - Continue?", abort=True)

    if sidekick_account:
        password = None
        if not deployer_interface.client.is_local:
            password = get_client_password(checksum_address=sidekick_account)
        ADMINISTRATOR.recruit_sidekick(sidekick_address=sidekick_account, sidekick_password=password)

    if not allocation_infile:
        allocation_infile = click.prompt("Enter allocation data filepath")
    ADMINISTRATOR.deploy_beneficiaries_from_file(allocation_data_filepath=allocation_infile,
                                                 allocation_outfile=allocation_outfile,
                                                 emitter=emitter,
                                                 interactive=not actor_options.force)
示例#5
0
def claim(general_config, worklock_options, registry_options, force,
          hw_wallet):
    """Claim tokens for a successful bid, and start staking them"""
    emitter = _setup_emitter(general_config)
    if not worklock_options.bidder_address:
        worklock_options.bidder_address = select_client_account(
            emitter=emitter,
            provider_uri=registry_options.provider_uri,
            network=registry_options.network,
            show_balances=True)

    # TODO: Show amount of tokens to claim

    if not force:
        emitter.echo(
            "Note: Claiming WorkLock NU tokens will initialize a new stake.",
            color='blue')
        click.confirm(
            f"Continue worklock claim for bidder {worklock_options.bidder_address}?",
            abort=True)
    emitter.message("Submitting Claim...")
    registry = registry_options.get_registry(emitter, general_config.debug)
    bidder = worklock_options.create_bidder(registry=registry,
                                            hw_wallet=hw_wallet)
    receipt = bidder.claim()
    paint_receipt_summary(
        receipt=receipt,
        emitter=emitter,
        chain_name=bidder.staking_agent.blockchain.client.chain_name)
    paint_worklock_claim(emitter=emitter,
                         bidder_address=worklock_options.bidder_address,
                         network=registry_options.network,
                         provider_uri=registry_options.provider_uri)
    return  # Exit
示例#6
0
def refund(general_config, worklock_options, force, hw_wallet):
    """Reclaim ETH unlocked by your work"""
    emitter, registry, blockchain = worklock_options.setup(
        general_config=general_config)
    if not worklock_options.bidder_address:
        worklock_options.bidder_address = select_client_account(
            emitter=emitter,
            provider_uri=worklock_options.provider_uri,
            poa=worklock_options.poa,
            network=worklock_options.network,
            registry=registry,
            show_balances=True)
    if not force:
        click.confirm(
            f"Collect ETH refund for bidder {worklock_options.bidder_address}?",
            abort=True)
    emitter.echo("Submitting WorkLock refund request...")

    bidder = worklock_options.create_bidder(registry=registry,
                                            hw_wallet=hw_wallet)
    receipt = bidder.refund_deposit()
    paint_receipt_summary(
        receipt=receipt,
        emitter=emitter,
        chain_name=bidder.staking_agent.blockchain.client.chain_name)
    return  # Exit
示例#7
0
def cancel_bid(general_config, registry_options, worklock_options, force,
               hw_wallet):
    """Cancel your bid"""
    emitter = _setup_emitter(general_config)
    if not worklock_options.bidder_address:  # TODO: Consider bundle this in worklock_options
        worklock_options.bidder_address = select_client_account(
            emitter=emitter,
            provider_uri=registry_options.provider_uri,
            network=registry_options.network,
            show_balances=True)
    registry = registry_options.get_registry(emitter, general_config.debug)
    bidder = worklock_options.create_bidder(registry=registry,
                                            hw_wallet=hw_wallet)
    if not force:
        value = bidder.get_deposited_eth
        click.confirm(
            f"Confirm bid cancellation of {prettify_eth_amount(value)}"
            f" for {worklock_options.bidder_address}?",
            abort=True)
    receipt = bidder.cancel_bid()
    emitter.echo("Bid canceled\n", color='green')
    paint_receipt_summary(
        receipt=receipt,
        emitter=emitter,
        chain_name=bidder.staking_agent.blockchain.client.chain_name)
    return  # Exit
示例#8
0
    def generate_config(self, emitter, config_root, force):

        assert not self.dev

        staker_address = self.staker_address
        worker_address = self.worker_address
        if (not staker_address or not worker_address) and not self.federated_only:
            if not staker_address:
                staker_address = click.prompt("Enter staker address", type=EIP55_CHECKSUM_ADDRESS)

            if not worker_address:
                prompt = "Select worker account"
                worker_address = select_client_account(emitter=emitter,
                                                       prompt=prompt,
                                                       provider_uri=self.provider_uri,
                                                       show_balances=False)

        rest_host = self.rest_host
        if not rest_host:
            rest_host = actions.determine_external_ip_address(emitter, force=force)

        return UrsulaConfiguration.generate(password=get_nucypher_password(confirm=True),
                                            config_root=config_root,
                                            rest_host=rest_host,
                                            rest_port=self.rest_port,
                                            db_filepath=self.db_filepath,
                                            domains=self.domains,
                                            federated_only=self.federated_only,
                                            checksum_address=staker_address,
                                            worker_address=worker_address,
                                            registry_filepath=self.registry_filepath,
                                            provider_process=self.eth_node,
                                            provider_uri=self.provider_uri,
                                            poa=self.poa,
                                            light=self.light)
示例#9
0
def cancel_bid(general_config, worklock_options, force, hw_wallet):
    """Cancel your bid and receive your ETH back"""
    emitter, registry, blockchain = worklock_options.setup(
        general_config=general_config)
    worklock_agent = ContractAgency.get_agent(
        WorkLockAgent, registry=registry)  # type: WorkLockAgent
    now = maya.now().epoch
    if not worklock_agent.start_bidding_date <= now <= worklock_agent.end_cancellation_date:
        raise click.Abort(
            f"You can't cancel your bid. The cancellation window is closed.")

    if not worklock_options.bidder_address:  # TODO: Consider bundle this in worklock_options
        worklock_options.bidder_address = select_client_account(
            emitter=emitter,
            provider_uri=worklock_options.provider_uri,
            poa=worklock_options.poa,
            network=worklock_options.network,
            show_balances=True,
            registry=registry)

    bidder = worklock_options.create_bidder(registry=registry,
                                            hw_wallet=hw_wallet)
    if not force:
        value = bidder.get_deposited_eth
        click.confirm(
            f"Confirm bid cancellation of {prettify_eth_amount(value)}"
            f" for {worklock_options.bidder_address}?",
            abort=True)
    receipt = bidder.cancel_bid()
    emitter.echo("Bid canceled\n", color='green')
    paint_receipt_summary(
        receipt=receipt,
        emitter=emitter,
        chain_name=bidder.staking_agent.blockchain.client.chain_name)
    return  # Exit
示例#10
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)
示例#11
0
def burn_unclaimed_tokens(general_config, registry_options, checksum_address):
    emitter = _setup_emitter(general_config)
    registry = registry_options.get_registry(emitter, general_config.debug)
    worklock_agent = ContractAgency.get_agent(WorkLockAgent, registry=registry)
    if not checksum_address:
        checksum_address = select_client_account(emitter=emitter, provider_uri=general_config.provider_uri)
    receipt = worklock_agent.burn_unclaimed(sender_address=checksum_address)
    paint_receipt_summary(receipt=receipt, emitter=emitter, chain_name=worklock_agent.blockchain.client.chain_name)
    return  # Exit
示例#12
0
def remaining_work(general_config, worklock_options, registry_options):
    emitter = _setup_emitter(general_config)
    if not worklock_options.bidder_address:
        worklock_options.bidder_address = select_client_account(emitter=emitter, provider_uri=general_config.provider_uri)
    registry = registry_options.get_registry(emitter, general_config.debug)
    bidder = worklock_options.create_bidder(registry=registry)
    _remaining_work = bidder.remaining_work
    emitter.message(f"Work Remaining for {worklock_options.bidder_address}: {_remaining_work}")
    return  # Exit
示例#13
0
文件: deploy.py 项目: y3v63n/nucypher
    def create_actor(self, emitter, is_multisig: bool = False):

        _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
        password = None
        if is_multisig:
            multisig_agent = ContractAgency.get_agent(MultiSigAgent, registry=local_registry)
            deployer_address = multisig_agent.contract.address
            is_transacting = False
        else:
            is_transacting = True
            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)

            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,
                                              is_transacting=is_transacting,
                                              staking_escrow_test_mode=self.se_test_mode)
        # Verify ETH Balance
        emitter.echo(f"\n\nDeployer ETH balance: {ADMINISTRATOR.eth_balance}")
        if is_transacting and 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
示例#14
0
def enable_claiming(general_config, registry_options, worklock_options, force, hw_wallet, gas_limit):
    """Ensure correctness of bidding and enable claiming"""
    emitter = _setup_emitter(general_config)
    registry = registry_options.get_registry(emitter, general_config.debug)
    if not worklock_options.bidder_address:  # TODO: Consider bundle this in worklock_options
        worklock_options.bidder_address = select_client_account(emitter=emitter,
                                                                provider_uri=registry_options.provider_uri,
                                                                network=registry_options.network,
                                                                registry=registry,
                                                                show_balances=True)
    bidder = worklock_options.create_bidder(registry=registry, hw_wallet=hw_wallet)

    whales = bidder.get_whales()
    if whales:
        headers = ("Bidders that require correction", "Current bid bonus")
        columns = (whales.keys(), map(prettify_eth_amount, whales.values()))
        emitter.echo(tabulate.tabulate(dict(zip(headers, columns)), headers=headers, floatfmt="fancy_grid"))

        if not force:
            click.confirm(f"Confirm force refund to at least {len(whales)} bidders"
                          f" using {worklock_options.bidder_address}?", abort=True)

        force_refund_receipt = bidder.force_refund()
        emitter.echo(f"At least {len(whales)} bidders got a force refund\n", color='green')

        paint_receipt_summary(receipt=force_refund_receipt,
                              emitter=emitter,
                              chain_name=bidder.staking_agent.blockchain.client.chain_name,
                              transaction_type=f"force-refund")
    else:
        emitter.echo(f"All bids are correct, force refund is not needed\n", color='yellow')

    if not bidder.worklock_agent.bidders_checked():
        if not gas_limit:
            # TODO print gas estimations
            min_gas = 180000
            gas_limit = click.prompt(f"Enter gas limit per each verification transaction (at least {min_gas})",
                                     type=click.IntRange(min=min_gas))

        if not force:
            click.confirm(f"Confirm verifying of bidding from {worklock_options.bidder_address} "
                          f"using {gas_limit} gas per each transaction?", abort=True)

        verification_receipts = bidder.verify_bidding_correctness(gas_limit=gas_limit)
        emitter.echo("Bidding has been checked\n", color='green')

        for iteration, receipt in verification_receipts.items():
            paint_receipt_summary(receipt=receipt,
                                  emitter=emitter,
                                  chain_name=bidder.staking_agent.blockchain.client.chain_name,
                                  transaction_type=f"verify-correctness[{iteration}]")
    else:
        emitter.echo(f"Bidders have already been checked\n", color='yellow')

    return  # Exit
示例#15
0
def bid(general_config, worklock_options, registry_options, force, hw_wallet, value):
    """Place a bid, or increase an existing bid"""
    emitter = _setup_emitter(general_config)
    registry = registry_options.get_registry(emitter, general_config.debug)

    worklock_agent = ContractAgency.get_agent(WorkLockAgent, registry=registry)  # type: WorkLockAgent
    now = maya.now().epoch
    if not worklock_agent.start_bidding_date <= now <= worklock_agent.end_bidding_date:
        raise click.Abort(f"You can't bid, the bidding window is closed.")

    if not worklock_options.bidder_address:
        worklock_options.bidder_address = select_client_account(emitter=emitter,
                                                                provider_uri=registry_options.provider_uri,
                                                                poa=registry_options.poa,
                                                                network=registry_options.network,
                                                                registry=registry,
                                                                show_balances=True)

    bidder = worklock_options.create_bidder(registry=registry, hw_wallet=hw_wallet)

    if not value:
        if force:
            raise click.MissingParameter("Missing --value.")

        existing_bid_amount = bidder.get_deposited_eth
        if not existing_bid_amount:  # It's the first bid
            minimum_bid = bidder.worklock_agent.minimum_allowed_bid
            minimum_bid_in_eth = Web3.fromWei(minimum_bid, 'ether')
            prompt = f"Enter bid amount in ETH (at least {minimum_bid_in_eth} ETH)"
        else:  # There's an existing bid and the bidder is increasing the amount
            emitter.message(f"You have an existing bid of {Web3.fromWei(existing_bid_amount, 'ether')} ETH")
            minimum_bid_in_eth = Web3.fromWei(1, 'ether')
            prompt = f"Enter the amount in ETH that you want to increase your bid"
        value = click.prompt(prompt, type=DecimalRange(min=minimum_bid_in_eth))

    value = int(Web3.toWei(Decimal(value), 'ether'))

    if not force:
        paint_bidding_notice(emitter=emitter, bidder=bidder)
        click.confirm(f"Place WorkLock bid of {prettify_eth_amount(value)}?", abort=True)

    receipt = bidder.place_bid(value=value)
    emitter.message("Publishing WorkLock Bid...")

    maximum = NU.from_nunits(bidder.economics.maximum_allowed_locked)
    available_claim = NU.from_nunits(bidder.available_claim)
    message = f'Current bid: {prettify_eth_amount(bidder.get_deposited_eth)} | Claim: {available_claim}\n'
    if available_claim > maximum:
        message += f"This claim is currently above the allowed max ({maximum}), so the bid may be partially refunded.\n"
    message += f'Note that available claim value may fluctuate until bidding closes and claims are finalized.\n'
    emitter.echo(message, color='yellow')

    paint_receipt_summary(receipt=receipt, emitter=emitter, chain_name=bidder.staking_agent.blockchain.client.chain_name)
    return  # Exit
示例#16
0
def refund(general_config, worklock_options, registry_options, force):
    emitter = _setup_emitter(general_config)
    if not worklock_options.bidder_address:
        worklock_options.bidder_address = select_client_account(emitter=emitter, provider_uri=general_config.provider_uri)
    if not force:
        click.confirm(f"Collect ETH refund for bidder {worklock_options.bidder_address}?", abort=True)
    emitter.message("Submitting WorkLock refund request...")
    registry = registry_options.get_registry(emitter, general_config.debug)
    bidder = worklock_options.create_bidder(registry=registry)
    receipt = bidder.refund_deposit()
    paint_receipt_summary(receipt=receipt, emitter=emitter, chain_name=bidder.staking_agent.blockchain.client.chain_name)
    return  # Exit
示例#17
0
def claim(general_config, worklock_options, registry_options, force, hw_wallet):
    """Claim tokens for your bid, and start staking them"""
    emitter = _setup_emitter(general_config)
    registry = registry_options.get_registry(emitter, general_config.debug)

    worklock_agent = ContractAgency.get_agent(WorkLockAgent, registry=registry)  # type: WorkLockAgent
    if not worklock_agent.is_claiming_available():
        raise click.Abort(f"You can't claim tokens. Claiming is not currently available.")

    if not worklock_options.bidder_address:
        worklock_options.bidder_address = select_client_account(emitter=emitter,
                                                                provider_uri=registry_options.provider_uri,
                                                                poa=registry_options.poa,
                                                                network=registry_options.network,
                                                                registry=registry,
                                                                show_balances=True)

    bidder = worklock_options.create_bidder(registry=registry, hw_wallet=hw_wallet)

    unspent_bid = bidder.available_compensation
    if unspent_bid:
        emitter.echo(f"Note that WorkLock did not use your entire bid due to a maximum claim limit.\n"
                     f"Therefore, an unspent amount of {prettify_eth_amount(unspent_bid)} is available for refund.")
        if not force:
            click.confirm(f"Before claiming your NU tokens for {worklock_options.bidder_address}, you will need to be refunded your unspent bid amount. Would you like to proceed?", abort=True)
        emitter.echo("Requesting refund of unspent bid amount...")
        receipt = bidder.withdraw_compensation()
        paint_receipt_summary(receipt=receipt, emitter=emitter, chain_name=bidder.staking_agent.blockchain.client.chain_name)

    has_claimed = bidder._has_claimed
    if has_claimed:
        emitter.echo(f"Claim was already done for {bidder.checksum_address}", color='red')
        return

    tokens = NU.from_nunits(bidder.available_claim)
    emitter.echo(f"\nYou have an available claim of {tokens} 🎉 \n", color='green', bold=True)
    if not force:
        lock_duration = bidder.worklock_agent.worklock_parameters()[-2]
        emitter.echo(f"Note: Claiming WorkLock NU tokens will initialize a new stake to be locked for {lock_duration} periods.",
                     color='blue')
        click.confirm(f"Continue WorkLock claim for bidder {worklock_options.bidder_address}?", abort=True)
    emitter.echo("Submitting Claim...")

    receipt = bidder.claim()
    paint_receipt_summary(receipt=receipt, emitter=emitter, chain_name=bidder.staking_agent.blockchain.client.chain_name)
    paint_worklock_claim(emitter=emitter,
                         bidder_address=worklock_options.bidder_address,
                         network=registry_options.network,
                         provider_uri=registry_options.provider_uri)
    return  # Exit
示例#18
0
def cancel_bid(general_config, registry_options, worklock_options, force):
    emitter = _setup_emitter(general_config)
    if not worklock_options.bidder_address:
        worklock_options.bidder_address = select_client_account(emitter=emitter,
                                                                provider_uri=general_config.provider_uri)
    registry = registry_options.get_registry(emitter, general_config.debug)
    bidder = worklock_options.create_bidder(registry=registry)
    if not force:
        value = bidder.get_deposited_eth
        click.confirm(f"Confirm bid cancellation of {Web3.fromWei(value, 'ether')} ETH"
                      f" for {worklock_options.bidder_address}?", abort=True)
    receipt = bidder.cancel_bid()
    paint_receipt_summary(receipt=receipt, emitter=emitter, chain_name=bidder.staking_agent.blockchain.client.chain_name)
    return  # Exit
示例#19
0
def claim(general_config, worklock_options, registry_options, force):
    emitter = _setup_emitter(general_config)
    if not worklock_options.bidder_address:
        worklock_options.bidder_address = select_client_account(emitter=emitter,
                                                                provider_uri=general_config.provider_uri)
    if not force:
        emitter.message("Note: Claiming WorkLock NU tokens will initialize a new stake.", color='blue')
        click.confirm(f"Continue worklock claim for bidder {worklock_options.bidder_address}?", abort=True)
    emitter.message("Submitting Claim...")
    registry = registry_options.get_registry(emitter, general_config.debug)
    bidder = worklock_options.create_bidder(registry=registry)
    receipt = bidder.claim()
    paint_receipt_summary(receipt=receipt, emitter=emitter, chain_name=bidder.staking_agent.blockchain.client.chain_name)
    paint_worklock_claim(emitter, bidder_address=worklock_options.bidder_address)
    return  # Exit
示例#20
0
def remaining_work(general_config, worklock_options, registry_options):
    emitter = _setup_emitter(general_config)
    if not worklock_options.bidder_address:
        worklock_options.bidder_address = select_client_account(
            emitter=emitter,
            provider_uri=registry_options.provider_uri,
            network=registry_options.network,
            show_balances=True)
    registry = registry_options.get_registry(emitter, general_config.debug)
    bidder = worklock_options.create_transactionless_bidder(registry=registry)
    _remaining_work = bidder.remaining_work
    emitter.echo(
        f"Work Remaining for {worklock_options.bidder_address}: {_remaining_work}"
    )
    return  # Exit
示例#21
0
def bid(general_config, worklock_options, registry_options, force, hw_wallet,
        value):
    """Place a bid"""
    emitter = _setup_emitter(general_config)

    if not worklock_options.bidder_address:
        worklock_options.bidder_address = select_client_account(
            emitter=emitter,
            provider_uri=registry_options.provider_uri,
            network=registry_options.network,
            show_balances=True)
    if not value:
        if force:
            raise click.MissingParameter("Missing --value.")
        value = click.prompt("Enter bid amount in ETH", type=click.STRING)
    value = int(Web3.toWei(Decimal(value), 'ether'))

    registry = registry_options.get_registry(emitter, general_config.debug)
    bidder = worklock_options.create_bidder(registry=registry,
                                            hw_wallet=hw_wallet)

    if not force:
        paint_bidding_notice(emitter=emitter, bidder=bidder)
        click.confirm(f"Place WorkLock bid of {prettify_eth_amount(value)}?",
                      abort=True)

    receipt = bidder.place_bid(value=value)
    emitter.message("Publishing WorkLock Bid...")

    # Ensure the total bid value is worth a claim that is at
    # least large enough for the minimum stake.
    minimum = bidder.economics.minimum_allowed_locked
    available_claim = NU.from_nunits(bidder.available_claim)
    if available_claim < minimum:
        warning = f"Total bid ({available_claim}) is too small for a claim, please bid more or cancel.\n" \
                  f"Total must be worth at least {NU.from_nunits(minimum)})."
        emitter.echo(warning, color='yellow')
    else:
        message = f'Current bid: {prettify_eth_amount(bidder.get_deposited_eth)} | ' \
                  f'Available claim: {available_claim}\n' \
                  f'Note that available claim value may fluctuate until bidding closes and claims are finalized.\n'
        emitter.echo(message, color='yellow')

    paint_receipt_summary(
        receipt=receipt,
        emitter=emitter,
        chain_name=bidder.staking_agent.blockchain.client.chain_name)
    return  # Exit
示例#22
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)
示例#23
0
def remaining_work(general_config, worklock_options, registry_options):
    """Check how much work is pending until you can get all your locked ETH back"""
    emitter = _setup_emitter(general_config)
    registry = registry_options.get_registry(emitter, general_config.debug)
    if not worklock_options.bidder_address:
        worklock_options.bidder_address = select_client_account(emitter=emitter,
                                                                provider_uri=registry_options.provider_uri,
                                                                poa=registry_options.poa,
                                                                network=registry_options.network,
                                                                registry=registry,
                                                                show_balances=True)

    bidder = worklock_options.create_transactionless_bidder(registry=registry)
    _remaining_work = bidder.remaining_work
    emitter.echo(f"Work Remaining for {worklock_options.bidder_address}: {_remaining_work}")
    return  # Exit
示例#24
0
    def generate_config(self, emitter, config_root, federated_only):

        checksum_address = self.checksum_address
        if not checksum_address and not federated_only:
            checksum_address = select_client_account(
                emitter=emitter,
                provider_uri=self.provider_uri,
                show_balances=False)

        return BobConfiguration.generate(
            password=get_nucypher_password(confirm=True),
            config_root=config_root,
            checksum_address=checksum_address,
            domains=self.domains,
            federated_only=federated_only,
            registry_filepath=self.registry_filepath,
            provider_uri=self.provider_uri)
示例#25
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)
示例#26
0
def burn_unclaimed_tokens(general_config, registry_options, checksum_address):
    emitter = _setup_emitter(general_config)
    registry = registry_options.get_registry(emitter, general_config.debug)
    worklock_agent = ContractAgency.get_agent(WorkLockAgent, registry=registry)
    if not checksum_address:
        checksum_address = select_client_account(
            emitter=emitter,
            provider_uri=registry_options.provider_uri,
            network=registry_options.network,
            show_balances=True)
    # FIXME: This won't work in real life, it needs TransactingPowers and stuff
    receipt = worklock_agent.burn_unclaimed(sender_address=checksum_address)
    paint_receipt_summary(
        receipt=receipt,
        emitter=emitter,
        chain_name=worklock_agent.blockchain.client.chain_name)
    return  # Exit
示例#27
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')
示例#28
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
示例#29
0
    def generate_config(self, emitter, config_root, force):

        assert not self.dev  # TODO: Raise instead

        worker_address = self.worker_address
        if (not worker_address) and not self.federated_only:
            if not worker_address:
                prompt = "Select worker account"
                worker_address = select_client_account(
                    emitter=emitter,
                    prompt=prompt,
                    provider_uri=self.provider_uri,
                    show_balances=False)

        rest_host = self.rest_host
        if not rest_host:
            rest_host = os.environ.get(NUCYPHER_ENVVAR_WORKER_IP_ADDRESS)
            if not rest_host:
                # TODO: Something less centralized... :-(
                # TODO: Ask Ursulas instead
                rest_host = actions.determine_external_ip_address(emitter,
                                                                  force=force)

        return UrsulaConfiguration.generate(
            password=get_nucypher_password(confirm=True),
            config_root=config_root,
            rest_host=rest_host,
            rest_port=self.rest_port,
            db_filepath=self.db_filepath,
            domains=self.domains,
            federated_only=self.federated_only,
            worker_address=worker_address,
            registry_filepath=self.registry_filepath,
            provider_process=self.eth_node,
            provider_uri=self.provider_uri,
            signer_uri=self.signer_uri,
            gas_strategy=self.gas_strategy,
            poa=self.poa,
            light=self.light,
            availability_check=self.availability_check)
示例#30
0
def bid(general_config, worklock_options, registry_options, force, value):
    emitter = _setup_emitter(general_config)
    if not value:
        if force:
            raise click.MissingParameter("Missing --value.")
        value = int(Web3.fromWei(click.prompt("Enter bid amount in ETH", type=click.FloatRange(min=0)), 'wei'))

    if not worklock_options.bidder_address:
        worklock_options.bidder_address = select_client_account(emitter=emitter,
                                                                provider_uri=general_config.provider_uri)
    registry = registry_options.get_registry(emitter, general_config.debug)
    bidder = worklock_options.create_bidder(registry=registry)

    if not force:
        paint_bidding_notice(emitter=emitter, bidder=bidder)
        click.confirm(f"Place WorkLock bid of {Web3.fromWei(value, 'ether')} ETH?", abort=True)

    receipt = bidder.place_bid(value=value)
    emitter.message("Publishing WorkLock Bid...")

    # Ensure the total bid value is worth a claim that is at
    # least large enough for the minimum stake.
    minimum = bidder.economics.minimum_allowed_locked
    available_claim = bidder.available_claim
    if available_claim < minimum:
        warning = f"Total bid is too small for a claim, please bid more or cancel. " \
                  f"{available_claim} total / {minimum} minimum" \
                  f"(Total must be worth at least {NU.from_nunits(minimum)})"
        emitter.echo(warning, color='yellow')
    else:
        message = f'Current bid: {bidder.get_deposited_eth} | ' \
                  f'Available Claim: {bidder.available_claim} |' \
                  f'Note that available claim value may fluctuate ' \
                  f'until bidding closes and claims are finalized.'
        emitter.echo(message, color='yellow')

    paint_receipt_summary(receipt=receipt, emitter=emitter, chain_name=bidder.staking_agent.blockchain.client.chain_name)
    return  # Exit