Example #1
0
def test_upgradeability(temp_dir_path):
    # Prepare remote source for compilation
    download_github_dir(GITHUB_SOURCE_LINK, temp_dir_path)
    solidity_compiler = SolidityCompiler(source_dirs=[SourceDirs(SolidityCompiler.default_contract_dir()),
                                                      SourceDirs(temp_dir_path)])

    # Prepare the blockchain
    provider_uri = 'tester://pyevm/2'
    try:
        blockchain_interface = BlockchainDeployerInterface(provider_uri=provider_uri,
                                                           compiler=solidity_compiler,
                                                           gas_strategy=free_gas_price_strategy)
        blockchain_interface.connect()
        origin = blockchain_interface.client.accounts[0]
        BlockchainInterfaceFactory.register_interface(interface=blockchain_interface)
        blockchain_interface.transacting_power = TransactingPower(password=INSECURE_DEVELOPMENT_PASSWORD, account=origin)
        blockchain_interface.transacting_power.activate()

        # Check contracts with multiple versions
        raw_contracts = blockchain_interface._raw_contract_cache
        contract_name = AdjudicatorDeployer.contract_name
        test_adjudicator = len(raw_contracts[contract_name]) > 1
        contract_name = StakingEscrowDeployer.contract_name
        test_staking_escrow = len(raw_contracts[contract_name]) > 1
        contract_name = PolicyManagerDeployer.contract_name
        test_policy_manager = len(raw_contracts[contract_name]) > 1

        if not test_adjudicator and not test_staking_escrow and not test_policy_manager:
            return

        # Prepare master version of contracts and upgrade to the latest
        registry = InMemoryContractRegistry()

        token_deployer = NucypherTokenDeployer(registry=registry, deployer_address=origin)
        token_deployer.deploy()

        staking_escrow_deployer = StakingEscrowDeployer(registry=registry, deployer_address=origin)
        deploy_earliest_contract(blockchain_interface, staking_escrow_deployer)
        if test_staking_escrow:
            staking_escrow_deployer.upgrade(contract_version="latest", confirmations=0)

        if test_policy_manager:
            policy_manager_deployer = PolicyManagerDeployer(registry=registry, deployer_address=origin)
            deploy_earliest_contract(blockchain_interface, policy_manager_deployer)
            policy_manager_deployer.upgrade(contract_version="latest", confirmations=0)

        if test_adjudicator:
            adjudicator_deployer = AdjudicatorDeployer(registry=registry, deployer_address=origin)
            deploy_earliest_contract(blockchain_interface, adjudicator_deployer)
            adjudicator_deployer.upgrade(contract_version="latest", confirmations=0)

    finally:
        # Unregister interface
        with contextlib.suppress(KeyError):
            del BlockchainInterfaceFactory._interfaces[provider_uri]
def test_multi_versions():
    base_dir = os.path.join(dirname(abspath(__file__)), "contracts", "multiversion")
    v1_dir = os.path.join(base_dir, "v1")
    v2_dir = os.path.join(base_dir, "v2")
    root_dir = SolidityCompiler.default_contract_dir()
    solidity_compiler = SolidityCompiler(source_dirs=[SourceDirs(root_dir, {v1_dir}),
                                                      SourceDirs(root_dir, {v2_dir})])
    interfaces = solidity_compiler.compile()
    assert "VersionTest" in interfaces
    contract_data = interfaces["VersionTest"]
    assert len(contract_data) == 2
    assert "v1.2.3" in contract_data
    assert "v1.1.4" in contract_data
    assert contract_data["v1.2.3"]["devdoc"] != contract_data["v1.1.4"]["devdoc"]
Example #3
0
    def connect(cls, *args, **kwargs) -> 'TesterBlockchain':
        interface = BlockchainDeployerInterface(provider_uri=cls._PROVIDER_URI,
                                                compiler=SolidityCompiler(test_contract_dir=CONTRACT_ROOT),
                                                registry=InMemoryEthereumContractRegistry())

        testerchain = TesterBlockchain(interface=interface, *args, **kwargs)
        return testerchain
Example #4
0
    def connect(cls,
                provider_uri: str = None,
                registry: EthereumContractRegistry = None,
                deployer: bool = False,
                compile: bool = False,
                poa: bool = False) -> 'Blockchain':

        if cls._instance is NO_BLOCKCHAIN_AVAILABLE:
            registry = registry or EthereumContractRegistry()
            compiler = SolidityCompiler() if compile is True else None
            InterfaceClass = BlockchainDeployerInterface if deployer is True else BlockchainInterface
            interface = InterfaceClass(provider_uri=provider_uri,
                                       registry=registry,
                                       compiler=compiler)

            if poa is True:
                interface.w3.middleware_onion.inject(geth_poa_middleware,
                                                     layer=0)

            cls._instance = cls(interface=interface)
        else:
            if provider_uri is not None:
                existing_uri = cls._instance.interface.provider_uri
                if existing_uri != provider_uri:
                    raise ValueError(
                        "There is an existing blockchain connection to {}. "
                        "Use Interface.add_provider to connect additional providers"
                        .format(existing_uri))
        return cls._instance
Example #5
0
    def bootstrap_network(
        cls,
        economics: BaseEconomics = None
    ) -> Tuple['TesterBlockchain', 'InMemoryContractRegistry']:
        """For use with metric testing scripts"""

        registry = InMemoryContractRegistry()
        testerchain = cls(compiler=SolidityCompiler())
        BlockchainInterfaceFactory.register_interface(testerchain)
        power = TransactingPower(password=INSECURE_DEVELOPMENT_PASSWORD,
                                 account=testerchain.etherbase_account)
        power.activate()
        testerchain.transacting_power = power

        origin = testerchain.client.etherbase
        deployer = ContractAdministrator(deployer_address=origin,
                                         registry=registry,
                                         economics=economics
                                         or cls._default_token_economics,
                                         staking_escrow_test_mode=True)
        secrets = dict()
        for deployer_class in deployer.upgradeable_deployer_classes:
            secrets[
                deployer_class.contract_name] = INSECURE_DEVELOPMENT_PASSWORD
        _receipts = deployer.deploy_network_contracts(secrets=secrets,
                                                      interactive=False)
        return testerchain, registry
Example #6
0
def test_multi_source_compilation(testerchain):
    solidity_compiler = SolidityCompiler(
        source_dirs=[(SolidityCompiler.default_contract_dir(), None),
                     (SolidityCompiler.default_contract_dir(),
                      {TesterBlockchain.TEST_CONTRACTS_DIR})])
    interfaces = solidity_compiler.compile()

    # Remove AST because id in tree node depends on compilation scope
    for contract_name, contract_data in interfaces.items():
        for version, data in contract_data.items():
            data.pop("ast")
    raw_cache = testerchain._raw_contract_cache.copy()
    for contract_name, contract_data in raw_cache.items():
        for version, data in contract_data.items():
            data.pop("ast")
    assert interfaces == raw_cache
Example #7
0
def test_rapid_deployment():
    compiler = SolidityCompiler()
    registry = InMemoryEthereumContractRegistry()
    allocation_registry = InMemoryAllocationRegistry()
    interface = BlockchainDeployerInterface(compiler=compiler,
                                            registry=registry,
                                            provider_uri='tester://pyevm')
    blockchain = TesterBlockchain(interface=interface,
                                  airdrop=False,
                                  test_accounts=4)
    blockchain.ether_airdrop(amount=1000000000)
    origin, *everyone = blockchain.interface.w3.eth.accounts

    deployer = Deployer(blockchain=blockchain, deployer_address=origin)

    deployer_address, *all_yall = deployer.blockchain.interface.w3.eth.accounts

    # The Big Three (+ Dispatchers)
    deployer.deploy_network_contracts(miner_secret=os.urandom(32),
                                      policy_secret=os.urandom(32))

    # User Escrow Proxy
    deployer.deploy_escrow_proxy(secret=os.urandom(32))

    # Deploy User Escrow
    total_allocations = 100

    # Start with some hard-coded cases...
    allocation_data = [{
        'address': all_yall[1],
        'amount': MAX_ALLOWED_LOCKED,
        'duration': ONE_YEAR_IN_SECONDS
    }, {
        'address': all_yall[2],
        'amount': MIN_ALLOWED_LOCKED,
        'duration': ONE_YEAR_IN_SECONDS * 2
    }, {
        'address': all_yall[3],
        'amount': MIN_ALLOWED_LOCKED * 100,
        'duration': ONE_YEAR_IN_SECONDS * 3
    }]

    # Pile on the rest
    for _ in range(total_allocations - len(allocation_data)):
        random_password = ''.join(
            random.SystemRandom().choice(string.ascii_uppercase +
                                         string.digits) for _ in range(16))
        acct = w3.eth.account.create(random_password)
        beneficiary_address = acct.address
        amount = random.randint(MIN_ALLOWED_LOCKED, MAX_ALLOWED_LOCKED)
        duration = random.randint(MIN_LOCKED_PERIODS, MAX_MINTING_PERIODS * 3)
        random_allocation = {
            'address': beneficiary_address,
            'amount': amount,
            'duration': duration
        }
        allocation_data.append(random_allocation)

    deployer.deploy_beneficiary_contracts(
        allocations=allocation_data, allocation_registry=allocation_registry)
