def _create(self, msg): address = msg.sender result, gas_remained, new_address = create_contract(self, msg) if result: self.activities.append((self.current_msg, 'create')) self.creates_by_id[self.current_msg].append((address, new_address)) return result, gas_remained, new_address
def apply_transaction(block, tx, cb=None, validate=True): eth_call = False def dummy_cb(*args, **kwargs): pass if cb is None: cb = dummy_cb eth_call = True if validate: validate_transaction(block, tx) log_tx.debug('TX NEW', tx_dict=tx.log_dict()) # start transacting ################# block.increment_nonce(tx.sender) intrinsic_gas = intrinsic_gas_used(tx) if block.number >= block.config['HOMESTEAD_FORK_BLKNUM']: assert tx.s * 2 < transactions.secpk1n if not tx.to or tx.to == CREATE_CONTRACT_ADDRESS: intrinsic_gas += opcodes.CREATE[3] if tx.startgas < intrinsic_gas: raise InsufficientStartGas(rp('startgas', tx.startgas, intrinsic_gas)) # buy startgas if validate: assert block.get_balance(tx.sender) >= tx.startgas * tx.gasprice block.delta_balance(tx.sender, -tx.startgas * tx.gasprice) message_gas = tx.startgas - intrinsic_gas message_data = vm.CallData([safe_ord(x) for x in tx.data], 0, len(tx.data)) message = vm.Message(tx.sender, tx.to, tx.value, message_gas, message_data, code_address=tx.to) # MESSAGE ext = CapVMExt(block, tx, cb) if tx.to and tx.to != CREATE_CONTRACT_ADDRESS: result, gas_remained, data = ext._msg(message) log_tx.debug('_res_', result=result, gas_remained=gas_remained, data=data) else: # CREATE result, gas_remained, data = create_contract(ext, message) assert utils.is_numeric(gas_remained) log_tx.debug('_create_', result=result, gas_remained=gas_remained, data=data) assert gas_remained >= 0 log_tx.debug("TX APPLIED", result=result, gas_remained=gas_remained, data=data) if not result: # 0 = OOG failure in both cases log_tx.debug('TX FAILED', reason='out of gas', startgas=tx.startgas, gas_remained=gas_remained) block.gas_used += tx.startgas block.delta_balance(block.coinbase, tx.gasprice * tx.startgas) output = b'' success = 0 else: log_tx.debug('TX SUCCESS', data=data) gas_used = tx.startgas - gas_remained block.refunds += len(set(block.suicides)) * opcodes.GSUICIDEREFUND if block.refunds > 0: log_tx.debug('Refunding', gas_refunded=min(block.refunds, gas_used // 2)) gas_remained += min(block.refunds, gas_used // 2) gas_used -= min(block.refunds, gas_used // 2) block.refunds = 0 # sell remaining gas block.delta_balance(tx.sender, tx.gasprice * gas_remained) block.delta_balance(block.coinbase, tx.gasprice * gas_used) block.gas_used += gas_used if tx.to: output = b''.join(map(ascii_chr, data)) else: output = data success = 1 block.commit_state() suicides = block.suicides block.suicides = [] for s in suicides: block.ether_delta -= block.get_balance(s) block.set_balance(s, 0) block.del_account(s) block.add_transaction_to_list(tx) block.logs = [] return success, output