def apply_transaction(self, chain: MiningChain) -> None: # Instantiate the contract SimpleToken = self.w3.eth.contract( abi=self.contract_interface['abi'], bytecode=self.contract_interface['bin']) # Build transaction to deploy the contract w3_tx1 = SimpleToken.constructor().buildTransaction(W3_TX_DEFAULTS) tx = new_transaction( vm=chain.get_vm(), private_key=FUNDED_ADDRESS_PRIVATE_KEY, from_=FUNDED_ADDRESS, to=CREATE_CONTRACT_ADDRESS, amount=0, gas=FIRST_TX_GAS_LIMIT, data=decode_hex(w3_tx1['data']), ) logging.debug('Applying Transaction {}'.format(tx)) block, receipt, computation = chain.apply_transaction(tx) deployed_contract_address = computation.msg.storage_address assert computation.is_success # Interact with the deployed contract by calling the totalSupply() API simple_token = self.w3.eth.contract( address=Web3.toChecksumAddress( encode_hex(deployed_contract_address)), abi=self.contract_interface['abi'], ) w3_tx2 = simple_token.functions.totalSupply().buildTransaction( W3_TX_DEFAULTS) tx2 = new_transaction( vm=chain.get_vm(), private_key=FUNDED_ADDRESS_PRIVATE_KEY, from_=FUNDED_ADDRESS, to=deployed_contract_address, amount=0, gas=SECOND_TX_GAS_LIMIT, data=decode_hex(w3_tx2['data']), ) block, receipt, computation = chain.apply_transaction(tx2) assert computation.is_success assert to_int(computation.output) == EXPECTED_TOTAL_SUPPLY
def mine_block(self, chain: MiningChain, block_number: int, num_tx: int) -> BaseBlock: for i in range(1, num_tx + 1): self.apply_transaction(chain) return chain.mine_block()
def chain_without_pow(base_db: MemoryDB, vm: Type[BaseVM], genesis_params: Any, genesis_state: Any) -> MiningChain: vm_without_pow = vm.configure(validate_seal=lambda block: None) klass = MiningChain.configure( __name__='TestChain', vm_configuration=((constants.GENESIS_BLOCK_NUMBER, vm_without_pow), )) chain = klass.from_genesis(base_db, genesis_params, genesis_state) return chain
def mine_blocks(self, chain: MiningChain, num_blocks: int) -> Tuple[int, int]: total_gas_used = 0 total_num_tx = 0 for i in range(1, num_blocks + 1): num_tx = chain.get_block().header.gas_limit // SIMPLE_VALUE_TRANSFER_GAS_COST block = self.mine_block(chain, i, num_tx) total_num_tx = total_num_tx + len(block.transactions) total_gas_used = total_gas_used + block.header.gas_used return total_gas_used, total_num_tx
def apply_transaction(self, chain: MiningChain) -> None: if self.config.to_address is None: to_address = generate_random_address() else: to_address = self.config.to_address tx = new_transaction( vm=chain.get_vm(), private_key=FUNDED_ADDRESS_PRIVATE_KEY, from_=FUNDED_ADDRESS, to=to_address, amount=100, data=b'' ) logging.debug('Applying Transaction {}'.format(tx)) block, receipt, computation = chain.apply_transaction(tx) logging.debug('Block {}'.format(block)) logging.debug('Receipt {}'.format(receipt)) logging.debug('Computation {}'.format(computation))
def test_header_chain_invalid_if_no_vm_configuration(base_db, genesis_header): chain_class = MiningChain.configure('ChainNoEmptyConfiguration', vm_configuration=()) with pytest.raises(ValueError): chain_class(base_db, genesis_header)
def mine_empty_blocks(self, chain: MiningChain, number_blocks: int) -> None: for _ in range(1, number_blocks + 1): block = chain.mine_block() logging.debug(format_block(block))