def test_rapid_deployment(token_economics):
    compiler = SolidityCompiler()
    allocation_registry = InMemoryAllocationRegistry()

    blockchain = _TesterBlockchain(eth_airdrop=False,
                                   test_accounts=4,
                                   compiler=compiler)

    # TODO: #1092 - TransactingPower
    blockchain.transacting_power = BlockchainPower(
        blockchain=blockchain, account=blockchain.etherbase_account)
    deployer_address = blockchain.etherbase_account

    deployer = Deployer(blockchain=blockchain,
                        deployer_address=deployer_address)

    deployer.deploy_network_contracts(
        staker_secret=STAKING_ESCROW_DEPLOYMENT_SECRET,
        policy_secret=POLICY_MANAGER_DEPLOYMENT_SECRET,
        adjudicator_secret=ADJUDICATOR_DEPLOYMENT_SECRET,
        user_escrow_proxy_secret=USER_ESCROW_PROXY_DEPLOYMENT_SECRET)

    all_yall = blockchain.unassigned_accounts
    # Start with some hard-coded cases...
    allocation_data = [{
        'address': all_yall[1],
        'amount': token_economics.maximum_allowed_locked,
        'duration': ONE_YEAR_IN_SECONDS
    }, {
        'address': all_yall[2],
        'amount': token_economics.minimum_allowed_locked,
        'duration': ONE_YEAR_IN_SECONDS * 2
    }, {
        'address': all_yall[3],
        'amount': token_economics.minimum_allowed_locked * 100,
        'duration': ONE_YEAR_IN_SECONDS * 3
    }]

    # Pile on the rest
    for _ in range(NUMBER_OF_ALLOCATIONS_IN_TESTS - len(allocation_data)):
        random_password = ''.join(
            random.SystemRandom().choice(string.ascii_uppercase +
                                         string.digits) for _ in range(16))
        acct = w3.eth.account.create(random_password)
        beneficiary_address = acct.address
        amount = random.randint(token_economics.minimum_allowed_locked,
                                token_economics.maximum_allowed_locked)
        duration = random.randint(
            token_economics.minimum_locked_periods * ONE_YEAR_IN_SECONDS,
            (token_economics.maximum_locked_periods * ONE_YEAR_IN_SECONDS) * 3)
        random_allocation = {
            'address': beneficiary_address,
            'amount': amount,
            'duration': duration
        }
        allocation_data.append(random_allocation)

    deployer.deploy_beneficiary_contracts(
        allocations=allocation_data, allocation_registry=allocation_registry)
Example #9
0
 def __init__(self,
              compiler: SolidityCompiler = None,
              ignore_solidity_check: bool = False,
              *args,
              **kwargs):
     super().__init__(*args, **kwargs)
     self.compiler = compiler or SolidityCompiler(
         ignore_solidity_check=ignore_solidity_check)
Example #10
0
 def _setup_solidity(self, compiler: SolidityCompiler = None):
     if compiler:
         # Execute the compilation if we're recompiling
         # Otherwise read compiled contract data from the registry.
         _raw_contract_cache = compiler.compile()
     else:
         _raw_contract_cache = NO_COMPILATION_PERFORMED
     self._raw_contract_cache = _raw_contract_cache
Example #11
0
    def __init__(self,
                 deployer_address: str = None,
                 compiler: SolidityCompiler = None,
                 *args, **kwargs):
        super().__init__(*args, **kwargs)

        self.compiler = compiler or SolidityCompiler()
        self.__deployer_address = deployer_address or NO_DEPLOYER_CONFIGURED
Example #12
0
 def _setup_solidity(self, compiler: SolidityCompiler = None) -> None:
     if self.dry_run:
         self.log.info("Dry run is active, skipping solidity compile steps.")
         return
     if compiler:
         # Execute the compilation if we're recompiling
         # Otherwise read compiled contract data from the registry.
         _raw_contract_cache = compiler.compile()
     else:
         _raw_contract_cache = NO_COMPILATION_PERFORMED
     self._raw_contract_cache = _raw_contract_cache
Example #13
0
def test_rapid_deployment(token_economics, test_registry):
    compiler = SolidityCompiler()
    allocation_registry = InMemoryAllocationRegistry()

    blockchain = _TesterBlockchain(eth_airdrop=False,
                                   test_accounts=4,
                                   compiler=compiler)

    # TODO: #1092 - TransactingPower
    blockchain.transacting_power = TransactingPower(password=INSECURE_DEVELOPMENT_PASSWORD,
                                                    account=blockchain.etherbase_account)
    blockchain.transacting_power.activate()
    deployer_address = blockchain.etherbase_account

    deployer = ContractAdministrator(deployer_address=deployer_address,
                                     registry=test_registry)

    secrets = dict()
    for deployer_class in deployer.upgradeable_deployer_classes:
        secrets[deployer_class.contract_name] = INSECURE_DEVELOPMENT_PASSWORD

    deployer.deploy_network_contracts(secrets=secrets, emitter=StdoutEmitter())

    all_yall = blockchain.unassigned_accounts

    # Start with some hard-coded cases...
    allocation_data = [{'beneficiary_address': all_yall[1],
                        'amount': token_economics.maximum_allowed_locked,
                        'duration_seconds': ONE_YEAR_IN_SECONDS},

                       {'beneficiary_address': all_yall[2],
                        'amount': token_economics.minimum_allowed_locked,
                        'duration_seconds': ONE_YEAR_IN_SECONDS*2},

                       {'beneficiary_address': all_yall[3],
                        'amount': token_economics.minimum_allowed_locked*100,
                        'duration_seconds': ONE_YEAR_IN_SECONDS*3}
                       ]

    # Pile on the rest
    for _ in range(NUMBER_OF_ALLOCATIONS_IN_TESTS - len(allocation_data)):
        random_password = ''.join(random.SystemRandom().choice(string.ascii_uppercase+string.digits) for _ in range(16))
        acct = w3.eth.account.create(random_password)
        beneficiary_address = acct.address
        amount = random.randint(token_economics.minimum_allowed_locked, token_economics.maximum_allowed_locked)
        duration = random.randint(token_economics.minimum_locked_periods*ONE_YEAR_IN_SECONDS,
                                  (token_economics.maximum_rewarded_periods*ONE_YEAR_IN_SECONDS)*3)
        random_allocation = {'beneficiary_address': beneficiary_address, 'amount': amount, 'duration_seconds': duration}
        allocation_data.append(random_allocation)

    deployer.deploy_beneficiary_contracts(allocations=allocation_data,
                                          allocation_registry=allocation_registry,
                                          interactive=False)
Example #14
0
def test_rapid_deployment(token_economics, test_registry, tmpdir, get_random_checksum_address):
    compiler = SolidityCompiler()

    blockchain = _TesterBlockchain(eth_airdrop=False,
                                   test_accounts=4,
                                   compiler=compiler)

    # TODO: #1092 - TransactingPower
    blockchain.transacting_power = TransactingPower(password=INSECURE_DEVELOPMENT_PASSWORD,
                                                    account=blockchain.etherbase_account)
    blockchain.transacting_power.activate()
    deployer_address = blockchain.etherbase_account

    administrator = ContractAdministrator(deployer_address=deployer_address,
                                          registry=test_registry)

    administrator.deploy_network_contracts(emitter=StdoutEmitter(), interactive=False)

    all_yall = blockchain.unassigned_accounts

    # Start with some hard-coded cases...
    allocation_data = [{'checksum_address': all_yall[1],
                        'amount': token_economics.maximum_allowed_locked,
                        'lock_periods': token_economics.minimum_locked_periods},

                       {'checksum_address': all_yall[2],
                        'amount': token_economics.minimum_allowed_locked,
                        'lock_periods': token_economics.minimum_locked_periods},

                       {'checksum_address': all_yall[3],
                        'amount': token_economics.minimum_allowed_locked*100,
                        'lock_periods': token_economics.minimum_locked_periods},
                       ]

    # Pile on the rest
    for _ in range(NUMBER_OF_ALLOCATIONS_IN_TESTS - len(allocation_data)):
        checksum_address = get_random_checksum_address()
        amount = random.randint(token_economics.minimum_allowed_locked, token_economics.maximum_allowed_locked)
        duration = random.randint(token_economics.minimum_locked_periods, token_economics.maximum_rewarded_periods)
        random_allocation = {'checksum_address': checksum_address, 'amount': amount, 'lock_periods': duration}
        allocation_data.append(random_allocation)

    filepath = tmpdir / "allocations.json"
    with open(filepath, 'w') as f:
        json.dump(allocation_data, f)

    administrator.batch_deposits(allocation_data_filepath=str(filepath), interactive=False)

    minimum, default, maximum = 10, 20, 30
    administrator.set_fee_rate_range(minimum, default, maximum)
