def inject_tx(txhex): tx = rlp.decode(utils.decode_hex(txhex[2:]), transactions.Transaction) s.state.set_balance(tx.sender, tx.startgas * tx.gasprice) state_transition.apply_transaction(s.state, tx) contract_address = utils.mk_contract_address(tx.sender, 0) assert s.state.get_code(contract_address) return contract_address
class SafeCreation2Factory(factory.DjangoModelFactory): class Meta: model = SafeCreation2 safe = factory.SubFactory( SafeContractFactory, address=factory.LazyAttribute(lambda o: checksum_encode( mk_contract_address(o.factory_parent.proxy_factory, 0)))) master_copy = factory.LazyFunction(lambda: Account.create().address) proxy_factory = factory.LazyFunction(lambda: Account.create().address) salt_nonce = factory.fuzzy.FuzzyInteger(1, 10000000) owners = factory.LazyFunction( lambda: [Account.create().address, Account.create().address]) threshold = 2 payment_token = None payment = factory.fuzzy.FuzzyInteger(100, 100000) payment_receiver = NULL_ADDRESS setup_data = factory.Sequence(lambda n: HexBytes('%x' % (n + 1000))) gas_estimated = factory.fuzzy.FuzzyInteger(100000, 200000) gas_price_estimated = factory.fuzzy.FuzzyInteger(Web3.toWei(1, 'gwei'), Web3.toWei(20, 'gwei')) tx_hash = factory.Sequence( lambda n: Web3.keccak(text='safe-creation-2-%d' % n)) block_number = None
def deploy(cls, contract_path): cwd = os.getcwd() os.chdir('contract') # Our ContractGasToken contract relies on being deployed at address # 0x0000000000b3F879cb30FE243b4Dfee438691c04 # Through magic, we have determined that a contract created in a # transaction with nonce == magic_nonce sent from # address == magic_address will have this address. magic_key = 0xa7d79a51ff835c80c1f5c2c3b350b15f95550e41e379e50a10ef2ff3f6a215aa magic_address = 0x470F1C3217A2F408769bca5AB8a5c67A9040664A magic_nonce = 125 contract_address = 0x0000000000b3F879cb30FE243b4Dfee438691c04 computed_address = int( utils.encode_hex( utils.mk_contract_address(magic_address, magic_nonce)), 16) assert (computed_address == contract_address) cls.s.head_state.set_nonce(magic_address, magic_nonce) # check that we have reached magic_nonce and that there is no code at magic_address assert (cls.s.head_state.get_nonce(magic_address) == magic_nonce) assert (0 == len(cls.s.head_state.get_code(contract_address))) # deploy contract and check that it has been deployed successfully cls.c = deploy_solidity_contract(contract_path, 'GasToken2', cls.s, sender=magic_key) assert (0 < len(cls.s.head_state.get_code(contract_address))) os.chdir(cwd)
def deploy_and_initialize_contract(self, deployer_account: LocalAccount, constructor_data: bytes, initializer_data: bytes = b'', check_receipt: bool = True): contract_address = None for data in (constructor_data, initializer_data): # Because initializer_data is not mandatory if data: tx = { 'from': deployer_account.address, 'data': data, 'gasPrice': self.w3.eth.gasPrice, 'value': 0, 'to': contract_address if contract_address else b'' } tx['gas'] = self.w3.eth.estimateGas(tx) tx_hash = self.send_unsigned_transaction( tx, private_key=deployer_account.key) if check_receipt: tx_receipt = self.get_transaction_receipt(tx_hash, timeout=60) assert tx_receipt.status if not contract_address: contract_address = checksum_encode( mk_contract_address(tx['from'], tx['nonce'])) return EthereumTxSent(tx_hash, tx, contract_address)
class SafeCreationFactory(factory.DjangoModelFactory): class Meta: model = SafeCreation deployer = factory.LazyFunction(lambda: Account.create().address) safe = factory.SubFactory( SafeContractFactory, address=factory.LazyAttribute(lambda o: checksum_encode( mk_contract_address(o.factory_parent.deployer, 0)))) funder = factory.LazyFunction(lambda: Account.create().address) owners = factory.LazyFunction( lambda: [Account.create().address, Account.create().address]) threshold = 2 payment = factory.fuzzy.FuzzyInteger(100, 1000) tx_hash = factory.Sequence(lambda n: Web3.keccak(n)) gas = factory.fuzzy.FuzzyInteger(100000, 200000) gas_price = factory.fuzzy.FuzzyInteger(Web3.toWei(1, 'gwei'), Web3.toWei(20, 'gwei')) payment_token = None value = 0 v = factory.fuzzy.FuzzyInteger(SIGNATURE_V_MIN_VALUE, SIGNATURE_V_MAX_VALUE) r = factory.fuzzy.FuzzyInteger(SIGNATURE_R_MIN_VALUE, SIGNATURE_R_MAX_VALUE) s = factory.fuzzy.FuzzyInteger(SIGNATURE_S_MIN_VALUE, SIGNATURE_S_MAX_VALUE) data = factory.Sequence(lambda n: HexBytes('%x' % (n + 1000))) signed_tx = factory.Sequence(lambda n: HexBytes('%x' % (n + 5000)))
def buildContexts(ops, api, contracts, txhash): contexts = {} tx = api.getTransaction(txhash) to = tx['to'] blnum = int(tx['blockNumber']) if to == '0x0': to = None create = to is None # contract deployment # need to generate the contract address in order to fetch the bytecode if to is None: baddr = mk_contract_address(tx['from'], tx['nonce']) to = '0x%s' % encode_hex(baddr).decode() for depth, addr in findContextChanges(ops, to).items(): acc = api.getAccountInfo(addr, blnum) c = findContractForBytecode(contracts, acc['code']) if not c: print("Couldn't find contract for address {}".format(addr)) # print(acc['code']) if c and create and addr == to: c.create = True contexts[depth] = Context(addr, c) return contexts
def precompute_addresses(self): """ Precompute the addresses at which the Meta Contract and heads will be deployed. """ nonce = self.get_nonce() all_addresses = [utils.mk_contract_address(self.creator_addr, nonce)] nonce += 1 for _ in self.paths_to_heads: all_addresses.append( utils.mk_contract_address(self.creator_addr, nonce)) nonce += 1 return all_addresses
def determineContractAddr(deployerAddr, tx_count, qty=1): addresses = [] for i in range(tx_count, tx_count + qty): _addr = mk_contract_address(deployerAddr, i) _addr = checksum_encode(_addr) return _addr
def find(self): """ Build a hash table of contract addresses. Iterate through all blocks and search for new contract addresses. Append them to self.addresses if found. """ blocks = self.client.find( {"number": {"$lt": 4370000}} ).sort("number", 1 ) counter = 0 for block in blocks: if block["transactions"]: # Loop through all of the transactions in the current block # Add all the nodes to a global set (self.nodes) for txn in block["transactions"]: if txn["to"] == None: ts = self._rpcRequest("eth_getBlockByNumber", [hex(block["number"]), True], "result")["transactions"] notFound =True counter2 = 0 while(notFound): t=ts[counter2] if txn["from"] == t["from"] and txn["to"] == t["to"] and txn["input"] == t["input"] and txn[ "gas"] == t["gas"] and txn["gasPrice"] == t["gasPrice"] and not "used" in t: txn["nonce"] = t["nonce"] to = "0x" + encode_hex(mk_contract_address(txn["from"], int(txn["nonce"], 16))) self.addresses[to] = 3 ts[counter2]["used"]=True notFound=False counter2 += 1 #for t in ts: # if not "nonce" in txn: # if txn["from"] == t["from"] and txn["to"] == t["to"] and txn["input"] == t["input"] and txn["gas"] == t["gas"] and txn["gasPrice"] == t["gasPrice"]: # txn["nonce"] = t["nonce"] # to = "0x" + encode_hex(mk_contract_address(txn["from"], int(txn["nonce"], 16))) # self.addresses[to] = 3 elif not self.addresses[txn["to"]]: self.addresses[txn["to"]] = 1 if not self.addresses[txn["from"]]: self.addresses[txn["from"]] = 2 if not self.addresses[block["miner"]]: self.addresses[block["miner"]] = 4 self.last_block = block["number"] counter += 1 # Save the list every 10000 blocks in case geth crashes # midway through the procedure if "uncles" in block: for uncle in block["uncles"]: if not self.addresses[uncle["miner"]]: self.addresses[uncle["miner"]] = 5 if not counter % 10000: print("Done with block {}...".format(self.last_block)) self.save()
def test_child_initcode(self): """Check that the initcode of the child contract creates the correct contract. """ child_address = utils.mk_contract_address(self.c.address, 1) self.assertEqual(b'', self.s.head_state.get_code(child_address)) self.c.mint(1) self.assertEqual( self.CHILD_CONTRACT_BIN, utils.encode_hex(self.s.head_state.get_code(child_address)))
def generate_contracts(quantity_per_key, private_key, nonce=0): pa = checksum_encode(privtoaddr(private_key)) contracts = [] for i in range(quantity_per_key): c_addr_ = str(encode_hex(mk_contract_address(pa, i + nonce))) contracts.append("0x" + c_addr_.replace("\'", "")) return contracts
def inject_tx(txhex): tx = rlp.decode(utils.decode_hex(txhex[2:]), transactions.Transaction) # c.head_state.set_balance(tx.sender, tx.startgas * tx.gasprice) # temporarily using account[8] - k9, to dispense required fee for injected txs c.tx(t.k9, tx.sender, tx.startgas * tx.gasprice) # state_transition.apply_transaction(c.head_state, tx) c.direct_tx(tx) contract_address = utils.mk_contract_address(tx.sender, 0) assert c.head_state.get_code(contract_address) return contract_address
def test_random(self): for i in range(20): address = random_address() print('testing 200 random nonces for address {}'.format( utils.encode_hex(address))) for i in range(200): nonce = random.randint(0, 4722366482869645213696) self.assertEqual( utils.encode_hex(utils.mk_contract_address(address, nonce)), self.c.mk_contract_address(address, nonce)[2:])
def create_urs_tx(shard_id, gasprice=GASPRICE): bytecode = get_urs_bytecode(shard_id) tx = Transaction(0, gasprice, 2000000, to=b'', value=0, data=bytecode) tx.v = 27 tx.r = 10000 tx.s = shard_id + 1 tx_rawhash = get_tx_rawhash(tx) urs_sender_addr = utils.sha3( utils.ecrecover_to_pub(tx_rawhash, tx.v, tx.r, tx.s))[-20:] urs_addr = utils.mk_contract_address(urs_sender_addr, 0) return tx, urs_addr, urs_sender_addr
def test_exhaustive1(self): addresses = [ b'\x00' * 20, b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19', b'\xff\xfe\xfd\xfc\xfb\xfa\xf9\xf8\xf7\xf7\xf6\xf5\xf4\xf3\xf2\x00\xf0\x53\x00\x00', ] for address in addresses: for nonce in range(1025): self.assertEqual( utils.encode_hex(utils.mk_contract_address(address, nonce)), self.c.mk_contract_address(address, nonce)[2:])
def create_valmgr_tx(gasprice=GASPRICE): global _valmgr_sender_addr, _valmgr_addr, _valmgr_tx bytecode = get_valmgr_bytecode() tx = Transaction(0, gasprice, 4000000, to=b'', value=0, data=bytecode) tx.v = 27 tx.r = 1000000000000000000000000000000000000000000000000000000000000000000000000000 tx.s = 1000000000000000000000000000000000000000000000000000000000000000000000000000 valmgr_sender_addr = extract_sender_from_tx(tx) valmgr_addr = utils.mk_contract_address(valmgr_sender_addr, 0) _valmgr_sender_addr = valmgr_sender_addr _valmgr_addr = valmgr_addr _valmgr_tx = tx
def test_exhaustive2(self): #Â This is the actual address we use on the mainnet address = utils.normalize_address( "0x0000000000b3F879cb30FE243b4Dfee438691c04") for nonce in chain( range(72000), range(4722366482869645213696 - 72000, 4722366482869645213696)): self.assertEqual( utils.encode_hex(utils.mk_contract_address(address, nonce)), self.c.mk_contract_address(address, nonce)[2:]) if nonce % 1000 == 0: print('exhaustive test currently at nonce:', nonce)
def deploy_contract_and_accounts(state, n_devs, start=1, end=2, deploy_contract=True): dev_keys = [] dev_accounts = [] milestone = int(math.log10(n_devs)) notify_step = milestone - 2 notify_value = 10**notify_step if notify_step > 0 else 1 # create developer accounts and keys in fashion of testers for account_number in range(n_devs): if account_number % notify_value == 0: print "Account", account_number + 1, "out of", n_devs dev_keys.append(sha3('dev' + to_string(account_number))) dev_accounts.append(privtoaddr(dev_keys[-1])) # developer balances block = state.block for i in range(n_devs): if i % notify_value == 0: print "Balance", i + 1, "out of", n_devs addr, data = dev_accounts[i], {'wei': 10**24} if len(addr) == 40: addr = decode_hex(addr) assert len(addr) == 20 block.set_balance(addr, parse_int_or_hex(data['wei'])) block.commit_state() block.state.db.commit() dev_addresses = [ContractHelper.dev_address(a) for a in dev_accounts] # deploy the gnt contract with updated developer accounts if deploy_contract: contract, _, _ = deploy_gnt(state, tester.accounts[9], start, end, replacements=[(dev_addresses, DEV_ADDR_REGEX)]) alloc_addr = mk_contract_address(contract.address, 0) allocation = tester.ABIContract(state, ALLOC_ABI, alloc_addr) else: contract, allocation = None, None return contract, allocation, dev_keys, dev_accounts
def _generate_new_address(self, creator=None) -> str: """Generates a new address for the global state. :return: """ if creator: # TODO: Use nounce return "0x" + str(mk_contract_address(creator, 0).hex()) while True: address = "0x" + "".join( [str(hex(randint(0, 16)))[-1] for _ in range(40)]) if address not in self.accounts.keys(): return address
def test_child_address_check(self): """Check that the child contract will throw when it's called by anybody except the ERC20 contract. """ child_address = utils.mk_contract_address(self.c.address, 1) self.c.mint(1) self.assertLess(0, len(self.s.head_state.get_code(child_address))) with self.assertRaises(TransactionFailed): self.s.tx(sender=self.t.k0, to=child_address, value=0, data=b'', startgas=10**20)
def _generate_new_address(self, creator=None) -> BitVec: """Generates a new address for the global state. :return: """ if creator: # TODO: Use nounce address = "0x" + str(mk_contract_address(creator, 0).hex()) return symbol_factory.BitVecVal(int(address, 16), 256) while True: address = "0x" + "".join( [str(hex(randint(0, 16)))[-1] for _ in range(40)]) if address not in self._accounts.keys(): return symbol_factory.BitVecVal(int(address, 16), 256)
def __init__(self, w3: Web3, owners: List[str], threshold: int, signature_s: int, master_copy: str, gas_price: int, funder: str, payment_token: str = None): assert 0 < threshold <= len(owners) self.owners = owners self.threshold = threshold self.s = signature_s self.master_copy = master_copy self.gas_price = gas_price self.funder = funder self.payment_token = payment_token self.gnosis_safe_contract = get_safe_team_contract(w3, master_copy) self.paying_proxy_contract = get_paying_proxy_contract(w3) safe_tx = self.get_initial_setup_safe_tx(owners, threshold) encoded_data = safe_tx['data'] self.gas = self._calculate_gas(owners, encoded_data) # Payment will be safe deploy cost + transfer fees for sending money to the deployer self.payment = self.gas * self.gas_price + 23000 self.contract_creation_tx_dict = self._build_proxy_contract_creation_tx( master_copy=self.master_copy, initializer=encoded_data, funder=self.funder, payment_token=self.payment_token, payment=self.payment, gas=self.gas, gas_price=self.gas_price) (self.contract_creation_tx, self.v, self.r) = self._generate_valid_transaction( gas_price, self.gas, self.contract_creation_tx_dict['data'], self.s) self.raw_tx = rlp.encode(self.contract_creation_tx) self.tx_hash = self.contract_creation_tx.hash self.deployer_address = checksum_encode( self.contract_creation_tx.sender) self.safe_address = checksum_encode( mk_contract_address(self.deployer_address, nonce=0))
def test_finalize_funding(self): self.deploy_contract(tester.accounts[9], 2, 3) contract = self.c alloc_addr = mk_contract_address(contract.address, 0) allocation = tester.ABIContract(self.state, ALLOC_ABI, alloc_addr) # --------------- # PRE FUNDING # --------------- self.state.mine(1) with self.assertRaises(TransactionFailed): contract.finalize() # --------------- # FUNDING # --------------- self.state.mine(1) n_testers = len(tester.accounts) - 1 eths = [(i + 1) * 10000 * denoms.ether for i in xrange(n_testers)] for i, e in enumerate(eths): contract.create(sender=tester.keys[i], value=e) assert contract.balanceOf( tester.accounts[i]) == contract.tokenCreationRate() * e with self.assertRaises(TransactionFailed): contract.finalize() # --------------- # POST FUNDING # --------------- self.state.mine(2) total_tokens = contract.totalSupply() assert total_tokens == sum(eths) * contract.tokenCreationRate() contract.finalize() with self.assertRaises(TransactionFailed): contract.finalize() factory_percent = 12 devs_percent = 6 sum_percent = factory_percent + devs_percent tokens_extra = total_tokens * sum_percent / (100 - sum_percent) assert contract.totalSupply() == total_tokens + tokens_extra assert contract.balanceOf(allocation.address) == tokens_extra
def test_contractAddress(self): ac = self.auction_contract addresses = [ self.null_address(), '0x' + 'f' * 40, '0x' + '0' * 20 + 'a' * 20, '0x' + 'a' * 20 + '0' * 20, '0xEA674fdDe714fd979de3EdF0F56AA9716B898ec8', ] for address in addresses: for i in range(128): self.assertEqualAddr(mk_contract_address(address, i), ac._contractAddress(address, i)) with self.assertRaises(t.TransactionFailed): ac._contractAddress('0xEA674fdDe714fd979de3EdF0F56AA9716B898ec8', 128)
def create_contract(ext, msg): log_msg.debug("CONTRACT CREATION") # print('CREATING WITH GAS', msg.gas) sender = decode_hex(msg.sender) if len(msg.sender) == 40 else msg.sender code = msg.data.extract_all() if ext._block.number >= ext._block.config["METROPOLIS_FORK_BLKNUM"]: msg.to = mk_metropolis_contract_address(msg.sender, code) if ext.get_code(msg.to): if ext.get_nonce(msg.to) >= 2 ** 40: ext.set_nonce(msg.to, (ext.get_nonce(msg.to) + 1) % 2 ** 160) msg.to = normalize_address((ext.get_nonce(msg.to) - 1) % 2 ** 160) else: ext.set_nonce(msg.to, (big_endian_to_int(msg.to) + 2) % 2 ** 160) msg.to = normalize_address((ext.get_nonce(msg.to) - 1) % 2 ** 160) else: if ext.tx_origin != msg.sender: ext._block.increment_nonce(msg.sender) nonce = utils.encode_int(ext._block.get_nonce(msg.sender) - 1) msg.to = mk_contract_address(sender, nonce) b = ext.get_balance(msg.to) if b > 0: ext.set_balance(msg.to, b) ext._block.set_nonce(msg.to, 0) ext._block.set_code(msg.to, b"") ext._block.reset_storage(msg.to) msg.is_create = True # assert not ext.get_code(msg.to) msg.data = vm.CallData([], 0, 0) snapshot = ext._block.snapshot() res, gas, dat = _apply_msg(ext, msg, code) assert utils.is_numeric(gas) if res: if not len(dat): return 1, gas, msg.to gcost = len(dat) * opcodes.GCONTRACTBYTE if gas >= gcost: gas -= gcost else: dat = [] log_msg.debug("CONTRACT CREATION OOG", have=gas, want=gcost, block_number=ext._block.number) if ext._block.number >= ext._block.config["HOMESTEAD_FORK_BLKNUM"]: ext._block.revert(snapshot) return 0, 0, b"" ext._block.set_code(msg.to, b"".join(map(ascii_chr, dat))) return 1, gas, msg.to else: return 0, gas, b""
def create_contract(ext, msg): log_msg.debug('CONTRACT CREATION') #print('CREATING WITH GAS', msg.gas) sender = decode_hex(msg.sender) if len(msg.sender) == 40 else msg.sender code = msg.data.extract_all() if ext._block.number >= ext._block.config['METROPOLIS_FORK_BLKNUM']: msg.to = mk_metropolis_contract_address(msg.sender, code) if ext.get_code(msg.to): if ext.get_nonce(msg.to) >= 2 ** 40: ext.set_nonce(msg.to, (ext.get_nonce(msg.to) + 1) % 2 ** 160) msg.to = normalize_address((ext.get_nonce(msg.to) - 1) % 2 ** 160) else: ext.set_nonce(msg.to, (big_endian_to_int(msg.to) + 2) % 2 ** 160) msg.to = normalize_address((ext.get_nonce(msg.to) - 1) % 2 ** 160) else: if ext.tx_origin != msg.sender: ext._block.increment_nonce(msg.sender) nonce = utils.encode_int(ext._block.get_nonce(msg.sender) - 1) msg.to = mk_contract_address(sender, nonce) b = ext.get_balance(msg.to) if b > 0: ext.set_balance(msg.to, b) ext._block.set_nonce(msg.to, 0) ext._block.set_code(msg.to, b'') ext._block.reset_storage(msg.to) msg.is_create = True # assert not ext.get_code(msg.to) msg.data = vm.CallData([], 0, 0) snapshot = ext._block.snapshot() res, gas, dat = _apply_msg(ext, msg, code) assert utils.is_numeric(gas) if res: if not len(dat): return 1, gas, msg.to gcost = len(dat) * opcodes.GCONTRACTBYTE if gas >= gcost: gas -= gcost else: dat = [] log_msg.debug('CONTRACT CREATION OOG', have=gas, want=gcost, block_number=ext._block.number) if ext._block.number >= ext._block.config['HOMESTEAD_FORK_BLKNUM']: ext._block.revert(snapshot) return 0, 0, b'' ext._block.set_code(msg.to, b''.join(map(ascii_chr, dat))) return 1, gas, msg.to else: return 0, gas, b''
def serialize_transaction_receipt(block, transaction, transaction_receipt, transaction_index, is_pending): if hasattr(block, 'transaction_list'): origin_gas = block.transaction_list[0].startgas elif hasattr(block, 'transactions'): origin_gas = block.transactions[0].startgas else: raise Exception( 'Invariant: failed to match pyethereum16 or pyethereum21 API') if transaction.creates is not None: contract_addr = transaction.creates elif transaction.to == b'\x00' * 20: from ethereum.utils import mk_contract_address # pyethereum21 doesn't correctly detect this as a create address. contract_addr = mk_contract_address(transaction.sender, transaction.nonce) else: contract_addr = None return { "transaction_hash": transaction.hash, "transaction_index": None if is_pending else transaction_index, "block_number": None if is_pending else block.number, "block_hash": None if is_pending else block.hash, "cumulative_gas_used": origin_gas - transaction.startgas + transaction_receipt.gas_used, "gas_used": transaction_receipt.gas_used, "contract_address": contract_addr, "logs": [ serialize_log(block, transaction, transaction_index, log, log_index, is_pending) for log_index, log in enumerate(transaction_receipt.logs) ], }
def broadcast_deposit(self): if not self.valcode_tx or not self.deposit_tx: # Generate transactions valcode_tx = self.mk_validation_code_tx() valcode_addr = utils.mk_contract_address(self.coinbase, self.nonce - 1) deposit_tx = self.mk_deposit_tx(3 * 10**18, valcode_addr) # Verify the transactions pass temp_state = self.chain.state.ephemeral_clone() valcode_success, o1 = apply_transaction(temp_state, valcode_tx) deposit_success, o2 = apply_transaction(temp_state, deposit_tx) if not (valcode_success and deposit_success): self.nonce = self.chain.state.get_nonce(self.coinbase) raise Exception('Valcode tx or deposit tx failed') self.valcode_tx = valcode_tx log.info('Valcode Tx generated: {}'.format(str(valcode_tx))) self.valcode_addr = valcode_addr self.deposit_tx = deposit_tx log.info('Deposit Tx generated: {}'.format(str(deposit_tx))) self.broadcast_transaction(self.valcode_tx) self.broadcast_transaction(self.deposit_tx)
def serialize_transaction_receipt(block, transaction, transaction_receipt, prev_transaction_receipt, transaction_index, is_pending): if prev_transaction_receipt is not None: prev_transaction_gas_used = prev_transaction_receipt.gas_used else: prev_transaction_gas_used = 0 if transaction.creates is not None: contract_addr = transaction.creates elif transaction.to == b'\x00' * 20: from ethereum.utils import mk_contract_address # pyethereum21 doesn't correctly detect this as a create address. contract_addr = mk_contract_address(transaction.sender, transaction.nonce) else: contract_addr = None return { "transaction_hash": transaction.hash, "transaction_index": None if is_pending else transaction_index, "block_number": None if is_pending else block.number, "block_hash": None if is_pending else block.hash, "cumulative_gas_used": transaction_receipt.gas_used, "gas_used": transaction_receipt.gas_used - prev_transaction_gas_used, "contract_address": contract_addr, "logs": [ serialize_log(block, transaction, transaction_index, log, log_index, is_pending) for log_index, log in enumerate(transaction_receipt.logs) ], "state_root": transaction_receipt.state_root, }
def buildContexts(ops, api, contracts, txhash): contract_stack = [] tx = api.getTransaction(txhash) to = tx['to'] blnum = int(tx['blockNumber']) if to == '0x0': to = None create = to is None # contract deployment # need to generate the contract address in order to fetch the bytecode if to is None: baddr = mk_contract_address(tx['from'], tx['nonce']) to = '0x%s' % encode_hex(baddr).decode() cache = {} for addr in findContractChanges(ops, to): if addr in cache: c = cache[addr] if c and create and addr == to: # if it's cached, then the contract is already created so we need to create a new Contract instance w/ create = False newc = object.__new__(Contract) newc.__dict__ = c.__dict__.copy() c = newc else: acc = api.getAccountInfo(addr, blnum) c = findContractForBytecode(contracts, acc['code']) cache[addr] = c if not c: print("Couldn't find contract for address {}".format(addr)) if c and create and addr == to: c.create = True contract_stack.append(Context(addr, c)) return contract_stack
def test_rlp(self): addresses = [ utils.encode_hex(self.c.address), 0x0, "{:x}".format(256**20 - 1) ] nonces = [ 0, 1, 2, 5, 10, 20, 50, 100, 127, 128, 129, 255, 256, 257, 500, 1000, 256**2 - 1, 256**2, 256**2 + 256 + 1, 256**3 - 1, 256**3, 256**3 + 256**2 + 256 + 1, 256**4 - 1, 256**5 - 1, 256**6 - 1, 256**7 - 1, 256**8 - 1, 256**8, 256**8 + 1, 256**8 + 256**7 + 256**6 + 256**5 + 256**4 + 256**3 + 256**2 + 256 + 1, 256**9 - 2, 256**9 - 1 ] scaled_as_expected = True for address in addresses: for nonce in nonces: print("a={}, n={}".format(address, nonce)) gas_used_before = self.s.head_state.gas_used a1 = self.c.mk_contract_address(address, nonce) gas_used_after = self.s.head_state.gas_used gas_used = gas_used_after - gas_used_before expected = self.tot_rlp_cost(nonce, address) if gas_used != expected: scaled_as_expected = False warnings.warn( "RLP({}, {}) did not scale as expected. Got {}. " "Expected {}".format(nonce, address, gas_used, expected)) a2 = "0x{}".format( utils.encode_hex(utils.mk_contract_address(address, nonce))) self.assertEqual(a1, a2) self.assertTrue(scaled_as_expected)
def creates(self): "returns the address of a contract created by this tx" if self.to in (b'', '\0' * 20): return mk_contract_address(self.sender, self.nonce)
[b"\x81", "b"], [b""], [b"", b"\x01", b""], [b"", b"\x81", b""], [b"dog", b"c" * 54, b"\x01"], [b"\x01", b"c" * 55, b"pig"], [b"moose", b"c" * 56, b"\x00"], [b'\x01', b'55555555555555555555555555555555', b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', b'', b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1b\x88\xa7\x85r\x1b3\x17\xcaP\x96\xca\xd3S\xfcgM\xec\xe0\xf5!\xc8\xb4m\xd9\xb7E\xf3\x81d\x87\x93VD\xe0Ej\xcd\xec\x80\x11\x86(qZ\x9b\x80\xbf\xce\xe5*\r\x9d.o\xcd\x11s\xc5\xbc\x8c\xcb\xb9\xa9 '] ] s = tester.state() c = s.evm(sighash, sender=tester.k0, endowment=0) for test in tests: z = s.send(tester.k0, c, 0, rlp.encode(test)) assert z == utils.sha3(rlp.encode(test[:-1])) print("Passed test, gas consumed: ", s.state.receipts[-1].gas_used - s.state.receipts[-2].gas_used - s.last_tx.intrinsic_gas_used) # Create transaction t = transactions.Transaction(0, 30 * 10**9, 2999999, '', 0, sighash) t.startgas = t.intrinsic_gas_used + 50000 + 200 * len(sighash) t.v = 27 t.r = 45 t.s = 79 print("Sighash") print('Send %d wei to %s' % (t.startgas * t.gasprice, '0x'+utils.encode_hex(t.sender))) print('Contract address: 0x'+utils.encode_hex(utils.mk_contract_address(t.sender, 0))) print('Code: 0x'+utils.encode_hex(rlp.encode(t)))