def __init__(self, blknum1, txindex1, oindex1, blknum2, txindex2, oindex2, newowner1, amount1, newowner2, amount2, fee, sig1=b'\x00' * 65, sig2=b'\x00' * 65): # Input 1 self.blknum1 = blknum1 self.txindex1 = txindex1 self.oindex1 = oindex1 self.sig1 = sig1 # Input 2 self.blknum2 = blknum2 self.txindex2 = txindex2 self.oindex2 = oindex2 self.sig2 = sig2 # Outputs self.newowner1 = utils.normalize_address(newowner1) self.amount1 = amount1 self.newowner2 = utils.normalize_address(newowner2) self.amount2 = amount2 # Fee self.fee = fee self.confirmation1 = None self.confirmation2 = None self.spent1 = False self.spent2 = False
def sendtx(client, blknum1, txindex1, oindex1, blknum2, txindex2, oindex2, newowner1, contractaddress1, amount1, tokenid1, newowner2, contractaddress2, amount2, tokenid2, key1, key2): if newowner1 == "0x0": newowner1 = NULL_ADDRESS if newowner2 == "0x0": newowner2 = NULL_ADDRESS if contractaddress1 == "0x0": contractaddress1 = NULL_ADDRESS if contractaddress2 == "0x0": contractaddress2 = NULL_ADDRESS if key2 is None: key2 = key1 # Form a transaction tx = Transaction(blknum1, txindex1, oindex1, blknum2, txindex2, oindex2, utils.normalize_address(newowner1), utils.normalize_address(contractaddress1), amount1, tokenid1, utils.normalize_address(newowner2), utils.normalize_address(contractaddress2), amount2, tokenid2) # Sign it tx.sign1(utils.normalize_key(key1)) tx.sign2(utils.normalize_key(key2)) client.apply_transaction(tx) print("Sent transaction")
def call(this, to, value=0, data='', sender=None, startgas=25000, gasprice=60 * denoms.shannon): sender = normalize_address(sender or this.coinbase) to = normalize_address(to, allow_blank=True) block = this.head_candidate state_root_before = block.state_root assert block.has_parent() # rebuild block state before finalization parent = block.get_parent() test_block = block.init_from_parent(parent, block.coinbase, timestamp=block.timestamp) for tx in block.get_transactions(): success, output = processblock.apply_transaction(test_block, tx) assert success # apply transaction nonce = test_block.get_nonce(sender) tx = Transaction(nonce, gasprice, startgas, to, value, data) tx.sender = sender try: success, output = processblock.apply_transaction(test_block, tx) except InvalidTransaction: success = False assert block.state_root == state_root_before if success: return output else: return False
def make_trustless_multisend(payouts, remainder, gasprice=20 * 10**9): """ Creates a transaction that trustlessly sends money to multiple recipients, and any left over (unsendable) funds to the address specified in remainder. Arguments: payouts: A list of (address, value tuples) remainder: An address in hex form to send any unsendable balance to gasprice: The gas price, in wei Returns: A transaction object that accomplishes the multisend. """ ct = abi.ContractTranslator(multisend_abi) addresses = [utils.normalize_address(addr) for addr, value in payouts] values = [value for addr, value in payouts] cdata = ct.encode_constructor_arguments([addresses, values, utils.normalize_address(remainder)]) tx = transactions.Transaction( 0, gasprice, 50000 + len(addresses) * 35000, '', sum(values), multisend_contract + cdata) tx.v = 27 tx.r = 0x0DA0DA0DA0DA0DA0DA0DA0DA0DA0DA0DA0DA0DA0DA0DA0DA0DA0DA0DA0DA0 tx.s = 0x0DA0DA0DA0DA0DA0DA0DA0DA0DA0DA0DA0DA0DA0DA0DA0DA0DA0DA0DA0DA0 while True: try: tx.sender return tx except Exception, e: # Failed to generate public key tx.r += 1
def set_dict(self, **num): print("set test") print("Data type of argument:", type(num)) for key, value in num.items(): print("{} is {}".format(key, value)) #self.root_chain.deposit(transact={'from': owner, 'value': amount}) mapping = {} mapping.update(num) for key, value in mapping.items(): print("{} is {}".format(key, value)) #convert dict to binary string bin_mapping = pickle.dumps(mapping) blknum = self.chain.next_deposit_block new_block = Block(None, blknum, NULL_SIGNATURE) new_block.add_mapping(mapping) self.chain.add_block(new_block) print("Number {} {}".format(new_block.number, self.chain.next_deposit_block)) tx = Transaction( blknum, 0, 0, 0, 0, 0, utils.normalize_address(0x0), utils.normalize_address( '0xfd02EcEE62797e75D86BCff1642EB0844afB28c7'), 1, utils.normalize_address(NULL_ADDRESS), 1, NULL_SIGNATURE, NULL_SIGNATURE, 0, bin_mapping) key1 = '3bb369fecdc16b93b99514d8ed9c2e87c5824cf4a6a98d2e8e91b7dd0c063304' print("Data type of key1:", type(key1)) tx.sign1(utils.normalize_key(key1)) self.current_block.add_transaction(tx) print("Added {}".format(self.current_block.transaction_set[0])) print("Added {}".format(self.current_block.transaction_set[0].mapping)) self.chain.set_dict(**num)
def get_utxo(self, address, block): if block != "latest": raise Exception("only support block: latest") utxo = [] for block_number, block in self.blocks.items(): for tx_index, tx in enumerate(block.transaction_set): # check if utxo belongs to the owner and is not spent if tx.newowner1 == utils.normalize_address( address) and tx.spent1 == False and not ( tx.amount1 == 0 and tx.tokenid1 == 0): utxo.append([ block_number, tx_index, 0, utils.decode_addr(tx.contractaddress1), tx.amount1, tx.tokenid1 ]) if tx.newowner2 == utils.normalize_address( address) and tx.spent2 == False and not ( tx.amount2 == 0 and tx.tokenid2 == 0): utxo.append([ block_number, tx_index, 1, utils.decode_addr(tx.contractaddress2), tx.amount2, tx.tokenid2 ]) return utxo
def __init__(self, sender, abi, address, call_func, transact_func): sender = normalize_address(sender) self.abi = abi self.address = address = normalize_address(address) self.translator = ContractTranslator(abi) for function_name in self.translator.function_data: function_proxy = MethodProxy( sender, address, function_name, self.translator, call_func, transact_func, ) type_argument = self.translator.function_data[function_name][ 'signature'] arguments = [ '{type} {argument}'.format(type=type_, argument=argument) for type_, argument in type_argument ] function_signature = ', '.join(arguments) function_proxy.__doc__ = '{function_name}({function_signature})'.format( function_name=function_name, function_signature=function_signature, ) setattr(self, function_name, function_proxy)
def tester_channels(tester_chain, tester_nettingcontracts, reveal_timeout): result = list() for first_key, second_key, nettingcontract in tester_nettingcontracts: first_externalstate = ChannelExternalStateTester( tester_chain, first_key, normalize_address(nettingcontract.address), ) first_channel = channel_from_nettingcontract( first_key, nettingcontract, first_externalstate, reveal_timeout, ) second_externalstate = ChannelExternalStateTester( tester_chain, second_key, normalize_address(nettingcontract.address), ) second_channel = channel_from_nettingcontract( second_key, nettingcontract, second_externalstate, reveal_timeout, ) result.append( (first_key, second_key, nettingcontract, first_channel, second_channel) ) return result
def main(): #init test variables gasPrice = 50000000000 # 50 gwei gasLimit = 3712394 # startgas toAddress = normalize_address("0x7AEB1Fd3A42731c4Ae80870044C992eb689fb2Fe") fromAddress = normalize_address( "0x94146296881b3322838cFF5f2d50fdde841928D8") sendAmount = 123000000000000 dappData = b"" tx, addressB, commit, randw = generateAddressB(fromAddress, toAddress, sendAmount, dappData, gasPrice, gasLimit) # print("-"* 35) # printRemix(fromAddress, tx, encode_hex(randw)) print("-" * 35) print("AddressB: %s" % addressB ) # addressB also can retreived using tx.to_dict().get("sender") print("commit: %s" % encode_hex(commit)) print("witness (w): %s" % encode_hex(randw)) # print("Reveal Transation (json): %s" % tx.to_dict()) print("Reveal Transaction (hex): %s" % encode_hex(rlp.encode(tx)))
def sendtx(client, blknum1, txindex1, oindex1, blknum2, txindex2, oindex2, cur12, amount1, newowner1, amount2, newowner2, key1, key2): if cur12 == "0x0": cur12 = NULL_ADDRESS if newowner1 == "0x0": newowner1 = NULL_ADDRESS if newowner2 == "0x0": newowner2 = NULL_ADDRESS # Form a transaction tx = Transaction(blknum1, txindex1, oindex1, blknum2, txindex2, oindex2, utils.normalize_address(cur12), utils.normalize_address(newowner1), amount1, utils.normalize_address(newowner2), amount2) # Sign it if key1: tx.sign1(utils.normalize_key(key1)) if key2: tx.sign2(utils.normalize_key(key2)) client_call(client.apply_transaction, [tx], "Sent transaction")
def create_utxo(self, to_contractaddress, provide_amount): utxos = self.get_utxos() for blknum, txindex, oindex, contractaddress, amount, tokenid in utxos: if contractaddress.lower() == to_contractaddress[2:].lower(): if amount == provide_amount: return blknum, txindex, oindex, contractaddress, amount, tokenid for blknum, txindex, oindex, contractaddress, amount, tokenid in utxos: if contractaddress.lower() == to_contractaddress[2:].lower(): if amount > provide_amount: tx = Transaction(blknum, txindex, oindex, 0, 0, 0, utils.normalize_address(self.address), utils.normalize_address(contractaddress), provide_amount, 0, utils.normalize_address(self.address), utils.normalize_address(contractaddress), amount - provide_amount, 0) tx.sign1( utils.normalize_key(plasma_config["AUTHORITY_KEY"])) tx.sign2( utils.normalize_key(plasma_config["AUTHORITY_KEY"])) self.child_chain.apply_transaction( rlp.encode(tx, Transaction).hex()) break else: raise ValueError("no available utxo") utxos = self.get_utxos() for blknum, txindex, oindex, contractaddress, amount, tokenid in utxos: if contractaddress.lower() == to_contractaddress[2:].lower(): if amount == provide_amount: return blknum, txindex, oindex, contractaddress, amount, tokenid raise Exception("Something went wrong")
def makeorder(client, address, currency, amount, tokenprice, key): utxos = client_call(client.get_utxos, [address, currency]) amount = int(amount * 1e18) # Find a utxos with enough tokens for utxo in utxos: if utxo[3] >= amount: # generate the transaction object change_amount = utxo[3] - amount if change_amount: tx = Transaction(Transaction.TxnType.make_order, utxo[0], utxo[1], utxo[2], 0, 0, 0, Transaction.UTXOType.make_order, utils.normalize_address(address), amount, tokenprice, utils.normalize_address(currency), Transaction.UTXOType.transfer, utils.normalize_address(address), change_amount, 0, utils.normalize_address(currency), 0, NULL_ADDRESS, 0, 0, NULL_ADDRESS, 0, NULL_ADDRESS, 0, 0, NULL_ADDRESS) else: tx = Transaction(Transaction.TxnType.make_order, utxo[0], utxo[1], utxo[2], 0, 0, 0, Transaction.UTXOType.make_order, utils.normalize_address(address), amount, tokenprice, utils.normalize_address(currency), 0, NULL_ADDRESS, 0, 0, NULL_ADDRESS, 0, NULL_ADDRESS, 0, 0, NULL_ADDRESS, 0, NULL_ADDRESS, 0, 0, NULL_ADDRESS) tx.sign1(utils.normalize_key(key)) client_call(client.apply_transaction, [tx], "Sent transaction") break
def hash(self): return utils.sha3(rlp.encode(self, UnsignedTransaction)) self.utxotype1 = utxotype1 self.newowner1 = utils.normalize_address(newowner1) self.amount1 = amount1 self.tokenprice1 = tokenprice1 # This field is only used if utxotype1 == make_order self.cur1 = utils.normalize_address(cur1)
def help_test_entire_block(self, path_to_jsonrpc_response): PRESENT = self.verifier_contract.TX_PROOF_RESULT_PRESENT() ABSENT = self.verifier_contract.TX_PROOF_RESULT_ABSENT() with open(path_to_jsonrpc_response, 'r') as f: jsonrpc = json.load(f) block_dict = jsonrpc['result'] for i in range(len(block_dict['transactions']) + 20): proof_blob = proveth.generate_proof_blob_from_jsonrpc_response( jsonrpc, i) result, index, nonce, gas_price, gas, to, value, data, v, r, s, contract_creation = self.verifier_contract.txProof( utils.decode_hex(block_dict['hash']), proof_blob, startgas=10**7) print(i) present = i < len(block_dict['transactions']) self.assertEqual(result, PRESENT if present else ABSENT) self.assertEqual(index, i) if present: self.assertEqual( nonce, utils.parse_as_int(block_dict['transactions'][i]['nonce'])) self.assertEqual( gas_price, utils.parse_as_int( block_dict['transactions'][i]['gasPrice'])) self.assertEqual( gas, utils.parse_as_int(block_dict['transactions'][i]['gas'])) # contract creation corner case if utils.normalize_address(block_dict['transactions'][i]['to'] or '', allow_blank=True) == b'': self.assertEqual( utils.normalize_address(to), utils.normalize_address( "0x0000000000000000000000000000000000000000")) self.assertEqual(utils.parse_as_int(contract_creation), 1) else: self.assertEqual( utils.normalize_address(to), utils.normalize_address( block_dict['transactions'][i]['to'])) self.assertEqual(utils.parse_as_int(contract_creation), 0) self.assertEqual( value, utils.parse_as_int(block_dict['transactions'][i]['value'])) self.assertEqual( data, utils.decode_hex(block_dict['transactions'][i]['input'])) self.assertEqual( v, utils.parse_as_int(block_dict['transactions'][i]['v'])) self.assertEqual( r, utils.parse_as_int(block_dict['transactions'][i]['r'])) self.assertEqual( s, utils.parse_as_int(block_dict['transactions'][i]['s'])) if i > 0 and i % 100 == 0: self.chain.mine()
def check_signing_address(self, address: str) -> bool: """ :param address: address in any format :type address: str :return: true if this address was used to sign the message, false otherwise :rtype: bool """ return utils.normalize_address(address) == utils.normalize_address( self.get_signing_address())
def __init__(self, blknum1, txindex1, oindex1, blknum2, txindex2, oindex2, newowner1, contractaddress1, amount1, tokenid1, newowner2, contractaddress2, amount2, tokenid2, fee=DEFAULT_FEE, expiretimestamp=None, salt=None, sig1=b'\x00' * 65, sig2=b'\x00' * 65): if expiretimestamp is None: expiretimestamp = int(ttime()) + DEFAULT_DELAY_SECONDS if salt is None: salt = randint(1000000000000, 9999999999999) # Input 1 self.blknum1 = blknum1 self.txindex1 = txindex1 self.oindex1 = oindex1 self.sig1 = sig1 # Input 2 self.blknum2 = blknum2 self.txindex2 = txindex2 self.oindex2 = oindex2 self.sig2 = sig2 # Outputs self.newowner1 = utils.normalize_address(newowner1) self.contractaddress1 = utils.normalize_address(contractaddress1) self.amount1 = amount1 self.tokenid1 = tokenid1 self.newowner2 = utils.normalize_address(newowner2) self.contractaddress2 = utils.normalize_address(contractaddress2) self.amount2 = amount2 self.tokenid2 = tokenid2 self.fee = fee self.expiretimestamp = expiretimestamp self.salt = salt self.confirmation1 = None self.confirmation2 = None self.spent1 = False self.spent2 = False
def verify_to_address_field(self): title = "Input error" body = "Invalid address field" try: normalize_address(self.send_to_address) except Exception: dialog = Controller.create_dialog(title, body) dialog.open() return False return True
def transact(this, to, value=0, data='', sender=None, startgas=25000, gasprice=60 * denoms.shannon): sender = normalize_address(sender or this.coinbase) to = normalize_address(to, allow_blank=True) nonce = this.pending.get_nonce(sender) tx = Transaction(nonce, gasprice, startgas, to, value, data) this.app.services.accounts.sign_tx(sender, tx) assert tx.sender == sender this.chainservice.add_transaction(tx) return tx
def generateInvalidUnlockTx(self, userAddress, contractAddress, maliciousAddress): commit, witness, R, S = generate_submarine_commit._generateRS( normalize_address(rec_hex(userAddress)), normalize_address(rec_hex(contractAddress)), UNLOCK_AMOUNT, b'', OURGASPRICE, OURGASLIMIT) unlockFunctionSelector = b"\xec\x9b\x5b\x3a" submarineData = unlockFunctionSelector + commit # need the unsigned TX hash for ECRecover unlock_tx_unsigned_object = transactions.UnsignedTransaction( 0, # nonce; OURGASPRICE, # gasprice OURGASLIMIT, # startgas normalize_address(maliciousAddress), # to addr UNLOCK_AMOUNT, # value submarineData, # data ) unlock_tx_unsigned_hash = sha3( rlp.encode(unlock_tx_unsigned_object, transactions.UnsignedTransaction)) unlock_tx_object = transactions.Transaction( 0, # nonce; OURGASPRICE, # gasprice OURGASLIMIT, # startgas normalize_address(maliciousAddress), # to addr UNLOCK_AMOUNT, # value submarineData, # data 27, # v R, # r S # s ) try: pub = ecrecover_to_pub(unlock_tx_unsigned_hash, 27, R, S) if pub == b"\x00" * 64: log.info("Address no good, retrying") return self.generateInvalidUnlockTx(userAddress, contractAddress, maliciousAddress) else: commit_addr = sha3(pub)[-20:] log.info("Fake Unlock TX Dict: {}".format( unlock_tx_unsigned_object.as_dict())) log.info("Fake Unlock TX Commit B: {}".format(commit_addr)) return unlock_tx_object, unlock_tx_unsigned_object, commit_addr, commit, witness except (ValueError, InvalidTransaction) as e: if isinstance(e, ValueError) and "VRS" not in str(e): raise log.info("Address no good (%s), retrying" % e) return self.generateInvalidUnlockTx(userAddress, contractAddress, maliciousAddress)
def channel_from_nettingcontract( our_key, netting_contract, external_state, reveal_timeout): """ Create a `channel.Channel` for the `netting_contract`. Use this to make sure that both implementations (the smart contract and the python code) work in tandem. """ our_address = privatekey_to_address(our_key) token_address_hex = netting_contract.tokenAddress(sender=our_key) settle_timeout = netting_contract.settleTimeout(sender=our_key) address_balance = netting_contract.addressAndBalance(sender=our_key) address1_hex, balance1, address2_hex, balance2 = address_balance token_address = normalize_address(token_address_hex) address1 = normalize_address(address1_hex) address2 = normalize_address(address2_hex) if our_address == address1: our_balance = balance1 partner_address = address2 partner_balance = balance2 else: our_balance = balance2 partner_address = address1 partner_balance = balance1 our_state = ChannelEndState( our_address, our_balance, None, EMPTY_MERKLE_TREE, ) partner_state = ChannelEndState( partner_address, partner_balance, None, EMPTY_MERKLE_TREE, ) channel = Channel( our_state, partner_state, external_state, token_address, reveal_timeout, settle_timeout, ) return channel
def get_dao_balance(state, address): msg_data = CallData( [ord(x) for x in dao_ct.encode('balanceOf', [address])]) msg = Message(normalize_address(address), normalize_address(dao), 0, 1000000, msg_data, code_address=normalize_address(dao)) output = ''.join(map(chr, apply_const_message(state, msg))) return dao_ct.decode('balanceOf', output)[0]
def run(self, sender=None, to=None, code=None, gas=None): sender = normalize_address(sender) if sender else normalize_address(zpad('sender', 20)) to = normalize_address(to) if to else normalize_address(zpad('receiver', 20)) code = scan_bin(code) if code else '' gas = scan_int(gas) if gas else 10000000000000 msg = vm.Message(sender, to, gas=gas) ext = VMExt(self.state, Transaction(0, 0, 21000, b'', 0, b'')) result, gas_remained, data = _apply_msg(ext, msg, code) return bytearray_to_bytestr(data) if result else None
def get_trusted_transactions(addr, trusted_addresses): txs = blockchain.get_transactions_on_address(addr) trusted_txs = [] norm_trusted_addresses = [] for address in trusted_addresses: norm_trusted_addresses.append(normalize_address(address)) for tx in txs: if normalize_address(tx['from']) in norm_trusted_addresses: trusted_txs.append(tx) return trusted_txs
def get_takeorder_txn(self, address, utxopos, amount): print("called get_takeorder_txn with params [%s, %d, %d]" % (address, utxopos, amount)) encoded_utxos = self.get_utxos(address, ZERO_ADDRESS) blkid = int(utxopos / 1000000000) txid = int((utxopos % 1000000000) / 10000) oindex = utxopos % 10000 tx_info = self._get_input_info(blkid, txid, oindex, None, None) print("make order info: %s" % str(tx_info)) utxos = rlp.decode(utils.decode_hex(encoded_utxos), rlp.sedes.CountableList(rlp.sedes.List([rlp.sedes.big_endian_int, rlp.sedes.big_endian_int, rlp.sedes.big_endian_int, rlp.sedes.big_endian_int]))) tx = None purchase_price = Web3.fromWei(amount, 'ether') * tx_info['tokenprice'] # Find a utxos with enough ether for utxo in utxos: if utxo[3] >= purchase_price: # generate the transaction object ether_change_amount = utxo[3] - purchase_price makeorder_change_amount = tx_info['amount'] - amount if ether_change_amount: ether_change_utxo = [Transaction.UTXOType.transfer, utils.normalize_address(address), int(ether_change_amount), 0, ZERO_ADDRESS] else: ether_change_utxo = [0, ZERO_ADDRESS, 0, 0, ZERO_ADDRESS] if makeorder_change_amount: makeorder_change_utxo = [Transaction.UTXOType.make_order, utils.normalize_address(tx_info['owner']), int(makeorder_change_amount), tx_info['tokenprice'], utils.normalize_address(tx_info['currency'])] else: makeorder_change_utxo = [0, ZERO_ADDRESS, 0, 0, ZERO_ADDRESS] tx = Transaction(Transaction.TxnType.take_order, utxo[0], utxo[1], utxo[2], blkid, txid, oindex, Transaction.UTXOType.transfer, utils.normalize_address(tx_info['owner']), int(purchase_price), 0, ZERO_ADDRESS, # The ether payment to seller Transaction.UTXOType.transfer, utils.normalize_address(address), amount, 0, utils.normalize_address(tx_info['currency']), # The token transfer to buyer *(ether_change_utxo + makeorder_change_utxo)) break return (tx, tx.readable_str if tx else None)
def del_account(self, address): self.set_balance(address, 0) self.set_nonce(address, 0) self.set_code(address, b'') self.reset_storage(address) self.set_and_journal( self.get_and_cache_account( utils.normalize_address(address)), 'deleted', True) self.set_and_journal( self.get_and_cache_account( utils.normalize_address(address)), 'touched', False)
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 address_hex(address): """ Normalizes address. """ prefix = "0x" address_hex = prefix + normalize_address(address).encode("hex") return address_hex
def test_recoverAddressFromSignature(tester_chain, tester_nettingchannel_library_address): auxiliary = deploy_auxiliary_tester(tester_chain, tester_nettingchannel_library_address) privkey, address = make_privkey_address() msg = DirectTransfer( identifier=1, nonce=1, token='x' * 20, channel=auxiliary.address, transferred_amount=10, recipient='y' * 20, locksroot=HASH ) msg.sign(privkey, address) data = msg.encode() signature = data[-65:] extra_hash = sha3(data[:-65]) computed_address = auxiliary.recoverAddressFromSignature( msg.nonce, msg.transferred_amount, msg.locksroot, extra_hash, signature ) assert normalize_address(computed_address) == msg.sender
def new_filter( jsonrpc_client: JSONRPCClient, contract_address: address, topics: Optional[List[int]], from_block: Union[str, int] = 0, to_block: Union[str, int] = 'latest'): """ Custom new filter implementation to handle bad encoding from geth rpc. """ if isinstance(from_block, int): from_block = hex(from_block) if isinstance(to_block, int): to_block = hex(to_block) json_data = { 'fromBlock': from_block, 'toBlock': to_block, 'address': address_encoder(normalize_address(contract_address)), } if topics is not None: json_data['topics'] = [ topic_encoder(topic) for topic in topics ] return jsonrpc_client.call('eth_newFilter', json_data)
def send_transaction(self, transaction): tx = rlp.decode(utils.decode_hex(transaction), Transaction) # Reject transactions refering to a future block as prev_block if (tx.prev_block > self.current_block_number + self.child_block_interval): raise InvalidPrevBlockException('failed to send transaction') # If the tx we are spending is not a deposit tx if tx.prev_block % self.child_block_interval == 0: # If the TX we are referencing was initially a deposit TX, then it # does not have a signature attached # The tx we are referencing should be included in a block prev_tx = self.blocks[tx.prev_block].get_tx_by_uid(tx.uid) if prev_tx is None: raise PreviousTxNotFoundException('failed to send transaction') # The tx we are referencing should not be spent if prev_tx.spent: raise TxAlreadySpentException('failed to send transaction') # deposit tx if prev_block is 0 if (prev_tx.prev_block % self.child_block_interval == 0 and utils.normalize_address(tx.sender) != prev_tx.new_owner): raise InvalidTxSignatureException('failed to send transaction') # `add_tx` automatically checks if the coin has already been moved # in the current block self.current_block.add_tx(tx) prev_tx.spent = True # Mark the previous tx as spent # If the tx we are spending is a deposit tx else: self.current_block.add_tx(tx) return tx.hash
def verify_block(block_info): # verify the difficulty if utils.parse_as_int(block_info['difficulty']) < 10000000: return False if int(normalize_bytes(block_info["nonce"]).hex(), 16) * utils.parse_as_int(block_info['difficulty']) \ > pow(2, 256): return False # get block header from block info header = block.BlockHeader( normalize_bytes(block_info["parentHash"]), normalize_bytes(block_info["sha3Uncles"]), utils.normalize_address(block_info["miner"]), normalize_bytes(block_info["stateRoot"]), normalize_bytes(block_info["transactionsRoot"]), normalize_bytes(block_info["receiptsRoot"]), utils.bytes_to_int(normalize_bytes(block_info["logsBloom"])), utils.parse_as_int(block_info['difficulty']), utils.parse_as_int(block_info['number']), utils.parse_as_int(block_info['gasLimit']), utils.parse_as_int(block_info['gasUsed']), utils.parse_as_int(block_info['timestamp']), normalize_bytes(block_info["extraData"]), normalize_bytes(block_info["mixHash"]), normalize_bytes(block_info["nonce"]), ) # calculate the block hash # compare the block hash with trusted block hash if normalize_bytes(block_info.hash) != header.hash: return False else: return True
def test_recoverAddressFromSignature(tester_chain, tester_nettingchannel_library_address): auxiliary = deploy_auxiliary_tester(tester_chain, tester_nettingchannel_library_address) privkey, address = make_privkey_address() message_identifier = random.randint(0, UINT64_MAX) msg = DirectTransfer(message_identifier=message_identifier, payment_identifier=1, nonce=1, registry_address='x' * 20, token='x' * 20, channel=auxiliary.address, transferred_amount=10, recipient='y' * 20, locksroot=HASH) msg.sign(privkey, address) data = msg.encode() signature = data[-65:] extra_hash = sha3(data[:-65]) computed_address = auxiliary.recoverAddressFromSignature( msg.nonce, msg.transferred_amount, msg.locksroot, extra_hash, signature) assert normalize_address(computed_address) == msg.sender
def address_by_endpoint(self, endpoint): address = self.proxy.call('findAddressByEndpoint', endpoint) if address == self.not_found_address: # the 0 address means nothing found return None return normalize_address(address)
def validate_transaction(block, tx): def rp(what, actual, target): return "%r: %r actual:%r target:%r" % (tx, what, actual, target) # (1) The transaction signature is valid; if not tx.sender: # sender is set and validated on Transaction initialization if block.number >= config.default_config["METROPOLIS_FORK_BLKNUM"]: tx._sender = normalize_address(config.default_config["METROPOLIS_ENTRY_POINT"]) else: raise UnsignedTransaction(tx) if block.number >= config.default_config["HOMESTEAD_FORK_BLKNUM"]: tx.check_low_s() # (2) the transaction nonce is valid (equivalent to the # sender account's current nonce); acctnonce = block.get_nonce(tx.sender) if acctnonce != tx.nonce: raise InvalidNonce(rp("nonce", tx.nonce, acctnonce)) # (3) the gas limit is no smaller than the intrinsic gas, # g0, used by the transaction; if tx.startgas < tx.intrinsic_gas_used: raise InsufficientStartGas(rp("startgas", tx.startgas, tx.intrinsic_gas_used)) # (4) the sender account balance contains at least the # cost, v0, required in up-front payment. total_cost = tx.value + tx.gasprice * tx.startgas if block.get_balance(tx.sender) < total_cost: raise InsufficientBalance(rp("balance", block.get_balance(tx.sender), total_cost)) # check block gas limit if block.gas_used + tx.startgas > block.gas_limit: raise BlockGasLimitReached(rp("gaslimit", block.gas_used + tx.startgas, block.gas_limit)) return True
def faucet_send(o, to, value): value = int(value * denoms.ether) nonce = o.eth.get_transaction_count(Faucet.ADDR.encode('hex')) to = normalize_address(to) tx = Transaction(nonce, 1, 21000, to, value, '') tx.sign(Faucet.PRIVKEY) r = o.eth.send(tx) print "Transaction sent:", r gevent.sleep(10)
def get_filter_events( jsonrpc_client: JSONRPCClient, contract_address: address, topics: Optional[List[int]], from_block: Union[str, int] = 0, to_block: Union[str, int] = 'latest') -> List[Dict]: """ Get filter. This handles bad encoding from geth rpc. """ if isinstance(from_block, int): from_block = hex(from_block) if isinstance(to_block, int): to_block = hex(to_block) json_data = { 'fromBlock': from_block, 'toBlock': to_block, 'address': address_encoder(normalize_address(contract_address)), } if topics is not None: json_data['topics'] = [ topic_encoder(topic) for topic in topics ] filter_changes = jsonrpc_client.call('eth_getLogs', json_data) # geth could return None if filter_changes is None: return [] result = [] for log_event in filter_changes: address = address_decoder(log_event['address']) data = data_decoder(log_event['data']) topics = [ topic_decoder(topic) for topic in log_event['topics'] ] block_number = log_event.get('blockNumber') if not block_number: block_number = 0 else: block_number = int(block_number, 0) result.append({ 'topics': topics, 'data': data, 'address': address, 'block_number': block_number, }) return result
def new_filter(jsonrpc_client, contract_address, topics): """ Custom new filter implementation to handle bad encoding from geth rpc. """ json_data = { 'fromBlock': '', 'toBlock': '', 'address': address_encoder(normalize_address(contract_address)), 'topics': [topic_encoder(topic) for topic in topics], } return jsonrpc_client.call('eth_newFilter', json_data)
def encode_payment(to, value): value = long(value) assert value < 2**96 value = zpad(int_to_big_endian(value), 12) assert type(value) is str assert len(value) == 12 to = normalize_address(to) assert len(to) == 20 mix = value + to assert len(mix) == 32 return mix
def gimme_money(ethnode, addr, value): nonce = ethnode.get_transaction_count(Faucet.ADDR.encode('hex')) addr = normalize_address(addr) tx = Transaction(nonce, 1, 21000, addr, value, '') tx.sign(Faucet.PRIVKEY) h = ethnode.send(tx) log.info("Faucet --({} ETH)--> {} ({})".format(float(value) / 10**18, addr.encode('hex'), h)) h = h[2:].decode('hex') assert h == tx.hash return h
def __init__( self, sender: address, abi: Dict, contract_address: address, call_function: Callable, transact_function: Callable, estimate_function: Optional[Callable] = None): sender = normalize_address(sender) contract_address = normalize_address(contract_address) translator = ContractTranslator(abi) self.abi = abi self.call_function = call_function self.contract_address = contract_address self.estimate_function = estimate_function self.sender = sender self.transaction_function = transact_function self.translator = translator self.valid_kargs = {'gasprice', 'startgas', 'value'}
def test_multisends(payouts, transactions): s = tester.state() roottx = transactions[0] s.state.set_balance(roottx.sender, roottx.value + roottx.startgas * roottx.gasprice) gas_used = 0 for i, tx in enumerate(transactions): s.state.get_balance(roottx.sender) state_transition.apply_transaction(s.state, tx) print "Applying transaction number %d consumed %d gas out of %d" % (i, s.state.gas_used - gas_used, tx.startgas) gas_used = s.state.gas_used for addr, value in payouts: balance = s.state.get_balance(utils.normalize_address(addr)) assert balance == value, (addr, balance, value) return s.state.gas_used
def __init__(self, nonce, gasprice, startgas, to, value, data, v=0, r=0, s=0): self.data = None to = utils.normalize_address(to, allow_blank=True) assert len(to) == 20 or len(to) == 0 super(Transaction, self).__init__(nonce, gasprice, startgas, to, value, data, v, r, s) self.logs = [] if self.gasprice >= TT256 or self.startgas >= TT256 or \ self.value >= TT256 or self.nonce >= TT256: raise InvalidTransaction("Values way too high!") if self.startgas < self.intrinsic_gas_used: raise InvalidTransaction("Startgas too low") log.debug('deserialized tx', tx=encode_hex(self.hash)[:8])
def all_contract_events_raw(rpc, contract_address, start_block=None, end_block=None): """Find all events for a deployed contract given its `contract_address`. Args: rpc (pyethapp.rpc_client.JSONRPCClient): client instance. contract_address (string): hex encoded contract address. start_block (int): read event-logs starting from this block number. end_block (int): read event-logs up to this block number. Returns: events (list) """ return rpc.call('eth_getLogs', { 'fromBlock': str(start_block or 0), 'toBlock': str(end_block or 'latest'), 'address': address_encoder(normalize_address(contract_address)), 'topics': [], })
def all_contract_events_raw( rpc: JSONRPCClient, contract_address: str, start_block: Union[str, int] = 0, end_block: Union[str, int] = 'latest') -> List[Dict]: """Find all events for a deployed contract given its `contract_address`. Args: rpc: client instance. contract_address: hex encoded contract address. start_block: read event-logs starting from this block number (default: 0). end_block: read event-logs up to this block number (default: 'latest'). Returns: events """ return rpc.call('eth_getLogs', { 'fromBlock': str(start_block), 'toBlock': str(end_block), 'address': address_encoder(normalize_address(contract_address)), 'topics': [], })
def __init__(self, nonce, gasprice, startgas, to, value, data, v=0, r=0, s=0): self.data = None to = utils.normalize_address(to, allow_blank=True) super( Transaction, self).__init__( nonce, gasprice, startgas, to, value, data, v, r, s) if self.gasprice >= TT256 or self.startgas >= TT256 or \ self.value >= TT256 or self.nonce >= TT256: raise InvalidTransaction("Values way too high!")
def test_blockchain( blockchain_backend, # required to start the geth backend pylint: disable=unused-argument blockchain_rpc_ports, private_keys, poll_timeout): # pylint: disable=too-many-locals addresses = [ privatekey_to_address(priv) for priv in private_keys ] privatekey = private_keys[0] address = privatekey_to_address(privatekey) total_token = 100 host = '127.0.0.1' jsonrpc_client = JSONRPCClient( host, blockchain_rpc_ports[0], privatekey, ) humantoken_path = get_contract_path('HumanStandardToken.sol') humantoken_contracts = compile_file(humantoken_path, libraries=dict()) token_proxy = jsonrpc_client.deploy_solidity_contract( address, 'HumanStandardToken', humantoken_contracts, list(), (total_token, 'raiden', 2, 'Rd'), contract_path=humantoken_path, gasprice=GAS_PRICE, timeout=poll_timeout, ) registry_path = get_contract_path('Registry.sol') registry_contracts = compile_file(registry_path) registry_proxy = jsonrpc_client.deploy_solidity_contract( address, 'Registry', registry_contracts, list(), tuple(), contract_path=registry_path, gasprice=GAS_PRICE, timeout=poll_timeout, ) log_list = jsonrpc_client.call( 'eth_getLogs', { 'fromBlock': '0x0', 'toBlock': 'latest', 'topics': [], }, ) assert not log_list assert token_proxy.call('balanceOf', address) == total_token transaction_hash = registry_proxy.transact( 'addToken', token_proxy.contract_address, gasprice=denoms.wei, ) jsonrpc_client.poll(unhexlify(transaction_hash), timeout=poll_timeout) assert len(registry_proxy.call('tokenAddresses')) == 1 log_list = jsonrpc_client.call( 'eth_getLogs', { 'fromBlock': '0x0', 'toBlock': 'latest', 'topics': [], }, ) assert len(log_list) == 1 channel_manager_address_encoded = registry_proxy.call( 'channelManagerByToken', token_proxy.contract_address, ) channel_manager_address = normalize_address(channel_manager_address_encoded) log = log_list[0] log_topics = [ topic_decoder(topic) for topic in log['topics'] # pylint: disable=invalid-sequence-index ] log_data = log['data'] # pylint: disable=invalid-sequence-index event = registry_proxy.translator.decode_event( log_topics, unhexlify(log_data[2:]), ) assert channel_manager_address == normalize_address(event['channel_manager_address']) assert token_proxy.contract_address == normalize_address(event['token_address']) channel_manager_proxy = jsonrpc_client.new_contract_proxy( CONTRACT_MANAGER.get_abi(CONTRACT_CHANNEL_MANAGER), channel_manager_address, ) transaction_hash = channel_manager_proxy.transact( 'newChannel', addresses[1], 10, gasprice=denoms.wei, ) jsonrpc_client.poll(unhexlify(transaction_hash), timeout=poll_timeout) log_list = jsonrpc_client.call( 'eth_getLogs', { 'fromBlock': '0x0', 'toBlock': 'latest', 'topics': [], }, ) assert len(log_list) == 2
def get_dao_balance(state, address): msg_data = CallData([ord(x) for x in dao_ct.encode('balanceOf', [address])]) msg = Message(normalize_address(address), normalize_address(dao), 0, 1000000, msg_data, code_address=normalize_address(dao)) output = ''.join(map(chr, apply_const_message(state, msg))) return dao_ct.decode('balanceOf', output)[0]
def test(): s = t.state() t.gas_price = 0 s.block.coinbase = '\x35' * 20 content = open('one_phase_auction.sol').read() + open('two_phase_auction.sol').read() + open('adStorer.sol').read() logs = [] c = s.abi_contract(content, language='solidity', log_listener = lambda x: logs.append(x)) opa_sig = t.languages['solidity'].mk_full_signature(content, 'OnePhaseAuction') tpa_sig = t.languages['solidity'].mk_full_signature(content, 'TwoPhaseAuction') auctions = [] while not c.initialize(): pass for i in range(7): a = utils.normalize_address(c.getAuctionAddress(i)) auctions.append(t.ABIContract(s, opa_sig if i < 4 else tpa_sig, a, True, lambda x: logs.append(x))) bids = ( # bidder, value, higherValue, metadata (0, 10000, 100000, 'horse'), (1, 50000, 200000, 'cow'), (2, 102000, 300000, 'dog'), (3, 80000, 400000, 'mooch') ) desired_winner = (2, 'dog') desired_balance_changes = [ # First price [0 + 102, 0 + 204, -102000 + 306, 0 + 408], # Second price [0 + 80, 0 + 160, -80000 + 240, 0 + 320], # All pay [-10000 + 242, -50000 + 484, -102000 + 726, -80000 + 968] ] # Test all three auction types start_time = s.block.timestamp for i in range(3): print 'Starting tests for two-phase auction type %d' % i s.block.timestamp = start_time for p in permutations(bids): old_balances = [s.block.get_balance(x) for x in t.accounts] bid_ids = [] for bidder, value, higherValue, metadata in p: _id = auctions[4 + i].commitBid(sha3num(value, '\x35' * 32), metadata, value=higherValue, sender=t.keys[bidder]) assert _id >= 0, _id bid_ids.append(_id) assert not auctions[4 + i].revealBid(_id, value, '\x35' * 32) s.mine(1, coinbase='\x35' * 20) s.block.timestamp += 86400 assert auctions[4 + i].commitBid(sha3num(value, '\x35' * 32), metadata, value=higherValue, sender=t.keys[bidder]) < 0 for _id, (bidder, value, higherValue, metadata) in zip(bid_ids, p): assert not auctions[4 + i].revealBid(_id, value - 1, '\x35' * 32) o = auctions[4 + i].revealBid(_id, value, '\x35' * 32) assert o s.mine(1, coinbase='\x35' * 20) s.block.timestamp += 86400 assert not auctions[4 + i].revealBid(_id, value) while 1: r = auctions[4 + i].ping() if r: break assert auctions[4 + i].getPhase() == 1, auctions[4 + i].getPhase() auction_winner_logs = [x for x in logs if x["_event_type"] == "AuctionWinner"] assert len(auction_winner_logs) assert auction_winner_logs[-1]["bidder"] == t.accounts[desired_winner[0]].encode('hex') assert auction_winner_logs[-1]["metadata"].strip('\x00') == desired_winner[1] new_balances = [s.block.get_balance(x) for x in t.accounts] deltas = [a - b for a,b in zip(new_balances, old_balances)] assert deltas[:len(desired_balance_changes[i])] == desired_balance_changes[i], (deltas, desired_balance_changes[i]) assert c.getWinnerAddress(4 + i) == t.accounts[desired_winner[0]].encode('hex') assert c.getWinnerUrl(4 + i) == desired_winner[1] bids = ( # bidder, value, metadata, expected result (0, 200, "cow", True), (2, 220, "moose", True), # increases max 200 -> 220 (1, 270, "pig", True), # increases max 220 -> 270 (2, 240, "moose", False), # 240 < 270 (3, 280, "mouse", False), # 280 < 270 * 1.05 (4, 290, "remorse", True), # increases max 270 -> 290 (1, 30, None, False), # 270+30 = 300 < 290 * 1.05 (1, 50, None, True), # increases max 290 -> 270+50 = 320 (2, 110, None, False), # 220+110 = 330 < 320 * 1.05 (2, 170, None, True), # increasea max 320 -> 220+170 = 390 ) desired_winners = [(4, "remorse"), (2, "moose"), (4, "remorse"), (2, "moose")] desired_balance_changes = [ [0, 0, 0, 0, -290], [0, 0, -390, 0, 0], [-200, -270, -220, 0, -290], [-200, -320, -390, 0, -290] ] for i in range(4): print "Starting tests for one-phase auction type %d" % i s.block.timestamp = start_time bidmap = {} old_balances = [s.block.get_balance(x) for x in t.accounts] for bidder, value, metadata, expected_result in bids: if metadata: o = auctions[i].bid(metadata, value=value, sender=t.keys[bidder]) assert (o >= 0) is expected_result if o >= 0: bidmap[bidder] = o elif i & 1: assert auctions[i].increaseBid(bidmap[bidder], value=value, sender=t.keys[bidder]) is expected_result s.mine(1, coinbase='\x35' * 20) s.block.timestamp += 86400 newish_balances = [s.block.get_balance(x) for x in t.accounts] deltas0 = [a - b for a,b in zip(newish_balances, old_balances)] while not auctions[i].ping(): pass auction_winner_logs = [x for x in logs if x["_event_type"] == "AuctionWinner"] assert len(auction_winner_logs) assert auction_winner_logs[-1]["bidder"] == t.accounts[desired_winners[i][0]].encode('hex') assert auction_winner_logs[-1]["metadata"] == desired_winners[i][1] new_balances = [s.block.get_balance(x) for x in t.accounts] deltas = [a - b for a,b in zip(new_balances, old_balances)] assert deltas[:len(desired_balance_changes[i])] == desired_balance_changes[i] assert c.getWinnerAddress(i) == t.accounts[desired_winners[i][0]].encode('hex') assert c.getWinnerUrl(i) == desired_winners[i][1]
def run_state_test(params, mode): pre = params['pre'] exek = params['transaction'] env = params['env'] assert set(env.keys()) == set(['currentGasLimit', 'currentTimestamp', 'previousHash', 'currentCoinbase', 'currentDifficulty', 'currentNumber']) assert len(env['currentCoinbase']) == 40 # setup env header = blocks.BlockHeader( prevhash=decode_hex(env['previousHash']), number=parse_int_or_hex(env['currentNumber']), coinbase=decode_hex(env['currentCoinbase']), difficulty=parse_int_or_hex(env['currentDifficulty']), timestamp=parse_int_or_hex(env['currentTimestamp']), # work around https://github.com/ethereum/pyethereum/issues/390 [1]: gas_limit=min(2 ** 63 - 1, parse_int_or_hex(env['currentGasLimit']))) blk = blocks.Block(header, env=db_env) # work around https://github.com/ethereum/pyethereum/issues/390 [2]: blk.gas_limit = parse_int_or_hex(env['currentGasLimit']) # setup state for address, h in list(pre.items()): assert len(address) == 40 address = decode_hex(address) assert set(h.keys()) == set(['code', 'nonce', 'balance', 'storage']) blk.set_nonce(address, parse_int_or_hex(h['nonce'])) blk.set_balance(address, parse_int_or_hex(h['balance'])) blk.set_code(address, decode_hex(h['code'][2:])) for k, v in h['storage'].items(): blk.set_storage_data(address, utils.big_endian_to_int(decode_hex(k[2:])), utils.big_endian_to_int(decode_hex(v[2:]))) for address, h in list(pre.items()): address = decode_hex(address) assert blk.get_nonce(address) == parse_int_or_hex(h['nonce']) assert blk.get_balance(address) == parse_int_or_hex(h['balance']) assert blk.get_code(address) == decode_hex(h['code'][2:]) for k, v in h['storage'].items(): assert blk.get_storage_data(address, utils.big_endian_to_int( decode_hex(k[2:]))) == utils.big_endian_to_int(decode_hex(v[2:])) # execute transactions orig_apply_msg = pb.apply_msg def apply_msg_wrapper(ext, msg): def blkhash(n): if n >= blk.number or n < blk.number - 256: return b'' else: return utils.sha3(to_string(n)) ext.block_hash = blkhash return orig_apply_msg(ext, msg) pb.apply_msg = apply_msg_wrapper try: tx = transactions.Transaction( nonce=parse_int_or_hex(exek['nonce'] or b"0"), gasprice=parse_int_or_hex(exek['gasPrice'] or b"0"), startgas=parse_int_or_hex(exek['gasLimit'] or b"0"), to=normalize_address(exek['to'], allow_blank=True), value=parse_int_or_hex(exek['value'] or b"0"), data=decode_hex(remove_0x_head(exek['data']))) except InvalidTransaction: tx = None success, output = False, b'' time_pre = time.time() time_post = time_pre else: if 'secretKey' in exek: tx.sign(exek['secretKey']) elif all(key in exek for key in ['v', 'r', 's']): tx.v = decode_hex(remove_0x_head(exek['v'])) tx.r = decode_hex(remove_0x_head(exek['r'])) tx.s = decode_hex(remove_0x_head(exek['s'])) else: assert False time_pre = time.time() try: print('trying') success, output = pb.apply_transaction(blk, tx) blk.commit_state() print('success', blk.get_receipts()[-1].gas_used) except InvalidTransaction: success, output = False, b'' blk.commit_state() pass time_post = time.time() if tx.to == b'': output = blk.get_code(output) pb.apply_msg = orig_apply_msg params2 = copy.deepcopy(params) if success: params2['logs'] = [log.to_dict() for log in blk.get_receipt(0).logs] params2['out'] = b'0x' + encode_hex(output) params2['post'] = copy.deepcopy(blk.to_dict(True)['state']) params2['postStateRoot'] = encode_hex(blk.state.root_hash) if mode == FILL: return params2 elif mode == VERIFY: params1 = copy.deepcopy(params) shouldbe, reallyis = params1.get('post', None), params2.get('post', None) compare_post_states(shouldbe, reallyis) for k in ['pre', 'exec', 'env', 'callcreates', 'out', 'gas', 'logs', 'postStateRoot']: _shouldbe = params1.get(k, None) _reallyis = params2.get(k, None) if _shouldbe != _reallyis: print(('Mismatch {key}: shouldbe {shouldbe_key} != reallyis {reallyis_key}.\n' 'post: {shouldbe_post} != {reallyis_post}').format( shouldbe_key=_shouldbe, reallyis_key=_reallyis, shouldbe_post=shouldbe, reallyis_post=reallyis, key=k)) raise Exception("Mismatch: " + k + ':\n shouldbe %r\n reallyis %r' % (_shouldbe, _reallyis)) elif mode == TIME: return time_post - time_pre
# Metropolis fork METROPOLIS_FORK_BLKNUM=4370000, METROPOLIS_ENTRY_POINT=2 ** 160 - 1, METROPOLIS_STATEROOT_STORE=0x10, METROPOLIS_BLOCKHASH_STORE=0x20, METROPOLIS_WRAPAROUND=65536, METROPOLIS_GETTER_CODE=decode_hex('6000355460205260206020f3'), METROPOLIS_DIFF_ADJUSTMENT_CUTOFF=9, # Constantinople fork CONSTANTINOPLE_FORK_BLKNUM=2**100, # DAO fork DAO_FORK_BLKNUM=1920000, DAO_FORK_BLKHASH=decode_hex( '4985f5ca3d2afbec36529aa96f74de3cc10a2a4a6c44f2157a57d2c6059a11bb'), DAO_FORK_BLKEXTRA=decode_hex('64616f2d686172642d666f726b'), DAO_WITHDRAWER=utils.normalize_address( '0xbf4ed7b27f1d666546e30d74d50d173d20bca754'), # Anti-DoS fork ANTI_DOS_FORK_BLKNUM=2463000, SPURIOUS_DRAGON_FORK_BLKNUM=2675000, CONTRACT_CODE_SIZE_LIMIT=0x6000, # Default consensus strategy: ethash, poa, casper, pbft CONSENSUS_STRATEGY='ethash', # Serenity fork SERENITY_FORK_BLKNUM=2**99, PREV_HEADER_DEPTH=256, SYSTEM_ENTRY_POINT=utils.int_to_addr(2**160 - 2), SERENITY_HEADER_VERIFIER=utils.int_to_addr(255), SERENITY_HEADER_POST_FINALIZER=utils.int_to_addr(254), SERENITY_GETTER_CODE=decode_hex( '60ff331436604014161560155760203560003555005b6000355460205260206020f3'), # Custom specials
print 'State created' # Check pre-balance pre_balance = state.get_balance(my_account) pre_dao_tokens = get_dao_balance(state, my_account) pre_withdrawer_balance = state.get_balance(withdrawer) print 'Pre ETH (wei) balance: %d' % pre_balance print 'Pre DAO (base unit) balance: %d' % pre_dao_tokens # Attempt to claim the ETH without approving (should fail) tx0 = Transaction(state.get_nonce(my_account), 0, 1000000, withdrawer, 0, withdrawer_ct.encode('withdraw', [])).sign('\x33' * 32) tx0._sender = normalize_address(my_account) apply_transaction(state, tx0) med_balance = state.get_balance(my_account) med_dao_tokens = get_dao_balance(state, my_account) med_withdrawer_balance = state.get_balance(withdrawer) assert med_balance == pre_balance assert med_dao_tokens == pre_dao_tokens assert med_withdrawer_balance == pre_withdrawer_balance > 0 print 'ETH claim without approving failed, as expected' # Approve the withdrawal tx1 = Transaction(state.get_nonce(my_account), 0, 1000000, dao, 0, dao_ct.encode('approve', [withdrawer, 100000 * 10**18])).sign('\x33' * 32)
def test_withdraw_at_settlement_block( deposit, settle_timeout, tester_nettingcontracts, tester_chain, tester_token): """ It must be possible to unlock a lock up to and including the settlment block. """ pkey0, pkey1, nettingchannel = tester_nettingcontracts[0] address0 = privatekey_to_address(pkey0) address1 = privatekey_to_address(pkey1) initial_balance0 = tester_token.balanceOf(address0, sender=pkey0) initial_balance1 = tester_token.balanceOf(address1, sender=pkey0) lock_amount = 31 lock_expiration = tester_chain.block.number + settle_timeout secret = b'settlementsettlementsettlementse' hashlock = sha3(secret) lock0 = Lock( amount=lock_amount, expiration=lock_expiration, hashlock=hashlock, ) lock0_bytes = bytes(lock0.as_bytes) lock0_hash = sha3(lock0_bytes) opened_block = nettingchannel.opened(sender=pkey0) nonce = 1 + (opened_block * (2 ** 32)) mediated0 = MediatedTransfer( identifier=1, nonce=nonce, token=tester_token.address, channel=normalize_address(nettingchannel.address), transferred_amount=0, recipient=address1, locksroot=lock0_hash, lock=lock0, target=address1, initiator=address0, fee=0, ) sign_key0 = PrivateKey(pkey0) mediated0.sign(sign_key0, address0) mediated0_hash = sha3(mediated0.packed().data[:-65]) nettingchannel.close( mediated0.nonce, mediated0.transferred_amount, mediated0.locksroot, mediated0_hash, mediated0.signature, sender=pkey1, ) block_until_settlement_end = lock_expiration - tester_chain.block.number tester_chain.mine(number_of_blocks=block_until_settlement_end) assert lock_expiration == tester_chain.block.number nettingchannel.withdraw( lock0_bytes, b'', # the lock itself it the root, the proof is empty secret, sender=pkey1, ) tester_chain.mine(number_of_blocks=1) nettingchannel.settle(sender=pkey0) balance0 = initial_balance0 + deposit - lock0.amount balance1 = initial_balance1 + deposit + lock0.amount assert tester_token.balanceOf(address0, sender=pkey0) == balance0 assert tester_token.balanceOf(address1, sender=pkey0) == balance1 assert tester_token.balanceOf(nettingchannel.address, sender=pkey0) == 0