def test_rapid_deployment(token_economics):
    compiler = SolidityCompiler()
    registry = InMemoryEthereumContractRegistry()
    allocation_registry = InMemoryAllocationRegistry()
    interface = BlockchainDeployerInterface(compiler=compiler,
                                            registry=registry,
                                            provider_uri='tester://pyevm')

    blockchain = TesterBlockchain(interface=interface, airdrop=False, test_accounts=4)
    deployer_address = blockchain.etherbase_account

    deployer = Deployer(blockchain=blockchain, deployer_address=deployer_address)

    # The Big Three (+ Dispatchers)
    deployer.deploy_network_contracts(miner_secret=MINERS_ESCROW_DEPLOYMENT_SECRET,
                                      policy_secret=POLICY_MANAGER_DEPLOYMENT_SECRET,
                                      adjudicator_secret=MINING_ADJUDICATOR_DEPLOYMENT_SECRET)

    # Deploy User Escrow, too (+ Linker)
    deployer.deploy_escrow_proxy(secret=USER_ESCROW_PROXY_DEPLOYMENT_SECRET)

    total_allocations = NUMBER_OF_ALLOCATIONS_IN_TESTS

    all_yall = blockchain.unassigned_accounts
    # Start with some hard-coded cases...
    allocation_data = [{'address': all_yall[1],
                        'amount': token_economics.maximum_allowed_locked,
                        'duration': ONE_YEAR_IN_SECONDS},

                       {'address': all_yall[2],
                        'amount': token_economics.minimum_allowed_locked,
                        'duration': ONE_YEAR_IN_SECONDS*2},

                       {'address': all_yall[3],
                        'amount': token_economics.minimum_allowed_locked*100,
                        'duration': ONE_YEAR_IN_SECONDS*3}
                       ]

    # Pile on the rest
    for _ in range(total_allocations - len(allocation_data)):
        random_password = ''.join(random.SystemRandom().choice(string.ascii_uppercase+string.digits) for _ in range(16))
        acct = w3.eth.account.create(random_password)
        beneficiary_address = acct.address
        amount = random.randint(token_economics.minimum_allowed_locked, token_economics.maximum_allowed_locked)
        duration = random.randint(token_economics.minimum_locked_periods*ONE_YEAR_IN_SECONDS,
                                  (token_economics.maximum_locked_periods*ONE_YEAR_IN_SECONDS)*3)
        random_allocation = {'address': beneficiary_address, 'amount': amount, 'duration': duration}
        allocation_data.append(random_allocation)

    deployer.deploy_beneficiary_contracts(allocations=allocation_data, allocation_registry=allocation_registry)
Example #16
0
    def bootstrap_network(cls) -> Tuple['TesterBlockchain', Dict[str, EthereumContractAgent]]:
        """For use with metric testing scripts"""

        testerchain = cls(compiler=SolidityCompiler())
        power = BlockchainPower(blockchain=testerchain, account=testerchain.client.etherbase)
        power.unlock_account(password=INSECURE_DEVELOPMENT_PASSWORD)
        testerchain.transacting_power = power

        origin = testerchain.client.etherbase
        deployer = Deployer(blockchain=testerchain, deployer_address=origin, bare=True)
        _txhashes, agents = deployer.deploy_network_contracts(staker_secret=STAKING_ESCROW_DEPLOYMENT_SECRET,
                                                              policy_secret=POLICY_MANAGER_DEPLOYMENT_SECRET,
                                                              adjudicator_secret=ADJUDICATOR_DEPLOYMENT_SECRET,
                                                              user_escrow_proxy_secret=USER_ESCROW_PROXY_DEPLOYMENT_SECRET)
        return testerchain, agents
Example #17
0
    def from_configuration_file(cls, config: NodeConfiguration) -> 'BlockchainInterface':
        # Parse
        payload = parse_blockchain_config(filepath=config.config_file_location)

        # Init deps
        compiler = SolidityCompiler() if payload['compile'] else None
        registry = EthereumContractRegistry.from_config(config=config)
        interface_class = BlockchainInterface if not payload['deploy'] else BlockchainDeployerInterface

        # init class
        interface = interface_class(timeout=payload['timeout'],
                                    provider_uri=payload['provider_uri'],
                                    compiler=compiler,
                                    registry=registry)

        return interface
Example #18
0
def deployed_blockchain():

    #
    # Interface
    #
    compiler = SolidityCompiler()
    registry = InMemoryEthereumContractRegistry()
    allocation_registry = InMemoryAllocationRegistry()
    interface = BlockchainDeployerInterface(compiler=compiler,
                                            registry=registry,
                                            provider_uri=TEST_PROVIDER_URI)

    #
    # Blockchain
    #
    blockchain = TesterBlockchain(interface=interface,
                                  airdrop=False,
                                  test_accounts=5,
                                  poa=True)
    blockchain.ether_airdrop(amount=TESTING_ETH_AIRDROP_AMOUNT)
    origin, *everyone = blockchain.interface.w3.eth.accounts

    #
    # Delpoyer
    #
    deployer = Deployer(blockchain=blockchain, deployer_address=origin)

    deployer_address, *all_yall = deployer.blockchain.interface.w3.eth.accounts

    # The Big Three (+ Dispatchers)
    deployer.deploy_network_contracts(miner_secret=os.urandom(32),
                                      policy_secret=os.urandom(32))

    # User Escrow Proxy
    deployer.deploy_escrow_proxy(secret=os.urandom(32))

    # Start with some hard-coded cases...
    allocation_data = [{
        'address': all_yall[1],
        'amount': MAX_ALLOWED_LOCKED,
        'duration': ONE_YEAR_IN_SECONDS
    }]

    deployer.deploy_beneficiary_contracts(
        allocations=allocation_data, allocation_registry=allocation_registry)

    yield blockchain, deployer_address, registry
Example #19
0
    def from_config(cls, filepath=None) -> 'BlockchainInterface':
        # Parse
        filepath = filepath if filepath is None else DEFAULT_INI_FILEPATH
        payload = parse_blockchain_config(filepath=filepath)

        # Init deps
        compiler = SolidityCompiler() if payload['compile'] else None
        registry = EthereumContractRegistry.from_config(filepath=filepath)
        interface_class = BlockchainInterface if not payload['deploy'] else BlockchainDeployerInterface

        # init class
        circumflex = interface_class(timeout=payload['timeout'],
                                     provider_uri=payload['provider_uri'],
                                     compiler=compiler,
                                     registry=registry)

        return circumflex
Example #20
0
def deployed_blockchain(token_economics):

    # Interface
    compiler = SolidityCompiler()
    registry = InMemoryEthereumContractRegistry()
    allocation_registry = InMemoryAllocationRegistry()
    interface = BlockchainDeployerInterface(compiler=compiler,
                                            registry=registry,
                                            provider_uri=TEST_PROVIDER_URI)

    # Blockchain
    blockchain = TesterBlockchain(interface=interface,
                                  airdrop=True,
                                  test_accounts=5,
                                  poa=True)
    deployer_address = blockchain.etherbase_account

    # Deployer
    deployer = Deployer(blockchain=blockchain,
                        deployer_address=deployer_address)

    # The Big Three (+ Dispatchers)
    deployer.deploy_network_contracts(miner_secret=os.urandom(32),
                                      policy_secret=os.urandom(32),
                                      adjudicator_secret=os.urandom(32))

    # User Escrow Proxy
    deployer.deploy_escrow_proxy(secret=os.urandom(32))

    # Start with some hard-coded cases...
    all_yall = blockchain.unassigned_accounts
    allocation_data = [{
        'address': all_yall[1],
        'amount': token_economics.maximum_allowed_locked,
        'duration': ONE_YEAR_IN_SECONDS
    }]

    deployer.deploy_beneficiary_contracts(
        allocations=allocation_data, allocation_registry=allocation_registry)

    yield blockchain, deployer_address, registry
Example #21
0
    def bootstrap_network(cls) -> 'TesterBlockchain':
        """For use with metric testing scripts"""

        testerchain = cls(compiler=SolidityCompiler())
        power = TransactingPower(blockchain=testerchain,
                                 password=INSECURE_DEVELOPMENT_PASSWORD,
                                 account=testerchain.etherbase_account)
        power.activate()
        testerchain.transacting_power = power

        origin = testerchain.client.etherbase
        deployer = DeployerActor(blockchain=testerchain,
                                 deployer_address=origin,
                                 bare=True)
        secrets = dict()
        for deployer_class in deployer.upgradeable_deployer_classes:
            secrets[
                deployer_class.contract_name] = INSECURE_DEVELOPMENT_PASSWORD
        _receipts = deployer.deploy_network_contracts(secrets=secrets,
                                                      interactive=False)
        return testerchain
Example #22
0
def test_multiversion_contract():
    # Prepare compiler
    base_dir = os.path.join(dirname(abspath(__file__)), "contracts",
                            "multiversion")
    v1_dir = os.path.join(base_dir, "v1")
    v2_dir = os.path.join(base_dir, "v2")
    root_dir = SolidityCompiler.default_contract_dir()
    solidity_compiler = SolidityCompiler(source_dirs=[
        SourceDirs(root_dir, {v2_dir}),
        SourceDirs(root_dir, {v1_dir})
    ])

    # Prepare chain
    blockchain_interface = BlockchainDeployerInterface(
        provider_uri='tester://pyevm/2', compiler=solidity_compiler)
    blockchain_interface.connect()
    origin = blockchain_interface.client.accounts[0]
    blockchain_interface.transacting_power = TransactingPower(
        password=INSECURE_DEVELOPMENT_PASSWORD, account=origin)
    blockchain_interface.transacting_power.activate()

    # Searching both contract through raw data
    contract_name = "VersionTest"
    requested_version = "v1.2.3"
    version, _data = blockchain_interface.find_raw_contract_data(
        contract_name=contract_name, requested_version=requested_version)
    assert version == requested_version
    version, _data = blockchain_interface.find_raw_contract_data(
        contract_name=contract_name, requested_version="latest")
    assert version == requested_version

    requested_version = "v1.1.4"
    version, _data = blockchain_interface.find_raw_contract_data(
        contract_name=contract_name, requested_version=requested_version)
    assert version == requested_version
    version, _data = blockchain_interface.find_raw_contract_data(
        contract_name=contract_name, requested_version="earliest")
    assert version == requested_version

    # Deploy different contracts and check their versions
    registry = InMemoryContractRegistry()
    contract, receipt = blockchain_interface.deploy_contract(
        deployer_address=origin,
        registry=registry,
        contract_name=contract_name,
        contract_version="v1.1.4")
    assert contract.version == "v1.1.4"
    assert contract.functions.VERSION().call() == 1
    contract, receipt = blockchain_interface.deploy_contract(
        deployer_address=origin,
        registry=registry,
        contract_name=contract_name,
        contract_version="earliest")
    assert contract.version == "v1.1.4"
    assert contract.functions.VERSION().call() == 1

    contract, receipt = blockchain_interface.deploy_contract(
        deployer_address=origin,
        registry=registry,
        contract_name=contract_name,
        contract_version="v1.2.3")
    assert contract.version == "v1.2.3"
    assert contract.functions.VERSION().call() == 2
    contract, receipt = blockchain_interface.deploy_contract(
        deployer_address=origin,
        registry=registry,
        contract_name=contract_name,
        contract_version="latest")
    assert contract.version == "v1.2.3"
    assert contract.functions.VERSION().call() == 2
    contract, receipt = blockchain_interface.deploy_contract(
        deployer_address=origin,
        registry=registry,
        contract_name=contract_name)
    assert contract.version == "v1.2.3"
    assert contract.functions.VERSION().call() == 2
