def test_token_deployer_and_agent(testerchain): origin = testerchain.etherbase_account # Trying to get token from blockchain before it's been published fails with pytest.raises(EthereumContractRegistry.UnknownContract): NucypherTokenAgent(blockchain=testerchain) # The big day... deployer = NucypherTokenDeployer(blockchain=testerchain, deployer_address=origin) deployment_txhashes = deployer.deploy() for title, txhash in deployment_txhashes.items(): receipt = testerchain.wait_for_receipt(txhash=txhash) assert receipt['status'] == 1, "Transaction Rejected {}:{}".format(title, txhash) # Create a token instance token_agent = deployer.make_agent() token_contract = token_agent.contract expected_token_supply = token_contract.functions.totalSupply().call() assert expected_token_supply == token_agent.contract.functions.totalSupply().call() # Retrieve the token from the blockchain same_token_agent = NucypherTokenAgent(blockchain=testerchain) # Compare the contract address for equality assert token_agent.contract_address == same_token_agent.contract_address assert token_agent == same_token_agent # __eq__ testerchain.registry.clear()
def __init__(self, checksum_address: str = None, blockchain: Blockchain = None ) -> None: """ :param checksum_address: If not passed, we assume this is an unknown actor :param token_agent: The token agent with the blockchain attached; If not passed, A default token agent and blockchain connection will be created from default values. """ try: parent_address = self.checksum_public_address # type: str if checksum_address is not None: if parent_address != checksum_address: raise ValueError("Can't have two different addresses.") except AttributeError: self.checksum_public_address = checksum_address # type: str if blockchain is None: blockchain = Blockchain.connect() self.blockchain = blockchain self.token_agent = NucypherTokenAgent() self._transaction_cache = list() # type: list # track transactions transmitted
def test_nucypher_deploy_contracts(testerchain, click_runner, mock_primary_registry_filepath): # We start with a blockchain node, and nothing else... assert not os.path.isfile(mock_primary_registry_filepath) command = ( 'contracts', '--registry-outfile', mock_primary_registry_filepath, '--provider-uri', TEST_PROVIDER_URI, '--poa', ) user_input = 'Y\n' + f'{INSECURE_DEVELOPMENT_PASSWORD}\n' * 6 result = click_runner.invoke(deploy, command, input=user_input, catch_exceptions=False) assert result.exit_code == 0 # Check that the primary contract registry was written assert os.path.isfile(mock_primary_registry_filepath) # Now show that we can use contract Agency and read from the blockchain token_agent = NucypherTokenAgent() assert token_agent.get_balance() == 0 miner_agent = MinerAgent() assert miner_agent.get_current_period() testerchain.sever_connection()
def __init__(self, blockchain: BlockchainInterface, sync_now: bool = True, *args, **kwargs): super().__init__(*args, **kwargs) self.log = Logger(f"stakeholder") # Blockchain and Contract connection self.blockchain = blockchain self.staking_agent = StakingEscrowAgent(blockchain=blockchain) self.token_agent = NucypherTokenAgent(blockchain=blockchain) self.economics = TokenEconomics() # Mode self.connect(blockchain=blockchain) self.__accounts = list() self.__stakers = dict() self.__transacting_powers = dict() self.__get_accounts() if sync_now: self.read_onchain_stakes() # Stakes
def test_token_deployer_and_agent(testerchain, deployment_progress, test_registry): testerchain = testerchain origin = testerchain.etherbase_account # Trying to get token from blockchain before it's been published fails with pytest.raises(BaseContractRegistry.UnknownContract): NucypherTokenAgent(registry=test_registry) # The big day... deployer = NucypherTokenDeployer(registry=test_registry, deployer_address=origin) deployment_receipts = deployer.deploy(progress=deployment_progress) for title, receipt in deployment_receipts.items(): assert receipt['status'] == 1 # deployment steps must match expected number of steps assert deployment_progress.num_steps == len(deployer.deployment_steps) == 1 # Create a token instance token_agent = deployer.make_agent() token_contract = token_agent.contract expected_token_supply = token_contract.functions.totalSupply().call() assert expected_token_supply == token_agent.contract.functions.totalSupply( ).call() # Retrieve the token from the blockchain same_token_agent = NucypherTokenAgent(registry=test_registry) # Compare the contract address for equality assert token_agent.contract_address == same_token_agent.contract_address assert token_agent == same_token_agent # __eq__
def __init__(self, is_me: bool, start_staking_loop: bool = True, *args, **kwargs) -> None: super().__init__(*args, **kwargs) self.log = Logger("miner") self.is_me = is_me if is_me: self.token_agent = NucypherTokenAgent(blockchain=self.blockchain) # Staking Loop self.__current_period = None self._abort_on_staking_error = True self._staking_task = task.LoopingCall(self._confirm_period) else: self.token_agent = constants.STRANGER_MINER self.miner_agent = MinerAgent(blockchain=self.blockchain) self.__stakes = constants.NO_STAKES self.__start_time = constants.NO_STAKES self.__uptime_period = constants.NO_STAKES self.__terminal_period = constants.NO_STAKES self.__read_stakes() if self.stakes and start_staking_loop: self.stake()
def test_transfer_tokens(click_runner, registry_filepath): # # Setup # # Let's transfer some NU to a random stranger recipient_address = to_checksum_address(os.urandom(20)) registry = LocalContractRegistry(filepath=registry_filepath) token_agent = NucypherTokenAgent(registry=registry) assert token_agent.get_balance(address=recipient_address) == 0 command = [ 'transfer-tokens', '--target-address', recipient_address, '--value', 42, '--registry-infile', registry_filepath, '--provider', TEST_PROVIDER_URI, '--poa' ] user_input = '0\n' + 'Y\n' + 'Y\n' result = click_runner.invoke(deploy, command, input=user_input, catch_exceptions=False) assert result.exit_code == 0 # Check that the NU has arrived to the recipient assert token_agent.get_balance(address=recipient_address) == 42
def connect(self, blockchain: BlockchainInterface = None) -> None: """Go Online""" if not self.staking_agent: self.staking_agent = StakingEscrowAgent(blockchain=blockchain) if not self.token_agent: self.token_agent = NucypherTokenAgent(blockchain=blockchain) self.blockchain = self.token_agent.blockchain
def __init__(self, economics: TokenEconomics = None, *args, **kwargs): super().__init__(*args, **kwargs) self.token_agent = NucypherTokenAgent(blockchain=self.blockchain) if not economics: economics = TokenEconomics() self.__economics = economics
def test_token_deployer_and_agent(testerchain): origin, *everybody_else = testerchain.interface.w3.eth.accounts # Trying to get token from blockchain before it's been published fails with pytest.raises(EthereumContractRegistry.UnknownContract): NucypherTokenAgent(blockchain=testerchain) # The big day... deployer = NucypherTokenDeployer(blockchain=testerchain, deployer_address=origin) # It's not armed with pytest.raises(NucypherTokenDeployer.ContractDeploymentError): deployer.deploy() # Token must be armed before deploying to the blockchain deployer.arm() deployer.deploy() # Create a token instance token_agent = deployer.make_agent() token_contract = testerchain.get_contract(token_agent.contract_name) expected_token_supply = token_contract.functions.totalSupply().call() assert expected_token_supply == token_agent.contract.functions.totalSupply( ).call() # Retrieve the token from the blockchain same_token_agent = NucypherTokenAgent(blockchain=testerchain) # Compare the contract address for equality assert token_agent.contract_address == same_token_agent.contract_address assert token_agent == same_token_agent # __eq__ testerchain.interface._registry.clear()
def __init__(self, db_filepath: str, rest_host: str, rest_port: int, client_password: str = None, crash_on_error: bool = False, economics: TokenEconomics = None, distribute_ether: bool = True, *args, **kwargs): # Character super().__init__(*args, **kwargs) self.log = Logger(f"felix-{self.checksum_address[-6::]}") # Network self.rest_port = rest_port self.rest_host = rest_host self.rest_app = NOT_RUNNING self.crash_on_error = crash_on_error # Database self.db_filepath = db_filepath self.db = NO_DATABASE_AVAILABLE self.db_engine = create_engine(f'sqlite:///{self.db_filepath}', convert_unicode=True) # Blockchain transacting_power = TransactingPower(blockchain=self.blockchain, password=client_password, account=self.checksum_address) self._crypto_power.consume_power_up(transacting_power) self.token_agent = NucypherTokenAgent(blockchain=self.blockchain) self.reserved_addresses = [self.checksum_address, BlockchainInterface.NULL_ADDRESS] # Update reserved addresses with deployed contracts existing_entries = list(self.blockchain.registry.enrolled_addresses) self.reserved_addresses.extend(existing_entries) # Distribution self.__distributed = 0 # Track NU Output self.__airdrop = 0 # Track Batch self.__disbursement = 0 # Track Quantity self._distribution_task = LoopingCall(f=self.airdrop_tokens) self._distribution_task.clock = self._CLOCK self.start_time = NOT_RUNNING if not economics: economics = TokenEconomics() self.economics = economics self.MAXIMUM_DISBURSEMENT = economics.maximum_allowed_locked self.INITIAL_DISBURSEMENT = economics.minimum_allowed_locked # Optionally send ether with each token transaction self.distribute_ether = distribute_ether # Banner self.log.info(FELIX_BANNER.format(self.checksum_address))
def test_nucypher_deploy_contracts(testerchain, click_runner, mock_primary_registry_filepath): # We start with a blockchain node, and nothing else... assert not os.path.isfile(mock_primary_registry_filepath) command = ('contracts', '--registry-outfile', mock_primary_registry_filepath, '--provider-uri', TEST_PROVIDER_URI, '--poa') user_input = 'Y\n' + f'{INSECURE_DEVELOPMENT_PASSWORD}\n' * 8 result = click_runner.invoke(deploy, command, input=user_input, catch_exceptions=False) assert result.exit_code == 0 # Ensure there is a report on each contract for registry_name in Deployer.contract_names: assert registry_name in result.output # Check that the primary contract registry was written # and peek at some of the registered entries assert os.path.isfile(mock_primary_registry_filepath) with open(mock_primary_registry_filepath, 'r') as file: # Ensure every contract's name was written to the file, somehow raw_registry_data = file.read() for registry_name in Deployer.contract_names: assert registry_name in raw_registry_data # Ensure the Registry is JSON deserializable registry_data = json.loads(raw_registry_data) # and that is has the correct number of entries assert len(registry_data) == 9 # Read several records token_record, escrow_record, dispatcher_record, *other_records = registry_data registered_name, registered_address, registered_abi = token_record token_agent = NucypherTokenAgent() assert token_agent.contract_name == registered_name assert token_agent.registry_contract_name == registered_name assert token_agent.contract_address == registered_address # Now show that we can use contract Agency and read from the blockchain assert token_agent.get_balance() == 0 miner_agent = MinerAgent() assert miner_agent.get_current_period() # and at least the others can be instantiated assert PolicyAgent() assert MiningAdjudicatorAgent() testerchain.sever_connection()
def __init__(self, allocation_registry: AllocationRegistry = None, *args, **kwargs) -> None: super().__init__(*args, **kwargs) self.token_agent = NucypherTokenAgent(blockchain=self.blockchain) self.staking_agent = StakingEscrowAgent(blockchain=self.blockchain) self.policy_agent = PolicyAgent(blockchain=self.blockchain) self.__beneficiary_address = NO_BENEFICIARY self.__allocation_registry = allocation_registry or self.__allocation_registry( )
def __init__(self, checksum_address: str, policy_agent: PolicyAgent = None, economics: TokenEconomics = None, *args, **kwargs) -> None: """ :param policy_agent: A policy agent with the blockchain attached; If not passed, a default policy agent and blockchain connection will be created from default values. """ super().__init__(checksum_address=checksum_address, *args, **kwargs) # From defaults if not policy_agent: self.token_agent = NucypherTokenAgent(blockchain=self.blockchain) self.staking_agent = StakingEscrowAgent(blockchain=self.blockchain) self.policy_agent = PolicyAgent(blockchain=self.blockchain) # Injected else: self.policy_agent = policy_agent self.economics = economics or TokenEconomics()
def __init__(self, is_me: bool, stake_tracker: StakeTracker = None, worker_address: str = None, start_working_loop: bool = True, *args, **kwargs) -> None: super().__init__(*args, **kwargs) self.log = Logger("worker") self.__worker_address = worker_address self.is_me = is_me # Agency self.token_agent = NucypherTokenAgent(blockchain=self.blockchain) self.staking_agent = StakingEscrowAgent(blockchain=self.blockchain) # Stakes self.__start_time = WORKER_NOT_RUNNING self.__uptime_period = WORKER_NOT_RUNNING # Workers cannot be started without being assigned a stake first. if is_me: self.stake_tracker = stake_tracker or StakeTracker( checksum_addresses=[self.checksum_address]) if not self.stake_tracker.stakes( checksum_address=self.checksum_address): raise self.DetachedWorker else: self.stake_tracker.add_action(self._confirm_period) if start_working_loop: self.stake_tracker.start()
def __init__(self, blockchain: BlockchainInterface, deployer_address: str = None, client_password: str = None, bare: bool = True) -> None: self.blockchain = blockchain self.__deployer_address = NO_DEPLOYER_ADDRESS self.deployer_address = deployer_address self.checksum_address = self.deployer_address if not bare: self.token_agent = NucypherTokenAgent(blockchain=blockchain) self.staking_agent = StakingEscrowAgent(blockchain=blockchain) self.policy_agent = PolicyAgent(blockchain=blockchain) self.adjudicator_agent = AdjudicatorAgent(blockchain=blockchain) self.user_escrow_deployers = dict() self.deployers = {d.contract_name: d for d in self.deployer_classes} blockchain.transacting_power = TransactingPower( blockchain=blockchain, account=deployer_address, password=client_password) blockchain.transacting_power.activate() self.log = Logger("Deployment-Actor")
def test_deploy_ethereum_contracts(chain): """ Launch all ethereum contracts: - NuCypherToken - PolicyManager - MinersEscrow - UserEscrow - Issuer """ token_deployer = NucypherTokenDeployer(blockchain=chain) token_deployer.arm() token_deployer.deploy() token_agent = NucypherTokenAgent(blockchain=chain) miner_escrow_deployer = MinerEscrowDeployer(token_agent=token_agent) miner_escrow_deployer.arm() miner_escrow_deployer.deploy() miner_agent = MinerAgent(token_agent=token_agent) policy_manager_contract = PolicyManagerDeployer(miner_agent=miner_agent) policy_manager_contract.arm() policy_manager_contract.deploy()
def test_deploy_ethereum_contracts(testerchain): """ A bare minimum nucypher deployment fixture. """ origin, *everybody_else = testerchain.interface.w3.eth.accounts token_deployer = NucypherTokenDeployer(blockchain=testerchain, deployer_address=origin) token_deployer.arm() token_deployer.deploy() token_agent = NucypherTokenAgent(blockchain=testerchain) miners_escrow_secret = os.urandom(constants.DISPATCHER_SECRET_LENGTH) miner_escrow_deployer = MinerEscrowDeployer( token_agent=token_agent, deployer_address=origin, secret_hash=testerchain.interface.w3.sha3(miners_escrow_secret)) miner_escrow_deployer.arm() miner_escrow_deployer.deploy() miner_agent = MinerAgent(token_agent=token_agent) policy_manager_secret = os.urandom(constants.DISPATCHER_SECRET_LENGTH) policy_manager_deployer = PolicyManagerDeployer( miner_agent=miner_agent, deployer_address=origin, secret_hash=testerchain.interface.w3.sha3(policy_manager_secret)) policy_manager_deployer.arm() policy_manager_deployer.deploy() policy_agent = policy_manager_deployer.make_agent()
def __init__(self, checksum_address: str = None, token_agent: NucypherTokenAgent = None, registry_filepath: str = None) -> None: """ :param checksum_address: If not passed, we assume this is an unknown actor :param token_agent: The token agent with the blockchain attached; If not passed, A default token agent and blockchain connection will be created from default values. """ try: parent_address = self.checksum_public_address if checksum_address is not None: if parent_address != checksum_address: raise ValueError("Can't have two different addresses.") except AttributeError: self.checksum_public_address = checksum_address if registry_filepath is not None: EthereumContractRegistry.from_config( registry_filepath=registry_filepath) self.token_agent = token_agent if token_agent is not None else NucypherTokenAgent( ) self._transaction_cache = list() # track transactions transmitted
def test_stake_in_idle_network(testerchain, token_economics, test_registry): # Let's fund a staker first token_agent = NucypherTokenAgent(registry=test_registry) tpower = TransactingPower(account=testerchain.etherbase_account, signer=Web3Signer(testerchain.client)) token_airdrop(transacting_power=tpower, addresses=testerchain.stakers_accounts, token_agent=token_agent, amount=DEVELOPMENT_TOKEN_AIRDROP_AMOUNT) account = testerchain.stakers_accounts[0] tpower = TransactingPower(account=account, signer=Web3Signer(testerchain.client)) staker = Staker(transacting_power=tpower, domain=TEMPORARY_DOMAIN, registry=test_registry) # Since StakingEscrow hasn't been activated yet, deposit should work but making a commitment must fail amount = token_economics.minimum_allowed_locked periods = token_economics.minimum_locked_periods staker.initialize_stake(amount=amount, lock_periods=periods) staker.bond_worker(account) with pytest.raises((TransactionFailed, ValueError)): staker.staking_agent.commit_to_next_period(transacting_power=tpower)
def __init__(self, blockchain: Blockchain, deployer_address: str = None, allocation_registry: AllocationRegistry = None, bare: bool = True ) -> None: self.blockchain = blockchain self.__deployer_address = NO_DEPLOYER_ADDRESS if deployer_address: self.deployer_address = deployer_address if not bare: self.token_agent = NucypherTokenAgent(blockchain=blockchain) self.miner_agent = MinerAgent(blockchain=blockchain) self.policy_agent = PolicyAgent(blockchain=blockchain) self.allocation_registy = allocation_registry self.user_escrow_deployers = dict() self.deployers = { NucypherTokenDeployer.contract_name: self.deploy_token_contract, MinerEscrowDeployer.contract_name: self.deploy_miner_contract, PolicyManagerDeployer.contract_name: self.deploy_policy_contract, UserEscrowProxyDeployer.contract_name: self.deploy_escrow_proxy, }
def test_stake_in_idle_network(testerchain, token_economics, test_registry): # Let's fund a staker first token_agent = NucypherTokenAgent(registry=test_registry) token_airdrop(origin=testerchain.etherbase_account, addresses=testerchain.stakers_accounts, token_agent=token_agent, amount=DEVELOPMENT_TOKEN_AIRDROP_AMOUNT) account = testerchain.stakers_accounts[0] staker = Staker(is_me=True, checksum_address=account, registry=test_registry) # Mock TransactingPower consumption staker.transacting_power = TransactingPower( password=INSECURE_DEVELOPMENT_PASSWORD, account=staker.checksum_address) staker.transacting_power.activate() # Since StakingEscrow hasn't been activated yet, deposit should work but making a commitment must fail amount = token_economics.minimum_allowed_locked periods = token_economics.minimum_locked_periods staker.initialize_stake(amount=amount, lock_periods=periods) staker.bond_worker(account) with pytest.raises((TransactionFailed, ValueError)): staker.staking_agent.commit_to_next_period(worker_address=account)
def __init__(self, checksum_address: str, policy_agent=None, economics: TokenEconomics = None, *args, **kwargs) -> None: """ :param policy_agent: A policy agent with the blockchain attached; If not passed, a default policy agent and blockchain connection will be created from default values. """ super().__init__(checksum_address=checksum_address, *args, **kwargs) if not policy_agent: # From defaults self.token_agent = NucypherTokenAgent(blockchain=self.blockchain) self.miner_agent = MinerAgent(blockchain=self.blockchain) self.policy_agent = PolicyAgent(blockchain=self.blockchain) else: # Injected self.policy_agent = policy_agent if not economics: economics = TokenEconomics() self.economics = economics
def test_deploy_ethereum_contracts(testerchain): """ Launch all ethereum contracts: - NuCypherToken - PolicyManager - MinersEscrow - UserEscrow - Issuer """ origin, *everybody_else = testerchain.interface.w3.eth.accounts token_deployer = NucypherTokenDeployer(blockchain=testerchain, deployer_address=origin) token_deployer.arm() token_deployer.deploy() token_agent = NucypherTokenAgent(blockchain=testerchain) miner_escrow_deployer = MinerEscrowDeployer(token_agent=token_agent, deployer_address=origin) miner_escrow_deployer.arm() miner_escrow_deployer.deploy() miner_agent = MinerAgent(token_agent=token_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()
def __init__(self, blockchain: Blockchain, deployer_address: str = None, bare: bool = True) -> None: self.blockchain = blockchain self.__deployer_address = NO_DEPLOYER_ADDRESS if deployer_address: self.deployer_address = deployer_address if not bare: self.token_agent = NucypherTokenAgent(blockchain=blockchain) self.miner_agent = MinerAgent(blockchain=blockchain) self.policy_agent = PolicyAgent(blockchain=blockchain) self.adjudicator_agent = MiningAdjudicatorAgent( blockchain=blockchain) self.user_escrow_deployers = dict() self.deployers = { NucypherTokenDeployer.contract_name: self.deploy_token_contract, MinerEscrowDeployer.contract_name: self.deploy_miner_contract, PolicyManagerDeployer.contract_name: self.deploy_policy_contract, UserEscrowProxyDeployer.contract_name: self.deploy_escrow_proxy, MiningAdjudicatorDeployer.contract_name: self.deploy_mining_adjudicator_contract, } self.log = Logger("Deployment-Actor")
def __init__(self, checksum_address: str, policy_agent: PolicyAgent = None, *args, **kwargs) -> None: """ :param policy_agent: A policy agent with the blockchain attached; If not passed, A default policy agent and blockchain connection will be created from default values. """ if policy_agent is None: # From defaults self.token_agent = NucypherTokenAgent() self.miner_agent = MinerAgent(token_agent=self.token_agent) self.policy_agent = PolicyAgent(miner_agent=self.miner_agent) else: # From agent self.policy_agent = policy_agent self.miner_agent = policy_agent.miner_agent super().__init__(token_agent=self.policy_agent.token_agent, checksum_address=checksum_address, *args, **kwargs)
def paint_contract_status(blockchain, emitter): token_agent = NucypherTokenAgent(blockchain=blockchain) staking_agent = StakingEscrowAgent(blockchain=blockchain) policy_agent = PolicyManagerAgent(blockchain=blockchain) adjudicator_agent = AdjudicatorAgent(blockchain=blockchain) contract_payload = f""" | NuCypher Contracts | Chain .................... {blockchain.client.chain_name} Provider URI ............. {blockchain.provider_uri} Registry Path ............ {blockchain.registry.filepath} NucypherToken ............ {token_agent.contract_address} StakingEscrow ............ {staking_agent.contract_address} PolicyManager ............ {policy_agent.contract_address} Adjudicator .............. {adjudicator_agent.contract_address} """ network_payload = f""" | Staking | Current Period ........... {staking_agent.get_current_period()} Actively Staked Tokens ... {NU.from_nunits(staking_agent.get_global_locked_tokens())} Published Stakes ......... {staking_agent.get_staker_population()} Gas Price ................ {Web3.fromWei(blockchain.client.gas_price, 'gwei')} Gwei """ emitter.echo(contract_payload) emitter.echo(network_payload)
def test_transacting_power_sign_agent_transaction(testerchain, agency, test_registry): token_agent = NucypherTokenAgent(registry=test_registry) contract_function = token_agent.contract.functions.approve( testerchain.etherbase_account, 100) payload = { 'chainId': int(testerchain.client.chain_id), 'nonce': testerchain.client.w3.eth.getTransactionCount( testerchain.etherbase_account), 'from': testerchain.etherbase_account, 'gasPrice': testerchain.client.gas_price } unsigned_transaction = contract_function.buildTransaction(payload) # Sign with Transacting Power transacting_power = TransactingPower( password=INSECURE_DEVELOPMENT_PASSWORD, signer=Web3Signer(testerchain.client), account=testerchain.etherbase_account) signed_raw_transaction = transacting_power.sign_transaction( unsigned_transaction) # Demonstrate that the transaction is valid RLP encoded. restored_transaction = Transaction.from_bytes( serialized_bytes=signed_raw_transaction) restored_dict = restored_transaction.as_dict() assert to_checksum_address( restored_dict['to']) == unsigned_transaction['to']
def __init__(self, economics: SlashingEconomics = None, *args, **kwargs): super().__init__(*args, **kwargs) self.token_agent = NucypherTokenAgent(blockchain=self.blockchain) self.miner_agent = MinerAgent(blockchain=self.blockchain) if not economics: economics = SlashingEconomics() self.__economics = economics
def __init__(self, blockchain: BlockchainInterface, checksum_address: str = None): """ :param checksum_address: If not passed, we assume this is an unknown actor """ try: parent_address = self.checksum_address # type: str if checksum_address is not None: if parent_address != checksum_address: raise ValueError("Can't have two different addresses.") except AttributeError: self.checksum_address = checksum_address # type: str self.blockchain = blockchain self.token_agent = NucypherTokenAgent(blockchain=self.blockchain) self._saved_receipts = list( ) # type: list # track receipts of transmitted transactions