Example #23
0
def solidity_compiler():
    """Doing this more than once per session will result in slower test run times."""
    compiler = SolidityCompiler()
    yield compiler
Example #24
0
class TesterBlockchain(BlockchainDeployerInterface):
    """
    Blockchain subclass with additional test utility methods and options.
    """

    _instance = None

    GAS_STRATEGIES = {
        **BlockchainDeployerInterface.GAS_STRATEGIES, 'free':
        free_gas_price_strategy
    }

    _PROVIDER_URI = 'tester://pyevm'
    TEST_CONTRACTS_DIR = os.path.join(BASE_DIR, 'tests', 'blockchain', 'eth',
                                      'contracts', 'contracts')
    _compiler = SolidityCompiler(
        source_dirs=[(SolidityCompiler.default_contract_dir(),
                      {TEST_CONTRACTS_DIR})])
    _test_account_cache = list()

    _default_test_accounts = NUMBER_OF_ETH_TEST_ACCOUNTS

    # Reserved addresses
    _ETHERBASE = 0
    _ALICE = 1
    _BOB = 2
    _FIRST_STAKER = 5
    _stakers_range = range(NUMBER_OF_STAKERS_IN_BLOCKCHAIN_TESTS)
    _FIRST_URSULA = _FIRST_STAKER + NUMBER_OF_STAKERS_IN_BLOCKCHAIN_TESTS
    _ursulas_range = range(NUMBER_OF_URSULAS_IN_BLOCKCHAIN_TESTS)

    _default_token_economics = StandardTokenEconomics()

    def __init__(self,
                 test_accounts=None,
                 poa=True,
                 light=False,
                 eth_airdrop=False,
                 free_transactions=False,
                 compiler: SolidityCompiler = None,
                 *args,
                 **kwargs):

        if not test_accounts:
            test_accounts = self._default_test_accounts
        self.free_transactions = free_transactions

        if compiler:
            TesterBlockchain._compiler = compiler

        super().__init__(provider_uri=self._PROVIDER_URI,
                         provider_process=None,
                         poa=poa,
                         light=light,
                         compiler=self._compiler,
                         *args,
                         **kwargs)

        self.log = Logger("test-blockchain")
        self.connect()

        # Generate additional ethereum accounts for testing
        population = test_accounts
        enough_accounts = len(self.client.accounts) >= population
        if not enough_accounts:
            accounts_to_make = population - len(self.client.accounts)
            self.__generate_insecure_unlocked_accounts(
                quantity=accounts_to_make)
            assert test_accounts == len(self.w3.eth.accounts)

        if eth_airdrop is True:  # ETH for everyone!
            self.ether_airdrop(amount=DEVELOPMENT_ETH_AIRDROP_AMOUNT)

    def attach_middleware(self):
        if self.free_transactions:
            self.w3.eth.setGasPriceStrategy(free_gas_price_strategy)

    def __generate_insecure_unlocked_accounts(self,
                                              quantity: int) -> List[str]:

        #
        # Sanity Check - Only PyEVM can be used.
        #

        # Detect provider platform
        client_version = self.w3.clientVersion

        if 'Geth' in client_version:
            raise RuntimeError("WARNING: Geth providers are not implemented.")
        elif "Parity" in client_version:
            raise RuntimeError(
                "WARNING: Parity providers are not implemented.")

        addresses = list()
        for _ in range(quantity):
            address = self.provider.ethereum_tester.add_account(
                '0x' + os.urandom(32).hex())
            addresses.append(address)
            self._test_account_cache.append(address)
            self.log.info('Generated new insecure account {}'.format(address))
        return addresses

    def ether_airdrop(self, amount: int) -> List[str]:
        """Airdrops ether from creator address to all other addresses!"""

        coinbase, *addresses = self.w3.eth.accounts

        tx_hashes = list()
        for address in addresses:
            tx = {'to': address, 'from': coinbase, 'value': amount}
            txhash = self.w3.eth.sendTransaction(tx)

            _receipt = self.wait_for_receipt(txhash)
            tx_hashes.append(txhash)
            eth_amount = Web3().fromWei(amount, 'ether')
            self.log.info("Airdropped {} ETH {} -> {}".format(
                eth_amount, tx['from'], tx['to']))

        return tx_hashes

    def time_travel(self,
                    hours: int = None,
                    seconds: int = None,
                    periods: int = None):
        """
        Wait the specified number of wait_hours by comparing
        block timestamps and mines a single block.
        """

        more_than_one_arg = sum(map(bool, (hours, seconds, periods))) > 1
        if more_than_one_arg:
            raise ValueError(
                "Specify hours, seconds, or periods, not a combination")

        if periods:
            duration = self._default_token_economics.seconds_per_period * periods
            base = self._default_token_economics.seconds_per_period
        elif hours:
            duration = hours * (60 * 60)
            base = 60 * 60
        elif seconds:
            duration = seconds
            base = 1
        else:
            raise ValueError("Specify either hours, seconds, or periods.")

        now = self.w3.eth.getBlock(block_identifier='latest').timestamp
        end_timestamp = ((now + duration) // base) * base

        self.w3.eth.web3.testing.timeTravel(timestamp=end_timestamp)
        self.w3.eth.web3.testing.mine(1)

        delta = maya.timedelta(seconds=end_timestamp - now)
        self.log.info(
            f"Time traveled {delta} "
            f"| period {epoch_to_period(epoch=end_timestamp, seconds_per_period=self._default_token_economics.seconds_per_period)} "
            f"| epoch {end_timestamp}")

    @classmethod
    def bootstrap_network(
        cls,
        economics: BaseEconomics = None
    ) -> Tuple['TesterBlockchain', 'InMemoryContractRegistry']:
        """For use with metric testing scripts"""

        registry = InMemoryContractRegistry()
        testerchain = cls(compiler=SolidityCompiler())
        BlockchainInterfaceFactory.register_interface(testerchain)
        power = TransactingPower(password=INSECURE_DEVELOPMENT_PASSWORD,
                                 account=testerchain.etherbase_account)
        power.activate()
        testerchain.transacting_power = power

        origin = testerchain.client.etherbase
        deployer = ContractAdministrator(deployer_address=origin,
                                         registry=registry,
                                         economics=economics
                                         or cls._default_token_economics,
                                         staking_escrow_test_mode=True)
        secrets = dict()
        for deployer_class in deployer.upgradeable_deployer_classes:
            secrets[
                deployer_class.contract_name] = INSECURE_DEVELOPMENT_PASSWORD
        _receipts = deployer.deploy_network_contracts(secrets=secrets,
                                                      interactive=False)
        return testerchain, registry

    @property
    def etherbase_account(self):
        return self.client.accounts[self._ETHERBASE]

    @property
    def alice_account(self):
        return self.client.accounts[self._ALICE]

    @property
    def bob_account(self):
        return self.client.accounts[self._BOB]

    def ursula_account(self, index):
        if index not in self._ursulas_range:
            raise ValueError(
                f"Ursula index must be lower than {NUMBER_OF_URSULAS_IN_BLOCKCHAIN_TESTS}"
            )
        return self.client.accounts[index + self._FIRST_URSULA]

    def staker_account(self, index):
        if index not in self._stakers_range:
            raise ValueError(
                f"Staker index must be lower than {NUMBER_OF_STAKERS_IN_BLOCKCHAIN_TESTS}"
            )
        return self.client.accounts[index + self._FIRST_STAKER]

    @property
    def ursulas_accounts(self):
        return list(self.ursula_account(i) for i in self._ursulas_range)

    @property
    def stakers_accounts(self):
        return list(self.staker_account(i) for i in self._stakers_range)

    @property
    def unassigned_accounts(self):
        special_accounts = [
            self.etherbase_account, self.alice_account, self.bob_account
        ]
        assigned_accounts = set(self.stakers_accounts + self.ursulas_accounts +
                                special_accounts)
        accounts = set(self.client.accounts)
        return list(accounts.difference(assigned_accounts))

    def wait_for_receipt(self, txhash: bytes, timeout: int = None) -> dict:
        """Wait for a transaction receipt and return it"""
        timeout = timeout or self.TIMEOUT
        result = self.w3.eth.waitForTransactionReceipt(txhash, timeout=timeout)
        if result.status == 0:
            raise TransactionFailed()
        return result
Example #25
0
def solidity_compiler():
    """Doing this more than once per session will result in slower test run times."""
    compiler = SolidityCompiler(test_contract_dir=TEST_CONTRACTS_DIR)
    yield compiler
Example #26
0
 def __init__(self, compiler: SolidityCompiler = None, *args, **kwargs):
     super().__init__(*args, **kwargs)
     self.compiler = compiler or SolidityCompiler()
Example #27
0
def geth_poa_devchain():
    _testerchain = make_testerchain(provider_uri='tester://geth', solidity_compiler=SolidityCompiler())
    return f'ipc://{_testerchain.interface.provider.ipc_path}'
Example #28
0
def deploy(click_config, action, poa, provider_uri, geth, enode,
           deployer_address, contract_name, allocation_infile,
           allocation_outfile, registry_infile, registry_outfile, no_compile,
           amount, recipient_address, config_root, sync, force):
    """Manage contract and registry deployment"""

    ETH_NODE = None

    #
    # 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)

    #
    # Connect to Blockchain
    #

    if geth:
        # Spawn geth child process
        ETH_NODE = NuCypherGethDevnetProcess(config_root=config_root)
        ETH_NODE.ensure_account_exists(password=click_config.get_password(
            confirm=True))
        ETH_NODE.start()  # TODO: Graceful shutdown
        provider_uri = ETH_NODE.provider_uri

    # Establish a contract registry from disk if specified
    registry, registry_filepath = None, (registry_outfile or registry_infile)
    if registry_filepath is not None:
        registry = EthereumContractRegistry(
            registry_filepath=registry_filepath)

    # Deployment-tuned blockchain connection
    blockchain = BlockchainDeployerInterface(provider_uri=provider_uri,
                                             poa=poa,
                                             registry=registry,
                                             compiler=SolidityCompiler(),
                                             fetch_registry=False,
                                             sync_now=sync)

    #
    # Deployment Actor
    #

    if not deployer_address:
        for index, address in enumerate(blockchain.client.accounts):
            click.secho(f"{index} --- {address}")
        choices = click.IntRange(0, len(blockchain.client.accounts))
        deployer_address_index = click.prompt("Select deployer address",
                                              default=0,
                                              type=choices)
        deployer_address = blockchain.client.accounts[deployer_address_index]

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

    # TODO: Integrate with Deployer Actor (Character)
    blockchain.transacting_power = BlockchainPower(blockchain=blockchain,
                                                   account=deployer_address)
    deployer = Deployer(blockchain=blockchain,
                        deployer_address=deployer_address)

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

    if not blockchain.client.is_local:
        # (~ dev mode; Assume accounts are already unlocked)
        password = click.prompt("Enter ETH node password", hide_input=True)
        blockchain.client.unlockAccount(deployer_address, password)

    # Add ETH Bootnode or Peer
    if enode:
        if geth:
            blockchain.w3.geth.admin.addPeer(enode)
            click.secho(f"Added ethereum peer {enode}")
        else:
            raise NotImplemented  # TODO: other backends

    #
    # 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)
        deployer.upgrade_contract(contract_name=contract_name,
                                  existing_plaintext_secret=existing_secret,
                                  new_plaintext_secret=new_secret)

    elif action == '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)
        deployer.rollback_contract(contract_name=contract_name,
                                   existing_plaintext_secret=existing_secret,
                                   new_plaintext_secret=new_secret)

    elif action == "contracts":

        registry_filepath = deployer.blockchain.registry.filepath
        if os.path.isfile(registry_filepath):
            click.secho(
                f"\nThere is an existing contract registry at {registry_filepath}.\n"
                f"Did you mean 'nucypher-deploy upgrade'?\n",
                fg='yellow')
            click.confirm(
                "Optionally, destroy existing local registry and continue?",
                abort=True)
            click.confirm(
                f"Confirm deletion of contract registry '{registry_filepath}'?",
                abort=True)
            os.remove(registry_filepath)

        #
        # Deploy Single Contract
        #

        if contract_name:
            # TODO: Handle secret collection for single contract deployment

            try:
                deployer_func = deployer.deployers[contract_name]
            except KeyError:
                message = f"No such contract {contract_name}. Available contracts are {deployer.deployers.keys()}"
                click.secho(message, fg='red', bold=True)
                raise click.Abort()
            else:
                # Deploy single contract
                _txs, _agent = deployer_func()

            # TODO: Painting for single contract deployment
            if ETH_NODE:
                ETH_NODE.stop()
            return

        #
        # Stage Deployment
        #

        # Track tx hashes, and new agents
        __deployment_transactions = dict()
        __deployment_agents = dict()

        secrets = click_config.collect_deployment_secrets()
        click.clear()
        click.secho(NU_BANNER)

        w3 = deployer.blockchain.w3
        click.secho(f"Current Time ........ {maya.now().iso8601()}")
        click.secho(
            f"Web3 Provider ....... {deployer.blockchain.provider_uri}")
        click.secho(
            f"Block ............... {deployer.blockchain.client.block_number}")
        click.secho(
            f"Gas Price ........... {deployer.blockchain.client.gas_price}")

        click.secho(f"Deployer Address .... {deployer.checksum_address}")
        click.secho(f"ETH ................. {deployer.eth_balance}")
        click.secho(
            f"Chain ID ............ {deployer.blockchain.client.chain_id}")
        click.secho(
            f"Chain Name .......... {deployer.blockchain.client.chain_name}")

        # Ask - Last chance to gracefully abort
        if not force:
            click.secho(
                "\nDeployment successfully staged. Take a deep breath. \n",
                fg='green')
            if click.prompt("Type 'DEPLOY' to continue") != 'DEPLOY':
                raise click.Abort()

        # Delay - Last chance to crash and abort
        click.secho(f"Starting deployment in 3 seconds...", fg='red')
        time.sleep(1)
        click.secho(f"2...", fg='yellow')
        time.sleep(1)
        click.secho(f"1...", fg='green')
        time.sleep(1)
        click.secho(f"Deploying...", bold=True)

        #
        # DEPLOY < -------
        #

        txhashes, deployers = deployer.deploy_network_contracts(
            staker_secret=secrets.staker_secret,
            policy_secret=secrets.policy_secret,
            adjudicator_secret=secrets.adjudicator_secret,
            user_escrow_proxy_secret=secrets.escrow_proxy_secret)

        # Success
        __deployment_transactions.update(txhashes)

        #
        # Paint
        #

        total_gas_used = 0  # TODO: may be faulty
        for contract_name, transactions in __deployment_transactions.items():

            # Paint heading
            heading = '\n{} ({})'.format(
                contract_name, deployers[contract_name].contract_address)
            click.secho(heading, bold=True)
            click.echo('*' * (42 + 3 + len(contract_name)))

            for tx_name, txhash in transactions.items():

                # Wait for inclusion in the blockchain
                receipt = deployer.blockchain.w3.eth.waitForTransactionReceipt(
                    txhash)
                click.secho("OK", fg='green', nl=False, bold=True)

                # Accumulate gas
                total_gas_used += int(receipt['gasUsed'])

                # Paint
                click.secho(" | {}".format(tx_name), fg='yellow', nl=False)
                click.secho(" | {}".format(txhash.hex()),
                            fg='yellow',
                            nl=False)
                click.secho(" ({} gas)".format(receipt['cumulativeGasUsed']))
                click.secho("Block #{} | {}\n".format(
                    receipt['blockNumber'], receipt['blockHash'].hex()))

        # Paint outfile paths
        click.secho(
            "Cumulative Gas Consumption: {} gas".format(total_gas_used),
            bold=True,
            fg='blue')
        registry_outfile = deployer.blockchain.registry.filepath
        click.secho('Generated registry {}'.format(registry_outfile),
                    bold=True,
                    fg='blue')

        # Save transaction metadata
        receipts_filepath = deployer.save_deployment_receipts(
            transactions=__deployment_transactions)
        click.secho(f"Saved deployment receipts to {receipts_filepath}",
                    fg='blue',
                    bold=True)

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

    elif action == "transfer":
        token_agent = NucypherTokenAgent(blockchain=blockchain)
        click.confirm(
            f"Transfer {amount} from {token_agent.contract_address} to {recipient_address}?",
            abort=True)
        txhash = token_agent.transfer(
            amount=amount,
            sender_address=token_agent.contract_address,
            target_address=recipient_address)
        click.secho(f"OK | {txhash}")

    elif action == "destroy-registry":
        registry_filepath = deployer.blockchain.registry.filepath
        click.confirm(
            f"Are you absolutely sure you want to destroy the contract registry at {registry_filepath}?",
            abort=True)
        os.remove(registry_filepath)
        click.secho(f"Successfully destroyed {registry_filepath}", fg='red')

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

    if ETH_NODE:
        ETH_NODE.stop()
Example #29
0
def solidity_compiler():
    """Doing this more than once per session will result in slower test run times."""
    test_contracts_dir = os.path.join(dirname(abspath(contracts.__file__)),
                                      'contracts')
    compiler = SolidityCompiler(test_contract_dir=test_contracts_dir)
    yield compiler
Example #30
0
def estimate_gas():
    solidity_compiler = SolidityCompiler(test_contract_dir=CONTRACTS_DIR)

    # create a temporary registrar for the tester blockchain
    temporary_registry = TemporaryEthereumContractRegistry()

    # Configure a custom provider
    overrides = {'gas_limit': 4626271}
    pyevm_backend = OverridablePyEVMBackend(genesis_overrides=overrides)

    eth_tester = EthereumTester(backend=pyevm_backend,
                                auto_mine_transactions=True)
    pyevm_provider = EthereumTesterProvider(ethereum_tester=eth_tester)

    # Use the the custom provider and registrar to init an interface
    circumflex = DeployerCircumflex(
        compiler=solidity_compiler,  # freshly recompile
        registry=temporary_registry,  # use temporary registrar
        providers=(pyevm_provider, ))  # use custom test provider

    # Create the blockchain
    testerchain = TesterBlockchain(interface=circumflex, test_accounts=10)
    origin, ursula1, ursula2, ursula3, alice1, *everyone_else = testerchain.interface.w3.eth.accounts
    circumflex.deployer_address = origin  # Set the deployer address from a freshly created test account

    token_deployer = NucypherTokenDeployer(blockchain=testerchain,
                                           deployer_address=origin)
    token_deployer.arm()
    token_deployer.deploy()
    token_agent = token_deployer.make_agent()

    miner_escrow_deployer = MinerEscrowDeployer(token_agent=token_agent,
                                                deployer_address=origin)
    miner_escrow_deployer.arm()
    miner_escrow_deployer.deploy()
    miner_agent = miner_escrow_deployer.make_agent()

    policy_manager_deployer = PolicyManagerDeployer(miner_agent=miner_agent,
                                                    deployer_address=origin)
    policy_manager_deployer.arm()
    policy_manager_deployer.deploy()
    policy_agent = policy_manager_deployer.make_agent()

    web3 = testerchain.interface.w3

    print("Estimate gas:")
    # Pre deposit tokens
    tx = token_agent.contract.functions.approve(miner_agent.contract_address, constants.MIN_ALLOWED_LOCKED * 5)\
        .transact({'from': origin})
    testerchain.wait_for_receipt(tx)
    print("Pre-deposit tokens for 5 owners = " + str(
        miner_agent.contract.functions.preDeposit(
            everyone_else[0:5], [int(constants.MIN_ALLOWED_LOCKED)] *
            5, [int(constants.MIN_LOCKED_PERIODS)] *
            5).estimateGas({'from': origin})))

    # Give Ursula and Alice some coins
    print("Transfer tokens = " + str(
        token_agent.contract.functions.transfer(
            ursula1, constants.MIN_ALLOWED_LOCKED *
            10).estimateGas({'from': origin})))
    tx = token_agent.contract.functions.transfer(
        ursula1, constants.MIN_ALLOWED_LOCKED * 10).transact({'from': origin})
    testerchain.wait_for_receipt(tx)
    tx = token_agent.contract.functions.transfer(
        ursula2, constants.MIN_ALLOWED_LOCKED * 10).transact({'from': origin})
    testerchain.wait_for_receipt(tx)
    tx = token_agent.contract.functions.transfer(
        ursula3, constants.MIN_ALLOWED_LOCKED * 10).transact({'from': origin})
    testerchain.wait_for_receipt(tx)

    # Ursula and Alice give Escrow rights to transfer
    print("Approving transfer = " + str(
        token_agent.contract.functions.approve(
            miner_agent.contract_address, constants.MIN_ALLOWED_LOCKED *
            6).estimateGas({'from': ursula1})))
    tx = token_agent.contract.functions.approve(miner_agent.contract_address, constants.MIN_ALLOWED_LOCKED * 6)\
        .transact({'from': ursula1})
    testerchain.wait_for_receipt(tx)
    tx = token_agent.contract.functions.approve(miner_agent.contract_address, constants.MIN_ALLOWED_LOCKED * 6)\
        .transact({'from': ursula2})
    testerchain.wait_for_receipt(tx)
    tx = token_agent.contract.functions.approve(miner_agent.contract_address, constants.MIN_ALLOWED_LOCKED * 6)\
        .transact({'from': ursula3})
    testerchain.wait_for_receipt(tx)

    # Ursula and Alice transfer some tokens to the escrow and lock them
    print("First initial deposit tokens = " + str(
        miner_agent.contract.functions.deposit(
            constants.MIN_ALLOWED_LOCKED * 3, int(
                constants.MIN_LOCKED_PERIODS)).estimateGas({'from': ursula1})))
    tx = miner_agent.contract.functions.deposit(constants.MIN_ALLOWED_LOCKED * 3, int(constants.MIN_LOCKED_PERIODS))\
        .transact({'from': ursula1})
    testerchain.wait_for_receipt(tx)
    print("Second initial deposit tokens = " + str(
        miner_agent.contract.functions.deposit(
            constants.MIN_ALLOWED_LOCKED * 3, int(
                constants.MIN_LOCKED_PERIODS)).estimateGas({'from': ursula2})))
    tx = miner_agent.contract.functions.deposit(constants.MIN_ALLOWED_LOCKED * 3, int(constants.MIN_LOCKED_PERIODS))\
        .transact({'from': ursula2})
    testerchain.wait_for_receipt(tx)
    print("Third initial deposit tokens = " + str(
        miner_agent.contract.functions.deposit(
            constants.MIN_ALLOWED_LOCKED * 3, int(
                constants.MIN_LOCKED_PERIODS)).estimateGas({'from': ursula3})))
    tx = miner_agent.contract.functions.deposit(constants.MIN_ALLOWED_LOCKED * 3, int(constants.MIN_LOCKED_PERIODS))\
        .transact({'from': ursula3})
    testerchain.wait_for_receipt(tx)

    # Wait 1 period and confirm activity
    testerchain.time_travel(periods=1)
    print("First confirm activity = " +
          str(miner_agent.contract.functions.confirmActivity().estimateGas(
              {'from': ursula1})))
    tx = miner_agent.contract.functions.confirmActivity().transact(
        {'from': ursula1})
    testerchain.wait_for_receipt(tx)
    print("Second confirm activity = " +
          str(miner_agent.contract.functions.confirmActivity().estimateGas(
              {'from': ursula2})))
    tx = miner_agent.contract.functions.confirmActivity().transact(
        {'from': ursula2})
    testerchain.wait_for_receipt(tx)
    print("Third confirm activity = " +
          str(miner_agent.contract.functions.confirmActivity().estimateGas(
              {'from': ursula3})))
    tx = miner_agent.contract.functions.confirmActivity().transact(
        {'from': ursula3})
    testerchain.wait_for_receipt(tx)

    # Wait 1 period and mint tokens
    testerchain.time_travel(periods=1)
    print("First mining (1 stake) = " + str(
        miner_agent.contract.functions.mint().estimateGas({'from': ursula1})))
    tx = miner_agent.contract.functions.mint().transact({'from': ursula1})
    testerchain.wait_for_receipt(tx)
    print("Second mining (1 stake) = " + str(
        miner_agent.contract.functions.mint().estimateGas({'from': ursula2})))
    tx = miner_agent.contract.functions.mint().transact({'from': ursula2})
    testerchain.wait_for_receipt(tx)
    print("Third/last mining (1 stake) = " + str(
        miner_agent.contract.functions.mint().estimateGas({'from': ursula3})))
    tx = miner_agent.contract.functions.mint().transact({'from': ursula3})
    testerchain.wait_for_receipt(tx)

    print("First confirm activity again = " +
          str(miner_agent.contract.functions.confirmActivity().estimateGas(
              {'from': ursula1})))
    tx = miner_agent.contract.functions.confirmActivity().transact(
        {'from': ursula1})
    testerchain.wait_for_receipt(tx)
    print("Second confirm activity again = " +
          str(miner_agent.contract.functions.confirmActivity().estimateGas(
              {'from': ursula2})))
    tx = miner_agent.contract.functions.confirmActivity().transact(
        {'from': ursula2})
    testerchain.wait_for_receipt(tx)
    print("Third confirm activity again = " +
          str(miner_agent.contract.functions.confirmActivity().estimateGas(
              {'from': ursula3})))
    tx = miner_agent.contract.functions.confirmActivity().transact(
        {'from': ursula3})
    testerchain.wait_for_receipt(tx)

    # Confirm again
    testerchain.time_travel(periods=1)
    print("First confirm activity + mint = " +
          str(miner_agent.contract.functions.confirmActivity().estimateGas(
              {'from': ursula1})))
    tx = miner_agent.contract.functions.confirmActivity().transact(
        {'from': ursula1})
    testerchain.wait_for_receipt(tx)
    print("Second confirm activity + mint = " +
          str(miner_agent.contract.functions.confirmActivity().estimateGas(
              {'from': ursula2})))
    tx = miner_agent.contract.functions.confirmActivity().transact(
        {'from': ursula2})
    testerchain.wait_for_receipt(tx)
    print("Third confirm activity + mint = " +
          str(miner_agent.contract.functions.confirmActivity().estimateGas(
              {'from': ursula3})))
    tx = miner_agent.contract.functions.confirmActivity().transact(
        {'from': ursula3})
    testerchain.wait_for_receipt(tx)

    # Get locked tokens
    print("Getting locked tokens = " + str(
        miner_agent.contract.functions.getLockedTokens(ursula1).estimateGas()))

    # Wait 1 period and withdraw tokens
    testerchain.time_travel(periods=1)
    print("First withdraw = " + str(
        miner_agent.contract.functions.withdraw(1).estimateGas(
            {'from': ursula1})))
    tx = miner_agent.contract.functions.withdraw(1).transact({'from': ursula1})
    testerchain.wait_for_receipt(tx)
    print("Second withdraw = " + str(
        miner_agent.contract.functions.withdraw(1).estimateGas(
            {'from': ursula2})))
    tx = miner_agent.contract.functions.withdraw(1).transact({'from': ursula2})
    testerchain.wait_for_receipt(tx)
    print("Third withdraw = " + str(
        miner_agent.contract.functions.withdraw(1).estimateGas(
            {'from': ursula3})))
    tx = miner_agent.contract.functions.withdraw(1).transact({'from': ursula3})
    testerchain.wait_for_receipt(tx)

    # Wait 1 period and confirm activity
    testerchain.time_travel(periods=1)
    print("First confirm activity after downtime = " +
          str(miner_agent.contract.functions.confirmActivity().estimateGas(
              {'from': ursula1})))
    tx = miner_agent.contract.functions.confirmActivity().transact(
        {'from': ursula1})
    testerchain.wait_for_receipt(tx)
    print("Second confirm activity after downtime  = " +
          str(miner_agent.contract.functions.confirmActivity().estimateGas(
              {'from': ursula2})))
    tx = miner_agent.contract.functions.confirmActivity().transact(
        {'from': ursula2})
    testerchain.wait_for_receipt(tx)
    print("Third confirm activity after downtime  = " +
          str(miner_agent.contract.functions.confirmActivity().estimateGas(
              {'from': ursula3})))
    tx = miner_agent.contract.functions.confirmActivity().transact(
        {'from': ursula3})
    testerchain.wait_for_receipt(tx)

    # Ursula and Alice deposit some tokens to the escrow again
    print("First deposit tokens again = " + str(
        miner_agent.contract.functions.deposit(
            constants.MIN_ALLOWED_LOCKED * 2, int(
                constants.MIN_LOCKED_PERIODS)).estimateGas({'from': ursula1})))
    tx = miner_agent.contract.functions.deposit(constants.MIN_ALLOWED_LOCKED * 2, int(constants.MIN_LOCKED_PERIODS))\
        .transact({'from': ursula1})
    testerchain.wait_for_receipt(tx)
    print("Second deposit tokens again = " + str(
        miner_agent.contract.functions.deposit(
            constants.MIN_ALLOWED_LOCKED * 2, int(
                constants.MIN_LOCKED_PERIODS)).estimateGas({'from': ursula2})))
    tx = miner_agent.contract.functions.deposit(constants.MIN_ALLOWED_LOCKED * 2, int(constants.MIN_LOCKED_PERIODS))\
        .transact({'from': ursula2})
    testerchain.wait_for_receipt(tx)
    print("Third deposit tokens again = " + str(
        miner_agent.contract.functions.deposit(
            constants.MIN_ALLOWED_LOCKED * 2, int(
                constants.MIN_LOCKED_PERIODS)).estimateGas({'from': ursula3})))
    tx = miner_agent.contract.functions.deposit(constants.MIN_ALLOWED_LOCKED * 2, int(constants.MIN_LOCKED_PERIODS))\
        .transact({'from': ursula3})
    testerchain.wait_for_receipt(tx)

    # Wait 1 period and mint tokens
    testerchain.time_travel(periods=1)
    print("First mining again = " + str(
        miner_agent.contract.functions.mint().estimateGas({'from': ursula1})))
    tx = miner_agent.contract.functions.mint().transact({'from': ursula1})
    testerchain.wait_for_receipt(tx)
    print("Second mining again = " + str(
        miner_agent.contract.functions.mint().estimateGas({'from': ursula2})))
    tx = miner_agent.contract.functions.mint().transact({'from': ursula2})
    testerchain.wait_for_receipt(tx)
    print("Third/last mining again = " + str(
        miner_agent.contract.functions.mint().estimateGas({'from': ursula3})))
    tx = miner_agent.contract.functions.mint().transact({'from': ursula3})
    testerchain.wait_for_receipt(tx)

    # Create policy
    policy_id_1 = os.urandom(int(constants.POLICY_ID_LENGTH))
    policy_id_2 = os.urandom(int(constants.POLICY_ID_LENGTH))
    number_of_periods = 10
    print("First creating policy (1 node, 10 periods) = " + str(
        policy_agent.contract.functions.createPolicy(
            policy_id_1, number_of_periods, 0, [ursula1]).estimateGas(
                {
                    'from': alice1,
                    'value': 10000
                })))
    tx = policy_agent.contract.functions.createPolicy(policy_id_1, number_of_periods, 0, [ursula1])\
        .transact({'from': alice1, 'value': 10000})
    testerchain.wait_for_receipt(tx)
    print("Second creating policy (1 node, 10 periods) = " + str(
        policy_agent.contract.functions.createPolicy(
            policy_id_2, number_of_periods, 0, [ursula1]).estimateGas(
                {
                    'from': alice1,
                    'value': 10000
                })))
    tx = policy_agent.contract.functions.createPolicy(policy_id_2, number_of_periods, 0, [ursula1])\
        .transact({'from': alice1, 'value': 10000})
    testerchain.wait_for_receipt(tx)

    # Revoke policy
    print("Revoking policy = " + str(
        policy_agent.contract.functions.revokePolicy(policy_id_1).estimateGas(
            {'from': alice1})))
    tx = policy_agent.contract.functions.revokePolicy(policy_id_1).transact(
        {'from': alice1})
    testerchain.wait_for_receipt(tx)
    tx = policy_agent.contract.functions.revokePolicy(policy_id_2).transact(
        {'from': alice1})
    testerchain.wait_for_receipt(tx)

    # Create policy with more periods
    policy_id_1 = os.urandom(int(constants.POLICY_ID_LENGTH))
    policy_id_2 = os.urandom(int(constants.POLICY_ID_LENGTH))
    policy_id_3 = os.urandom(int(constants.POLICY_ID_LENGTH))
    number_of_periods = 100
    print("First creating policy (1 node, " + str(number_of_periods) +
          " periods, first reward) = " + str(
              policy_agent.contract.functions.createPolicy(
                  policy_id_1, number_of_periods, 50, [ursula2]).estimateGas(
                      {
                          'from': alice1,
                          'value': 10050
                      })))
    tx = policy_agent.contract.functions.createPolicy(policy_id_1, number_of_periods, 50, [ursula2])\
        .transact({'from': alice1, 'value': 10050})
    testerchain.wait_for_receipt(tx)
    testerchain.time_travel(periods=1)
    print("Second creating policy (1 node, " + str(number_of_periods) +
          " periods, first reward) = " + str(
              policy_agent.contract.functions.createPolicy(
                  policy_id_2, number_of_periods, 50, [ursula2]).estimateGas(
                      {
                          'from': alice1,
                          'value': 10050
                      })))
    tx = policy_agent.contract.functions.createPolicy(policy_id_2, number_of_periods, 50, [ursula2])\
        .transact({'from': alice1, 'value': 10050})
    testerchain.wait_for_receipt(tx)
    print("Third creating policy (1 node, " + str(number_of_periods) +
          " periods, first reward) = " + str(
              policy_agent.contract.functions.createPolicy(
                  policy_id_3, number_of_periods, 50, [ursula1]).estimateGas(
                      {
                          'from': alice1,
                          'value': 10050
                      })))
    tx = policy_agent.contract.functions.createPolicy(policy_id_3, number_of_periods, 50, [ursula1])\
        .transact({'from': alice1, 'value': 10050})
    testerchain.wait_for_receipt(tx)

    # Mine and revoke policy
    testerchain.time_travel(periods=10)
    tx = miner_agent.contract.functions.confirmActivity().transact(
        {'from': ursula2})
    testerchain.wait_for_receipt(tx)
    tx = miner_agent.contract.functions.confirmActivity().transact(
        {'from': ursula1})
    testerchain.wait_for_receipt(tx)

    testerchain.time_travel(periods=1)
    print("First mining after downtime = " + str(
        miner_agent.contract.functions.mint().estimateGas({'from': ursula1})))
    tx = miner_agent.contract.functions.mint().transact({'from': ursula1})
    testerchain.wait_for_receipt(tx)
    print("Second mining after downtime = " + str(
        miner_agent.contract.functions.mint().estimateGas({'from': ursula2})))
    tx = miner_agent.contract.functions.mint().transact({'from': ursula2})
    testerchain.wait_for_receipt(tx)

    testerchain.time_travel(periods=10)
    print("First revoking policy after downtime = " + str(
        policy_agent.contract.functions.revokePolicy(policy_id_1).estimateGas(
            {'from': alice1})))
    tx = policy_agent.contract.functions.revokePolicy(policy_id_1).transact(
        {'from': alice1})
    testerchain.wait_for_receipt(tx)
    print("Second revoking policy after downtime = " + str(
        policy_agent.contract.functions.revokePolicy(policy_id_2).estimateGas(
            {'from': alice1})))
    tx = policy_agent.contract.functions.revokePolicy(policy_id_2).transact(
        {'from': alice1})
    testerchain.wait_for_receipt(tx)
    print("Second revoking policy after downtime = " + str(
        policy_agent.contract.functions.revokePolicy(policy_id_3).estimateGas(
            {'from': alice1})))
    tx = policy_agent.contract.functions.revokePolicy(policy_id_3).transact(
        {'from': alice1})
    testerchain.wait_for_receipt(tx)

    # Create policy with multiple nodes
    policy_id_1 = os.urandom(int(constants.POLICY_ID_LENGTH))
    policy_id_2 = os.urandom(int(constants.POLICY_ID_LENGTH))
    policy_id_3 = os.urandom(int(constants.POLICY_ID_LENGTH))
    number_of_periods = 100
    print("First creating policy (3 nodes, 100 periods, first reward) = " +
          str(
              policy_agent.contract.functions.createPolicy(
                  policy_id_1, number_of_periods, 50,
                  [ursula1, ursula2, ursula3]).estimateGas({
                      'from': alice1,
                      'value': 30150
                  })))
    tx = policy_agent.contract.functions.createPolicy(policy_id_1, number_of_periods, 50, [ursula1, ursula2, ursula3])\
        .transact({'from': alice1, 'value': 30150})
    testerchain.wait_for_receipt(tx)
    print("Second creating policy (3 nodes, 100 periods, first reward) = " +
          str(
              policy_agent.contract.functions.createPolicy(
                  policy_id_2, number_of_periods, 50,
                  [ursula1, ursula2, ursula3]).estimateGas({
                      'from': alice1,
                      'value': 30150
                  })))
    tx = policy_agent.contract.functions.createPolicy(policy_id_2, number_of_periods, 50, [ursula1, ursula2, ursula3])\
        .transact({'from': alice1, 'value': 30150})
    testerchain.wait_for_receipt(tx)
    print("Third creating policy (2 nodes, 100 periods, first reward) = " +
          str(
              policy_agent.contract.functions.createPolicy(
                  policy_id_3, number_of_periods, 50,
                  [ursula1, ursula2]).estimateGas({
                      'from': alice1,
                      'value': 20100
                  })))
    tx = policy_agent.contract.functions.createPolicy(policy_id_3, number_of_periods, 50, [ursula1, ursula2])\
        .transact({'from': alice1, 'value': 20100})
    testerchain.wait_for_receipt(tx)

    for index in range(5):
        tx = miner_agent.contract.functions.confirmActivity().transact(
            {'from': ursula1})
        testerchain.wait_for_receipt(tx)
        tx = miner_agent.contract.functions.confirmActivity().transact(
            {'from': ursula2})
        testerchain.wait_for_receipt(tx)
        tx = miner_agent.contract.functions.confirmActivity().transact(
            {'from': ursula3})
        testerchain.wait_for_receipt(tx)
        testerchain.time_travel(periods=1)

    tx = miner_agent.contract.functions.mint().transact({'from': ursula1})
    testerchain.wait_for_receipt(tx)
    tx = miner_agent.contract.functions.mint().transact({'from': ursula2})
    testerchain.wait_for_receipt(tx)
    tx = miner_agent.contract.functions.mint().transact({'from': ursula3})
    testerchain.wait_for_receipt(tx)

    # Check regular deposit
    print("First deposit tokens = " + str(
        miner_agent.contract.functions.deposit(
            int(constants.MIN_ALLOWED_LOCKED), int(
                constants.MIN_LOCKED_PERIODS)).estimateGas({'from': ursula1})))
    tx = miner_agent.contract.functions.deposit(int(constants.MIN_ALLOWED_LOCKED), int(constants.MIN_LOCKED_PERIODS))\
        .transact({'from': ursula1})
    testerchain.wait_for_receipt(tx)
    print("Second deposit tokens = " + str(
        miner_agent.contract.functions.deposit(
            int(constants.MIN_ALLOWED_LOCKED), int(
                constants.MIN_LOCKED_PERIODS)).estimateGas({'from': ursula2})))
    tx = miner_agent.contract.functions.deposit(int(constants.MIN_ALLOWED_LOCKED), int(constants.MIN_LOCKED_PERIODS))\
        .transact({'from': ursula2})
    testerchain.wait_for_receipt(tx)
    print("Third deposit tokens = " + str(
        miner_agent.contract.functions.deposit(
            int(constants.MIN_ALLOWED_LOCKED), int(
                constants.MIN_LOCKED_PERIODS)).estimateGas({'from': ursula3})))
    tx = miner_agent.contract.functions.deposit(int(constants.MIN_ALLOWED_LOCKED), int(constants.MIN_LOCKED_PERIODS))\
        .transact({'from': ursula3})
    testerchain.wait_for_receipt(tx)

    # ApproveAndCall
    testerchain.time_travel(periods=1)

    tx = miner_agent.contract.functions.mint().transact({'from': ursula1})
    testerchain.wait_for_receipt(tx)
    tx = miner_agent.contract.functions.mint().transact({'from': ursula2})
    testerchain.wait_for_receipt(tx)
    tx = miner_agent.contract.functions.mint().transact({'from': ursula3})
    testerchain.wait_for_receipt(tx)

    print("First approveAndCall = " + str(
        token_agent.contract.functions.approveAndCall(
            miner_agent.contract_address,
            int(constants.MIN_ALLOWED_LOCKED) *
            2, web3.toBytes(int(constants.MIN_LOCKED_PERIODS))).estimateGas(
                {'from': ursula1})))
    tx = token_agent.contract.functions.approveAndCall(miner_agent.contract_address,
                                                       int(constants.MIN_ALLOWED_LOCKED) * 2,
                                                       web3.toBytes(int(constants.MIN_LOCKED_PERIODS)))\
        .transact({'from': ursula1})
    testerchain.wait_for_receipt(tx)
    print("Second approveAndCall = " + str(
        token_agent.contract.functions.approveAndCall(
            miner_agent.contract_address,
            int(constants.MIN_ALLOWED_LOCKED) *
            2, web3.toBytes(int(constants.MIN_LOCKED_PERIODS))).estimateGas(
                {'from': ursula2})))
    tx = token_agent.contract.functions.approveAndCall(miner_agent.contract_address,
                                                       int(constants.MIN_ALLOWED_LOCKED) * 2,
                                                       web3.toBytes(int(constants.MIN_LOCKED_PERIODS)))\
        .transact({'from': ursula2})
    testerchain.wait_for_receipt(tx)
    print("Third approveAndCall = " + str(
        token_agent.contract.functions.approveAndCall(
            miner_agent.contract_address,
            int(constants.MIN_ALLOWED_LOCKED) *
            2, web3.toBytes(int(constants.MIN_LOCKED_PERIODS))).estimateGas(
                {'from': ursula3})))
    tx = token_agent.contract.functions.approveAndCall(miner_agent.contract_address,
                                                       int(constants.MIN_ALLOWED_LOCKED) * 2,
                                                       web3.toBytes(int(constants.MIN_LOCKED_PERIODS)))\
        .transact({'from': ursula3})
    testerchain.wait_for_receipt(tx)

    # Locking tokens
    testerchain.time_travel(periods=1)

    tx = miner_agent.contract.functions.confirmActivity().transact(
        {'from': ursula1})
    testerchain.wait_for_receipt(tx)
    tx = miner_agent.contract.functions.confirmActivity().transact(
        {'from': ursula2})
    testerchain.wait_for_receipt(tx)
    tx = miner_agent.contract.functions.confirmActivity().transact(
        {'from': ursula3})
    testerchain.wait_for_receipt(tx)

    print("First locking tokens = " + str(
        miner_agent.contract.functions.lock(int(
            constants.MIN_ALLOWED_LOCKED), int(
                constants.MIN_LOCKED_PERIODS)).estimateGas({'from': ursula1})))
    tx = miner_agent.contract.functions.lock(int(constants.MIN_ALLOWED_LOCKED),
                                             int(constants.MIN_LOCKED_PERIODS))\
        .transact({'from': ursula1})
    testerchain.wait_for_receipt(tx)
    print("Second locking tokens = " + str(
        miner_agent.contract.functions.lock(int(
            constants.MIN_ALLOWED_LOCKED), int(
                constants.MIN_LOCKED_PERIODS)).estimateGas({'from': ursula2})))
    tx = miner_agent.contract.functions.lock(int(constants.MIN_ALLOWED_LOCKED),
                                             int(constants.MIN_LOCKED_PERIODS))\
        .transact({'from': ursula2})
    testerchain.wait_for_receipt(tx)
    print("Third locking tokens = " + str(
        miner_agent.contract.functions.lock(int(
            constants.MIN_ALLOWED_LOCKED), int(
                constants.MIN_LOCKED_PERIODS)).estimateGas({'from': ursula3})))
    tx = miner_agent.contract.functions.lock(int(constants.MIN_ALLOWED_LOCKED),
                                             int(constants.MIN_LOCKED_PERIODS))\
        .transact({'from': ursula3})
    testerchain.wait_for_receipt(tx)

    # Divide stake
    print("First divide stake = " + str(
        miner_agent.contract.functions.divideStake(
            1, int(constants.MIN_ALLOWED_LOCKED), 2).estimateGas(
                {'from': ursula1})))
    tx = miner_agent.contract.functions.divideStake(
        1, int(constants.MIN_ALLOWED_LOCKED), 2).transact({'from': ursula1})
    testerchain.wait_for_receipt(tx)
    print("Second divide stake = " + str(
        miner_agent.contract.functions.divideStake(
            3, int(constants.MIN_ALLOWED_LOCKED), 2).estimateGas(
                {'from': ursula1})))
    tx = miner_agent.contract.functions.divideStake(
        3, int(constants.MIN_ALLOWED_LOCKED), 2).transact({'from': ursula1})
    testerchain.wait_for_receipt(tx)

    # Divide almost finished stake
    testerchain.time_travel(periods=1)
    tx = miner_agent.contract.functions.confirmActivity().transact(
        {'from': ursula1})
    testerchain.wait_for_receipt(tx)
    testerchain.time_travel(periods=1)
    print("Divide stake (next period is not confirmed) = " + str(
        miner_agent.contract.functions.divideStake(
            0, int(constants.MIN_ALLOWED_LOCKED), 2).estimateGas(
                {'from': ursula1})))
    tx = miner_agent.contract.functions.confirmActivity().transact(
        {'from': ursula1})
    testerchain.wait_for_receipt(tx)
    print("Divide stake (next period is confirmed) = " + str(
        miner_agent.contract.functions.divideStake(
            0, int(constants.MIN_ALLOWED_LOCKED), 2).estimateGas(
                {'from': ursula1})))

    print("All done!")