def test_namecoin(): k, v, k2, v2 = accounts() blk = b.genesis({v: u.denoms.ether * 1}) code1 = serpent.compile(namecoin_code) tx1 = t.contract(0, gasprice, startgas, 0, code1).sign(k) s, addr = pb.apply_transaction(blk, tx1) snapshot = blk.snapshot() # tx2 tx2 = t.Transaction(1, gasprice, startgas, addr, 0, serpent.encode_datalist(['george', 45])) tx2.sign(k) s, o = pb.apply_transaction(blk, tx2) assert serpent.decode_datalist(o) == [1] # tx3 tx3 = t.Transaction(2, gasprice, startgas, addr, 0, serpent.encode_datalist(['george', 20])).sign(k) s, o = pb.apply_transaction(blk, tx3) assert serpent.decode_datalist(o) == [0] # tx4 tx4 = t.Transaction(3, gasprice, startgas, addr, 0, serpent.encode_datalist(['harry', 60])).sign(k) s, o = pb.apply_transaction(blk, tx4) assert serpent.decode_datalist(o) == [1] blk.revert(snapshot) assert blk.to_dict() assert blk.to_dict()['state'][addr]['code']
def test_data_feeds(): k, v, k2, v2 = accounts() scode3 = ''' if !contract.storage[1000]: contract.storage[1000] = 1 contract.storage[1001] = msg.sender return(0) elif msg.sender == contract.storage[1001] and msg.datasize == 2: contract.storage[msg.data[0]] = msg.data[1] return(1) else: return(contract.storage[msg.data[0]]) ''' code3 = serpent.compile(scode3) # print("AST", serpent.rewrite(serpent.parse(scode3))) # print("Assembly", serpent.compile_to_assembly(scode3)) blk = b.genesis({v: 10**18, v2: 10**18}) tx10 = t.contract(0, gasprice, startgas, 0, code3).sign(k) s, addr = pb.apply_tx(blk, tx10) tx11 = t.Transaction(1, gasprice, startgas, addr, 0, '').sign(k) s, o = pb.apply_tx(blk, tx11) tx12 = t.Transaction(2, gasprice, startgas, addr, 0, serpent.encode_datalist([500])).sign(k) s, o = pb.apply_tx(blk, tx12) assert serpent.decode_datalist(o) == [0] tx13 = t.Transaction(3, gasprice, startgas, addr, 0, serpent.encode_datalist([500, 726])).sign(k) s, o = pb.apply_tx(blk, tx13) assert serpent.decode_datalist(o) == [1] tx14 = t.Transaction(4, gasprice, startgas, addr, 0, serpent.encode_datalist([500])).sign(k) s, o = pb.apply_tx(blk, tx14) assert serpent.decode_datalist(o) == [726] return blk, addr
def send_money(to, amount, genesis, root_contract, usr): key, addr = usr nonce = get_nonce(genesis, addr) tx_money = transactions.Transaction(nonce, 0, 10**12, 10000, root_contract, serpent.encode_datalist([to, amount ])).sign(key) ans = processblock.apply_tx(genesis, tx_money)
def step_impl(context): word = 'a5b2cc1f54' msg = context.msg = '\x00' * (32 - len(word)) + word tx = transactions.Transaction(1, 100, 10**40, context.contract, 0, msg).sign(context.key) success, context.ans = processblock.apply_transaction(context.gen, tx) assert (success)
def tag_content(content_hash, tag, genesis, root_contract, usr): key, addr = usr nonce = get_nonce(genesis, addr) tx_tag = transactions.Transaction( nonce, 0, 10**12, 10000, root_contract, serpent.encode_datalist([2, content_hash, tag])).sign(key) ans = processblock.apply_tx(genesis, tx_tag)
def test_gas_price_calculation(): code = [ 'CALLER', 'PUSH1', 69, 'SSTORE', 'PUSH1', 42, 'DUP', 'PUSH1', 16, 'PUSH1', 0, 'CODECOPY', 'PUSH1', 0, 'RETURN', 'STOP', 'PUSH1', 69, 'SLOAD', 'CALLER', 'EQ', 'NOT', 'PUSH1', 42, 'JUMPI', 'CALLDATASIZE', 'PUSH1', 0, 'MLOAD', 'LT', 'NOT', 'PUSH1', 42, 'JUMPI', 'PUSH1', 32, 'PUSH1', 0, 'MLOAD', 'ADD', 'CALLDATALOAD', 'PUSH1', 0, 'MLOAD', 'CALLDATALOAD', 'SSTORE', 'PUSH1', 64, 'PUSH1', 0, 'MLOAD', 'ADD', 'PUSH1', 0, 'MSTORE', 'PUSH1', 9, 'JUMP' ] tx_dict = { 'nonce': 0L, 'startgas': 10000L, 'value': 0L, 'to': '0000000000000000000000000000000000000000', 's': 9504411864285061276187941232604806802531640604671611347567260576513458657555L, 'r': 23362574597211079051662254624411036839077618676481166419446762923566339937125L, 'v': 28L, 'data': '3`EW`*Q`\x10`\x009`\x00\xf2\x00`EV3\x0e\x0f`*Y6`\x00S\n\x0f`*Y` `\x00S\x015`\x00S5W`@`\x00S\x01`\x00T`\tX', 'gasprice': 10000000000000L } assert serpent.compiler.serialize(code) == tx_dict['data'] set_db() block = genesis = blocks.genesis() tx = transactions.Transaction(**tx_dict) assert block.gas_used == 0 success, output = processblock.apply_transaction(block, tx) GAS_USED_CPP = 1001 # as seen for tx0 in block1 in protocol 17 cpp chain assert block.gas_used == GAS_USED_CPP
def __init__(self, to, donate_to, value=0): self.to = to self.value = value self.donate_to = donate_to self.data = serpent.encode_datalist([self._data_code(), donate_to]) self.tx = lambda user: transactions.Transaction( NonceSingleton.inc(user), self.DEFAULT_GASPRICE, self. DEFAULT_STARTGAS, to, value, self.data)
def vote_tag(content_hash, tag, vote, genesis, root_contract, usr): key, addr = usr nonce = get_nonce(genesis, addr) #vote on a tag. tx_vote = transactions.Transaction( nonce, 0, 10**12, 10000, root_contract, serpent.encode_datalist([3, content_hash, tag, vote])).sign(key) ans = processblock.apply_tx(genesis, tx_vote)
def register_name(name, genesis, root_contract, usr): key, addr = usr nonce = get_nonce(genesis, addr) # register eth-address to a name. recover name from blockchain. names are not unique. but names + first 4 digits of address probably are.... tx_register_name = transactions.Transaction( nonce, 0, 10**12, 10000, root_contract, serpent.encode_datalist([5, name])).sign(key) ans = processblock.apply_tx(genesis, tx_register_name)
def test_currency(): k, v, k2, v2 = accounts() scode2 = ''' if !contract.storage[1000]: contract.storage[1000] = 1 contract.storage[0x%s] = 1000 return(1) elif msg.datasize == 1: addr = msg.data[0] return(contract.storage[addr]) else: from = msg.sender fromvalue = contract.storage[from] to = msg.data[0] value = msg.data[1] if fromvalue >= value: contract.storage[from] = fromvalue - value contract.storage[to] = contract.storage[to] + value return(1) else: return(0) ''' % v code2 = serpent.compile(scode2) blk = b.genesis({v: 10 ** 18}) tx4 = t.contract(0, gasprice, startgas, 0, code2).sign(k) s, addr = pb.apply_transaction(blk, tx4) tx5 = t.Transaction(1, gasprice, startgas, addr, 0, '').sign(k) s, o = pb.apply_transaction(blk, tx5) assert serpent.decode_datalist(o) == [1] tx6 = t.Transaction(2, gasprice, startgas, addr, 0, serpent.encode_datalist([v2, 200])).sign(k) s, o = pb.apply_transaction(blk, tx6) assert serpent.decode_datalist(o) == [1] tx7 = t.Transaction(3, gasprice, startgas, addr, 0, serpent.encode_datalist([v2, 900])).sign(k) s, o = pb.apply_transaction(blk, tx7) assert serpent.decode_datalist(o) == [0] tx8 = t.Transaction(4, gasprice, startgas, addr, 0, serpent.encode_datalist([v])).sign(k) s, o = pb.apply_transaction(blk, tx8) assert serpent.decode_datalist(o) == [800] tx9 = t.Transaction(5, gasprice, startgas, addr, 0, serpent.encode_datalist([v2])).sign(k) s, o = pb.apply_transaction(blk, tx9) assert serpent.decode_datalist(o) == [200]
def step_impl(context): word = 342156 word = hex(word)[2:] if len(word) % 2 != 0: word = '0' + word msg = context.msg = '\x00' * (32 - len(word) / 2) + word.decode('hex') tx = transactions.Transaction(1, 100, 10**40, context.contract, 0, msg).sign(context.key) success, context.ans = processblock.apply_transaction(context.gen, tx) assert (success)
def get_transaction(gasprice=0, nonce=0): k, v, k2, v2 = accounts() tx = transactions.Transaction(nonce, gasprice, startgas=10000, to=v2, value=utils.denoms.finney * 10, data='').sign(k) return tx
def init_system(genesis, key): code = serpent.compile(open('serp/root.se').read()) tx_make_root = transactions.Transaction.contract(0, 0, 10**12, 10000, code).sign(key) root_contract = processblock.apply_tx(genesis, tx_make_root) root_hash = root_contract.encode('hex') f = lambda x: write_owner(root_hash, x) map(f, ['serp/data.se', 'serp/tag.se', 'serp/users.se', 'serp/currency.se']) code = serpent.compile(open('serp/data.se').read()) tx_make_data = transactions.Transaction.contract(1, 0, 10**12, 10000, code).sign(key) code = serpent.compile(open('serp/tag.se').read()) tx_make_tag = transactions.Transaction.contract(2, 0, 10**12, 10000, code).sign(key) code = serpent.compile(open('serp/users.se').read()) tx_make_users = transactions.Transaction.contract(3, 0, 10**12, 10000, code).sign(key) code = serpent.compile(open('serp/currency.se').read()) tx_make_currency = transactions.Transaction.contract( 4, 0, 10**12, 10000, code).sign(key) data_contract = processblock.apply_tx(genesis, tx_make_data) tag_contract = processblock.apply_tx(genesis, tx_make_tag) users_contract = processblock.apply_tx(genesis, tx_make_users) currency_contract = processblock.apply_tx(genesis, tx_make_currency) d_contract = data_contract.encode('hex') t_contract = tag_contract.encode('hex') u_contract = users_contract.encode('hex') c_contract = currency_contract.encode('hex') #init root tx_init_root = transactions.Transaction( 5, 0, 10**12, 10000, root_contract, serpent.encode_datalist( [d_contract, t_contract, u_contract, c_contract])).sign(key) ans = processblock.apply_tx(genesis, tx_init_root) adresses = { root_hash: 'root', d_contract: 'data', t_contract: 'tags', u_contract: 'users', utils.privtoaddr(key): 'me', c_contract: 'currency' } return adresses
def tx(self, frm, to, value, data, gas=STARTGAS): _tx = transactions.Transaction(nonce=self.nonce[frm], gasprice=self.GASPRICE, startgas=gas, to=to, value=value, data=encode_datalist(data)).sign( frm.key) result, ans = processblock.apply_transaction(self.genesis, _tx) assert result self.nonce[frm] += 1 return decode_datalist(ans)
def get_all_content(genesis, root_contract, usr): key, addr = usr nonce = get_nonce(genesis, addr) tx_v = transactions.Transaction(nonce, 0, 10**12, 10000, root_contract, serpent.encode_datalist([7, 'kjsdhg' ])).sign(key) ans = processblock.apply_tx(genesis, tx_v) decoded = serpent.decode_datalist(ans) hexd = map(hex, decoded) f = lambda x: x[2:-1] hexd = map(f, hexd) f = lambda x: x.decode('hex') hexd = map(f, hexd) return hexd
def test_namecoin(): k, v, k2, v2 = accounts() blk = b.genesis({v: u.denoms.ether * 1}) scode1 = ''' if !contract.storage[msg.data[0]]: contract.storage[msg.data[0]] = msg.data[1] return(1) else: return(0) ''' code1 = serpent.compile(scode1) tx1 = t.contract(0, gasprice, startgas, 0, code1).sign(k) s, addr = pb.apply_tx(blk, tx1) snapshot = blk.snapshot() tx2 = t.Transaction(1, gasprice, startgas, addr, 0, serpent.encode_datalist(['george', 45])) tx2.sign(k) s, o = pb.apply_tx(blk, tx2) assert serpent.decode_datalist(o) == [1] tx3 = t.Transaction(2, gasprice, startgas, addr, 0, serpent.encode_datalist(['george', 20])).sign(k) s, o = pb.apply_tx(blk, tx3) assert serpent.decode_datalist(o) == [0] tx4 = t.Transaction(3, gasprice, startgas, addr, 0, serpent.encode_datalist(['harry', 60])).sign(k) s, o = pb.apply_tx(blk, tx4) assert serpent.decode_datalist(o) == [1]
def push_content(content, title, genesis, root_contract, usr): key, addr = usr nonce = get_nonce(genesis, addr) content_hash = utils.sha3(content) # push a transaction with a title. recover title from blockchain tx_push = transactions.Transaction( nonce, 0, 10**12, 10000, root_contract, serpent.encode_datalist([1, content_hash, title])).sign(key) ans = processblock.apply_tx(genesis, tx_push) f = open('data/%s' % content_hash.encode('hex'), 'w') f.write(content) f.close() return content_hash
def do_test_vm(name): logger.debug('running test:%r', name) params = vm_tests_fixtures()[name] pre = params['pre'] exek = params['exec'] callcreates = params['callcreates'] env = params['env'] post = params['post'] check_testdata(env.keys(), ['currentGasLimit', 'currentTimestamp', 'previousHash', 'currentCoinbase', 'currentDifficulty', 'currentNumber']) # setup env blk = blocks.Block( prevhash=env['previousHash'].decode('hex'), number=int(env['currentNumber']), coinbase=env['currentCoinbase'], difficulty=int(env['currentDifficulty']), gas_limit=int(env['currentGasLimit']), timestamp=int(env['currentTimestamp'])) # code FIXME WHAT TO DO WITH THIS CODE??? # if isinstance(env['code'], str): # continue # else: # addr = 0 # FIXME # blk.set_code(addr, ''.join(map(chr, env['code']))) # setup state for address, h in pre.items(): check_testdata(h.keys(), ['code', 'nonce', 'balance', 'storage']) blk.set_nonce(address, int(h['nonce'])) blk.set_balance(address, int(h['balance'])) blk.set_code(address, h['code'][2:].decode('hex')) for k, v in h['storage']: blk.set_storage_data(address, u.big_endian_to_int(k.decode('hex')), u.big_endian_to_int(v.decode('hex'))) logger.debug('PRE Balance: %r: %r', address, h['balance']) # execute transactions pb.enable_debug() sender = exek['caller'] # a party that originates a call recvaddr = exek['address'] tx = transactions.Transaction( nonce=blk._get_acct_item(exek['caller'], 'nonce'), gasprice=int(exek['gasPrice']), startgas=int(exek['gas']), to=recvaddr, value=int(exek['value']), data=exek['data'][2:].decode('hex')) tx.sender = sender logger.debug('TX %r > %r v:%r gas:%s @price:%s', sender, recvaddr, tx.value, tx.startgas, tx.gasprice) # capture apply_message calls apply_message_calls = [] orig_apply_msg = pb.apply_msg def apply_msg_wrapper(_block, _tx, msg, code): pb.enable_debug() apply_message_calls.append(dict(gasLimit=msg.gas, value=msg.value, destination=msg.to, data=msg.data.encode('hex'))) result, gas_rem, data = orig_apply_msg(_block, _tx, msg, code) pb.disable_debug() return result, gas_rem, data pb.apply_msg = apply_msg_wrapper msg = pb.Message(tx.sender, tx.to, tx.value, tx.startgas, tx.data) blk.delta_balance(exek['caller'], tx.value) blk.delta_balance(exek['address'], -tx.value) success, gas_remained, output = \ pb.apply_msg(blk, tx, msg, exek['code'][2:].decode('hex')) pb.apply_msg = orig_apply_msg apply_message_calls.pop(0) blk.commit_state() assert success assert len(callcreates) == len(apply_message_calls) # check against callcreates for i, callcreate in enumerate(callcreates): amc = apply_message_calls[i] assert callcreate['data'] == '0x'+amc['data'].encode('hex') assert callcreate['gasLimit'] == str(amc['gasLimit']) assert callcreate['value'] == str(amc['value']) assert callcreate['destination'] == amc['destination'] assert '0x'+''.join(map(chr, output)).encode('hex') == params['out'] assert str(gas_remained) == params['gas'] # check state for address, data in post.items(): state = blk.account_to_dict(address) state.pop('storage_root', None) # attribute not present in vmtest fixtures assert data == state
def run_test_vm(params): pre = params['pre'] exek = params['exec'] callcreates = params.get('callcreates', []) env = params['env'] post = params.get('post', {}) check_testdata(env.keys(), [ 'currentGasLimit', 'currentTimestamp', 'previousHash', 'currentCoinbase', 'currentDifficulty', 'currentNumber' ]) # setup env db = new_db() blk = blocks.Block(db, prevhash=env['previousHash'].decode('hex'), number=int(env['currentNumber']), coinbase=env['currentCoinbase'], difficulty=int(env['currentDifficulty']), gas_limit=int(env['currentGasLimit']), timestamp=int(env['currentTimestamp'])) # code FIXME WHAT TO DO WITH THIS CODE??? # if isinstance(env['code'], str): # continue # else: # addr = 0 # FIXME # blk.set_code(addr, ''.join(map(chr, env['code']))) # setup state for address, h in pre.items(): check_testdata(h.keys(), ['code', 'nonce', 'balance', 'storage']) blk.set_nonce(address, int(h['nonce'])) blk.set_balance(address, int(h['balance'])) blk.set_code(address, h['code'][2:].decode('hex')) for k, v in h['storage']: blk.set_storage_data(address, u.big_endian_to_int(k.decode('hex')), u.big_endian_to_int(v.decode('hex'))) # execute transactions sender = exek['caller'] # a party that originates a call recvaddr = exek['address'] tx = transactions.Transaction(nonce=blk._get_acct_item( exek['caller'], 'nonce'), gasprice=int(exek['gasPrice']), startgas=int(exek['gas']), to=recvaddr, value=int(exek['value']), data=exek['data'][2:].decode('hex')) tx.sender = sender # capture apply_message calls apply_message_calls = [] orig_apply_msg = pb.apply_msg def apply_msg_wrapper(_ext, msg, code, toplevel=False): hexdata = msg.data.extract_all().encode('hex') apply_message_calls.append( dict(gasLimit=msg.gas, value=msg.value, destination=msg.to, data=hexdata)) if not toplevel: pb.apply_msg = orig_apply_msg result, gas_rem, data = orig_apply_msg(_ext, msg, code) if not toplevel: pb.apply_msg = apply_msg_wrapper return result, gas_rem, data pb.apply_msg = apply_msg_wrapper ext = pb.VMExt(blk, tx) msg = vm.Message(tx.sender, tx.to, tx.value, tx.startgas, vm.CallData([ord(x) for x in tx.data])) success, gas_remained, output = \ vm.vm_execute(ext, msg, exek['code'][2:].decode('hex')) pb.apply_msg = orig_apply_msg blk.commit_state() """ generally expected that the test implementer will read env, exec and pre then check their results against gas, logs, out, post and callcreates. If an exception is expected, then latter sections are absent in the test. Since the reverting of the state is not part of the VM tests. """ if not success: return for k in ['gas', 'logs', 'out', 'post', 'callcreates']: assert k in params assert len(callcreates) == len(apply_message_calls) # check against callcreates for i, callcreate in enumerate(callcreates): amc = apply_message_calls[i] assert callcreate['data'] == '0x' + amc['data'] assert callcreate['gasLimit'] == str(amc['gasLimit']) assert callcreate['value'] == str(amc['value']) assert callcreate['destination'] == amc['destination'] if 'out' in params: assert '0x' + ''.join(map(chr, output)).encode('hex') == params['out'] if 'gas' in params: assert str(gas_remained) == params['gas'] if 'logs' in params: """ The logs sections is a mapping between the blooms and their corresponding logentries. Each logentry has the format: address: The address of the logentry. data: The data of the logentry. topics: The topics of the logentry, given as an array of values. """ test_logs = params['logs'] vm_logs = [] for log in tx.logs: vm_logs.append({ "bloom": bloom.b64(bloom.bloom_from_list( log.bloomables())).encode('hex'), "address": log.address, "data": '0x' + log.data.encode('hex'), "topics": [ u.zpad(u.int_to_big_endian(t), 32).encode('hex') for t in log.topics ] }) assert len(vm_logs) == len(test_logs) assert vm_logs == test_logs # check state for address, data in post.items(): state = blk.account_to_dict(address, for_vmtest=True) state.pop('storage_root', None) # attribute not present in vmtest fixtures assert data == state db.delete_db()
def do_test_vm(name): logger.debug('running test:%r', name) for testname in vm_tests_fixtures(name).keys(): logger.debug('running test:%r', testname) params = vm_tests_fixtures(name)[testname] pre = params['pre'] exek = params['exec'] callcreates = params['callcreates'] env = params['env'] post = params['post'] check_testdata(env.keys(), [ 'currentGasLimit', 'currentTimestamp', 'previousHash', 'currentCoinbase', 'currentDifficulty', 'currentNumber' ]) # setup env blk = blocks.Block(prevhash=env['previousHash'].decode('hex'), number=int(env['currentNumber']), coinbase=env['currentCoinbase'], difficulty=int(env['currentDifficulty']), gas_limit=int(env['currentGasLimit']), timestamp=int(env['currentTimestamp'])) # code FIXME WHAT TO DO WITH THIS CODE??? # if isinstance(env['code'], str): # continue # else: # addr = 0 # FIXME # blk.set_code(addr, ''.join(map(chr, env['code']))) # setup state for address, h in pre.items(): check_testdata(h.keys(), ['code', 'nonce', 'balance', 'storage']) blk.set_nonce(address, int(h['nonce'])) blk.set_balance(address, int(h['balance'])) blk.set_code(address, h['code'][2:].decode('hex')) for k, v in h['storage']: blk.set_storage_data(address, u.big_endian_to_int(k.decode('hex')), u.big_endian_to_int(v.decode('hex'))) pblogger.log('PRE Balance', address=address, balance=h['balance']) # execute transactions sender = exek['caller'] # a party that originates a call recvaddr = exek['address'] tx = transactions.Transaction(nonce=blk._get_acct_item( exek['caller'], 'nonce'), gasprice=int(exek['gasPrice']), startgas=int(exek['gas']), to=recvaddr, value=int(exek['value']), data=exek['data'][2:].decode('hex')) tx.sender = sender pblogger.log('TX', tx=tx.hex_hash(), sender=sender, to=recvaddr, value=tx.value, startgas=tx.startgas, gasprice=tx.gasprice) # capture apply_message calls apply_message_calls = [] orig_apply_msg = pb.apply_msg def apply_msg_wrapper(_block, _tx, msg, code): apply_message_calls.append( dict(gasLimit=msg.gas, value=msg.value, destination=msg.to, data=msg.data.encode('hex'))) result, gas_rem, data = orig_apply_msg(_block, _tx, msg, code) return result, gas_rem, data pb.apply_msg = apply_msg_wrapper msg = pb.Message(tx.sender, tx.to, tx.value, tx.startgas, tx.data) blk.delta_balance(exek['caller'], tx.value) blk.delta_balance(exek['address'], -tx.value) try: success, gas_remained, output = \ pb.apply_msg(blk, tx, msg, exek['code'][2:].decode('hex')) except MemoryError: print "A memory error exception has been thrown and catched!\n" pb.apply_msg = orig_apply_msg apply_message_calls.pop(0) blk.commit_state() assert success assert len(callcreates) == len(apply_message_calls) # check against callcreates for i, callcreate in enumerate(callcreates): amc = apply_message_calls[i] assert callcreate['data'] == '0x' + amc['data'].encode('hex') assert callcreate['gasLimit'] == str(amc['gasLimit']) assert callcreate['value'] == str(amc['value']) assert callcreate['destination'] == amc['destination'] assert '0x' + ''.join(map(chr, output)).encode('hex') == params['out'] if gas_remained < 0: gas_remained = 0 assert str(gas_remained) == params['gas'] # check state for address, data in post.items(): state = blk.account_to_dict(address) state.pop('storage_root', None) # attribute not present in vmtest fixtures # check hex values in same format def newFormat(x): if x == '0x': return '0x00' elif x[:2] == '0x': return "0x%0.2X" % int(x, 0) else: return x data['storage'] = { newFormat(k): newFormat(v[0]) for k, v in data['storage'].items() if int(newFormat(v[0]), 0) != 0 } state['storage'] = { newFormat(k): newFormat(v) for k, v in state['storage'].items() } assert data == state
nargs = pad32(1) d0 = pad32('hi') print nargs, d0 msg_hash = utils.sha3(nargs + d0) v, r, s = bitcoin.ecdsa_raw_sign(msg_hash, key) pubkey = bitcoin.privkey_to_pubkey(key) verified = bitcoin.ecdsa_raw_verify(msg_hash, (v, r, s), pubkey) gen = blocks.genesis({addr: 10**18}) print serpent.compile_to_assembly(open("DAOist frame.se").read()) DAOcode = serpent.compile(open("DAOist frame.se").read()) DAOcontract = transactions.contract(0, 1, 10**12, 100, DAOcode) DAOcontract.sign(key) success, contract_address = processblock.apply_tx(gen, DAOcontract) DCP = transactions.Transaction( 1, 10**12, 10000, contract_address, 0, serpent.encode_datalist([1, 1, v, r, s, 1, 'hi'])) DCP.sign(key) success, result = processblock.apply_tx(gen, DCP) print "success: ", success print serpent.decode_datalist(result)
code = serpent.assemble(assembly) print code msg_hash = utils.sha3('heres a message') v, r, s = bitcoin.ecdsa_raw_sign(msg_hash, key) pub = bitcoin.privkey_to_pubkey(key) verified = bitcoin.ecdsa_raw_verify(msg_hash, (v, r, s), pub) print verified tx_make_root = transactions.contract(0, 10, 10**30, 10**30, code).sign(key) success, root_contract = processblock.apply_tx(gen, tx_make_root) #tx_init_root = transactions.Transaction(1, 100, 10**40, root_contract, 0, serpent.encode_datalist([msg_hash, v, r, s])).sign(key) #tx_init_root = transactions.Transaction(1, 100, 10**40, root_contract, 0, serpent.encode_datalist(['hi', 'bye'])).sign(key) tx_init_root = transactions.Transaction( 1, 100, 10**40, root_contract, 0, serpent.encode_datalist([2, '139dcd5cc79e260272e05147c349ab5f2db3f102', 1])).sign(key) #tx_init_root = transactions.Transaction(1, 100, 10**40, root_contract, 0, serpent.encode_datalist([2, 1])).sign(key) print assembly success, ans = processblock.apply_tx(gen, tx_init_root) print ans data = serpent.decode_datalist(ans) print data print hex(data[0]) quit() print ans.encode('hex') data = serpent.decode_datalist(ans) print 'raw decoded data:', data print 'data as hex:' print map(hex, data) #print ('%02x'%data).decode('hex')
def do_test_vm(name): tempdir = tempfile.mktemp() logger.debug('running test:%r', name) params = vm_tests_fixtures()[name] # HOTFIFX # params['pre']['0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6']['balance'] *= 100 pre = params['pre'] execs = params['exec'] callcreates = params['callcreates'] env = params['env'] post = params['post'] check_testdata(env.keys(), [ 'code', 'currentGasLimit', 'currentTimestamp', 'previousHash', 'currentCoinbase', 'currentDifficulty', 'currentNumber' ]) # setup env blk = blocks.Block(prevhash=env['previousHash'].decode('hex'), number=int(env['currentNumber']), coinbase=env['currentCoinbase'], difficulty=int(env['currentDifficulty']), gas_limit=int(env['currentGasLimit']), timestamp=env['currentTimestamp']) # code FIXME WHAT TO DO WITH THIS CODE??? # if isinstance(env['code'], str): # continue # else: # addr = 0 # FIXME # blk.set_code(addr, ''.join(map(chr, env['code']))) # setup state for address, h in pre.items(): check_testdata(h.keys(), ['code', 'nonce', 'balance', 'storage']) blk.set_balance(address, h['balance']) logger.debug('PRE Balance: %r: %r', address, h['balance']) blk._set_acct_item(address, 'nonce', h['nonce']) blk.set_code(address, ''.join(map(chr, h['code']))) assert h['storage'] == { } # FOR NOW test contracts don't seem to persist anything # execute transactions for i, exek in enumerate(execs): sender = exek['address'] # a party that originates a call recvaddr = exek['caller'] tx = transactions.Transaction(nonce=blk._get_acct_item( exek['caller'], 'nonce'), gasprice=int(exek['gasPrice']), startgas=int(exek['gas']), to=recvaddr, value=int(exek['value']), data=exek['data']) tx.sender = sender logger.debug('TX %r > %r v:%r gas:%s @price:%s', sender, recvaddr, tx.value, tx.startgas, tx.gasprice) # capture apply_message calls apply_message_calls = [] orig_apply_msg = processblock.apply_msg def apply_msg_wrapper(_block, _tx, msg): result, gas_remained, data = orig_apply_msg(_block, _tx, msg) apply_message_calls.append( dict(msg=msg, result=result, gas_remained=gas_remained, data=data)) return result, gas_remained, data processblock.apply_msg = apply_msg_wrapper success, output = processblock.apply_transaction(blk, tx) processblock.apply_msg = orig_apply_msg assert success assert len(callcreates) == len(apply_message_calls) # check against callcreates for i, callcreate in enumerate(callcreates): amc = apply_message_calls[i] assert callcreate['data'] == amc['data'] assert callcreate['gasLimit'] == amc['gas_remained'] assert callcreate['value'] == amc['msg'].value # data and out not set in tests yet assert output == params['out'] assert not params['out'] assert not callcreates['data'] # check state for address, h in post.items(): check_testdata(h.keys(), ['code', 'nonce', 'balance', 'storage']) logger.debug('POST: %r %r', address, h['balance']) blk.get_balance(address) == h['balance'] blk._get_acct_item(address, 'nonce') == h['nonce'] map(ord, blk.get_code(recvaddr)) == h['code'] assert storage == { } # FOR NOW test contracts don't seem to persist anything
def generate_op_tests(): outs = {} for opcode, (name, inargs, outargs, _) in opcodes.opcodes.items(): _subid = 0 for push_depths in push_params: for jump_num, code_size in codesize_params: if name in [ 'CALL', 'CREATE', 'CALLCODE', 'LOG', 'POP', 'RETURN', 'STOP', 'INVALID', 'JUMP', 'JUMPI', 'CALLDATALOAD', 'CALLDATACOPY', 'CODECOPY', 'EXTCODECOPY', 'SHA3', 'MLOAD', 'MSTORE', 'MSTORE8', 'SUICIDE' ]: continue if name[:3] in ['DUP', 'SWA', 'LOG']: continue if name == 'SSTORE': jump_num /= 10 c = '\x5b' if name[:4] == 'PUSH': if push_depths != push_params[0]: continue for i in range(code_size): v = int(name[4:]) w = random.randrange(256**v) c += chr(0x5f + v) + utils.zpad(utils.encode_int(w), v) else: for i in range(code_size): for _ in range(inargs): v = push_depths[i * len(push_depths) // code_size] w = random.randrange(256**v) c += chr(0x5f + v) + utils.zpad( utils.encode_int(w), v) c += chr(opcode) for _ in range(outargs): c += chr(0x50) # PUSH1 0 MLOAD . DUP1 . PUSH1 1 ADD PUSH1 0 MSTORE . PUSH2 <jumps> GT PUSH1 0 JUMPI c += '\x60\x00\x51' + '\x80' + '\x60\x01\x01\x60\x00\x52' + \ '\x61'+chr(jump_num // 256) + chr(jump_num % 256) + '\x11\x60\x00\x57' o = { "callcreates": [], "env": { "currentCoinbase": "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", "currentDifficulty": "256", "currentGasLimit": "1000000000", "currentNumber": "257", "currentTimestamp": "1", "previousHash": "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6" }, "exec": { "address": "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", "caller": "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", "code": "0x" + c.encode('hex'), "data": "0x", "gas": "1000000", "gasPrice": "100000000000000", "origin": "cd1722f3947def4cf144679da39c4c32bdc35681", "value": "1000000000000000000" }, "pre": { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6": { "balance": "1000000000000000000", "code": "0x", "nonce": "0", "storage": {} } }, "gas": "1000000", "logs": [], "out": "0x" } env = o['env'] pre = o['pre'] exek = o['exec'] blk = blocks.Block(db, prevhash=env['previousHash'].decode('hex'), number=int(env['currentNumber']), coinbase=env['currentCoinbase'], difficulty=int(env['currentDifficulty']), gas_limit=int(env['currentGasLimit']), timestamp=int(env['currentTimestamp'])) # setup state for address, h in pre.items(): blk.set_nonce(address, int(h['nonce'])) blk.set_balance(address, int(h['balance'])) blk.set_code(address, h['code'][2:].decode('hex')) for k, v in h['storage'].iteritems(): blk.set_storage_data( address, u.big_endian_to_int(k[2:].decode('hex')), u.big_endian_to_int(v[2:].decode('hex'))) # execute transactions sender = exek['caller'] # a party that originates a call recvaddr = exek['address'] tx = transactions.Transaction( nonce=blk._get_acct_item(exek['caller'], 'nonce'), gasprice=int(exek['gasPrice']), startgas=int(exek['gas']), to=recvaddr, value=int(exek['value']), data=exek['data'][2:].decode('hex')) tx.sender = sender ext = pb.VMExt(blk, tx) def blkhash(n): if n >= ext.block_number or n < ext.block_number - 256: return '' else: return u.sha3(str(n)) ext.block_hash = blkhash msg = vm.Message(tx.sender, tx.to, tx.value, tx.startgas, vm.CallData([ord(x) for x in tx.data])) success, gas_remained, output = \ vm.vm_execute(ext, msg, exek['code'][2:].decode('hex')) o['post'] = blk.to_dict(True)['state'] outs[name + str(_subid)] = o _subid += 1 return outs
def do_test_vm(filename, testname=None, limit=99999999): if testname is None: for testname in vm_tests_fixtures()[filename].keys()[:limit]: do_test_vm(filename, testname) return if testname in faulty: logger.debug('skipping test:%r in %r' % (testname, filename)) return logger.debug('running test:%r in %r' % (testname, filename)) params = vm_tests_fixtures()[filename][testname] pre = params['pre'] exek = params['transaction'] env = params['env'] post = params['post'] check_testdata(env.keys(), [ 'currentGasLimit', 'currentTimestamp', 'previousHash', 'currentCoinbase', 'currentDifficulty', 'currentNumber' ]) # setup env blk = blocks.Block(new_db(), prevhash=env['previousHash'].decode('hex'), number=int(env['currentNumber']), coinbase=env['currentCoinbase'], difficulty=int(env['currentDifficulty']), gas_limit=int(env['currentGasLimit']), timestamp=int(env['currentTimestamp'])) # code FIXME WHAT TO DO WITH THIS CODE??? # if isinstance(env['code'], str): # continue # else: # addr = 0 # FIXME # blk.set_code(addr, ''.join(map(chr, env['code']))) # setup state for address, h in pre.items(): check_testdata(h.keys(), ['code', 'nonce', 'balance', 'storage']) blk.set_nonce(address, int(h['nonce'])) blk.set_balance(address, int(h['balance'])) blk.set_code(address, h['code'][2:].decode('hex')) for k, v in h['storage'].iteritems(): blk.set_storage_data(address, u.big_endian_to_int(k[2:].decode('hex')), u.big_endian_to_int(v[2:].decode('hex'))) # execute transactions tx = transactions.Transaction(nonce=int(exek['nonce'] or "0"), gasprice=int(exek['gasPrice'] or "0"), startgas=int(exek['gasLimit'] or "0"), to=exek['to'], value=int(exek['value'] or "0"), data=exek['data'][2:].decode('hex')).sign( exek['secretKey']) orig_apply_msg = pb.apply_msg def apply_msg_wrapper(ext, msg, code): def blkhash(n): if n >= blk.number or n < blk.number - 256: return '' else: return u.sha3(str(n)) ext.block_hash = blkhash return orig_apply_msg(ext, msg, code) pb.apply_msg = apply_msg_wrapper try: success, output = pb.apply_transaction(blk, tx) blk.commit_state() except pb.InvalidTransaction: output = '' logger.debug('Transaction not valid') pass if tx.to == '': output = blk.get_code(output) pb.apply_msg = orig_apply_msg assert '0x' + output.encode('hex') == params['out'] # check state for address, data in post.items(): state = blk.account_to_dict(address, for_vmtest=True) state.pop('storage_root', None) assert state == data
def profile_vm_test(params): pre = params['pre'] exek = params['exec'] env = params['env'] # setup env blk = blocks.Block(db, prevhash=env['previousHash'].decode('hex'), number=int(env['currentNumber']), coinbase=env['currentCoinbase'], difficulty=int(env['currentDifficulty']), gas_limit=int(env['currentGasLimit']), timestamp=int(env['currentTimestamp'])) # setup state for address, h in pre.items(): blk.set_nonce(address, int(h['nonce'])) blk.set_balance(address, int(h['balance'])) blk.set_code(address, h['code'][2:].decode('hex')) for k, v in h['storage'].iteritems(): blk.set_storage_data(address, u.big_endian_to_int(k[2:].decode('hex')), u.big_endian_to_int(v[2:].decode('hex'))) # execute transactions sender = exek['caller'] # a party that originates a call recvaddr = exek['address'] tx = transactions.Transaction(nonce=blk._get_acct_item( exek['caller'], 'nonce'), gasprice=int(exek['gasPrice']), startgas=int(exek['gas']), to=recvaddr, value=int(exek['value']), data=exek['data'][2:].decode('hex')) tx.sender = sender ext = pb.VMExt(blk, tx) def blkhash(n): if n >= ext.block_number or n < ext.block_number - 256: return '' else: return u.sha3(str(n)) ext.block_hash = blkhash msg = vm.Message(tx.sender, tx.to, tx.value, tx.startgas, vm.CallData([ord(x) for x in tx.data])) blk2 = blocks.Block.deserialize(db, blk.serialize()) t1 = time.time() success, gas_remained, output = \ vm.vm_execute(ext, msg, exek['code'][2:].decode('hex')) blk.commit_state() t2 = time.time() recorder = LogRecorder() ext = pb.VMExt(blk2, tx) ext.block_hash = blkhash success, gas_remained, output = \ vm.vm_execute(ext, msg, exek['code'][2:].decode('hex')) trace = recorder.pop_records() ops = [x['op'] for x in trace if x['event'] == 'vm'] opdict = {} for op in ops: opdict[op] = opdict.get(op, 0) + 1 return {"ops": opdict, "time": t2 - t1}
def test_hedge(): k, v, k2, v2 = accounts() blk, addr = test_data_feeds() scode4 = ''' if !contract.storage[1000]: contract.storage[1000] = msg.sender contract.storage[1002] = msg.value contract.storage[1003] = msg.data[0] return(1) elif !contract.storage[1001]: ethvalue = contract.storage[1002] if msg.value >= ethvalue: contract.storage[1001] = msg.sender othervalue = ethvalue * msg(0x%s,0,tx.gas-100,[contract.storage[1003]],1) contract.storage[1004] = othervalue contract.storage[1005] = block.timestamp + 86400 return([2,othervalue],2) else: othervalue = contract.storage[1004] ethvalue = othervalue / msg(0x%s,0,tx.gas-100,[contract.storage[1003]],1) if ethvalue >= contract.balance: send(contract.storage[1000],contract.balance,tx.gas-100) return(3) elif block.timestamp > contract.storage[1005]: send(contract.storage[1001],contract.balance - ethvalue,tx.gas-100) send(contract.storage[1000],ethvalue,tx.gas-100) return(4) else: return(5) ''' % (addr, addr) code4 = serpent.compile(scode4) # print("AST", serpent.rewrite(serpent.parse(scode4))) # print("Assembly", serpent.compile_to_assembly(scode4)) # important: no new genesis block tx15 = t.contract(5, gasprice, startgas, 0, code4).sign(k) s, addr2 = pb.apply_tx(blk, tx15) tx16 = t.Transaction(6, gasprice, startgas, addr2, 10**17, serpent.encode_datalist([500])).sign(k) s, o = pb.apply_tx(blk, tx16) assert serpent.decode_datalist(o) == [1] tx17 = t.Transaction(0, gasprice, startgas, addr2, 10**17, serpent.encode_datalist([500])).sign(k2) s, o = pb.apply_tx(blk, tx17) assert serpent.decode_datalist(o) == [2, 72600000000000000000L] snapshot = blk.snapshot() tx18 = t.Transaction(7, gasprice, startgas, addr2, 0, '').sign(k) s, o = pb.apply_tx(blk, tx18) assert serpent.decode_datalist(o) == [5] tx19 = t.Transaction(8, gasprice, startgas, addr, 0, serpent.encode_datalist([500, 300])).sign(k) s, o = pb.apply_tx(blk, tx19) assert serpent.decode_datalist(o) == [1] tx20 = t.Transaction(9, gasprice, startgas, addr2, 0, '').sign(k) s, o = pb.apply_tx(blk, tx20) assert serpent.decode_datalist(o) == [3] blk.revert(snapshot) blk.timestamp += 200000 tx21 = t.Transaction(7, gasprice, startgas, addr, 0, serpent.encode_datalist([500, 1452])).sign(k) s, o = pb.apply_tx(blk, tx21) assert serpent.decode_datalist(o) == [1] tx22 = t.Transaction(8, gasprice, 2000, addr2, 0, '').sign(k) s, o = pb.apply_tx(blk, tx22) assert serpent.decode_datalist(o) == [4]
def prepare_state_test(params): pre = params['pre'] exek = params['transaction'] env = params['env'] # setup env blk = blocks.Block(db, prevhash=env['previousHash'].decode('hex'), number=int(env['currentNumber']), coinbase=env['currentCoinbase'], difficulty=int(env['currentDifficulty']), gas_limit=int(env['currentGasLimit']), timestamp=int(env['currentTimestamp'])) for address, h in pre.items(): blk.set_nonce(address, int(h['nonce'])) blk.set_balance(address, int(h['balance'])) blk.set_code(address, h['code'][2:].decode('hex')) for k, v in h['storage'].iteritems(): blk.set_storage_data(address, u.big_endian_to_int(k[2:].decode('hex')), u.big_endian_to_int(v[2:].decode('hex'))) # execute transactions tx = transactions.Transaction(nonce=int(exek['nonce'] or "0"), gasprice=int(exek['gasPrice'] or "0"), startgas=int(exek['gasLimit'] or "0"), to=exek['to'], value=int(exek['value'] or "0"), data=exek['data'][2:].decode('hex')).sign( exek['secretKey']) orig_apply_msg = pb.apply_msg def apply_msg_wrapper(ext, msg, code): def blkhash(n): if n >= blk.number or n < blk.number - 256: return '' else: return u.sha3(str(n)) ext.block_hash = blkhash return orig_apply_msg(ext, msg, code) pb.apply_msg = apply_msg_wrapper blk2 = blocks.Block.deserialize(db, blk.serialize()) t1 = time.time() try: pb.apply_transaction(blk, tx) except: print 'exception' pass t2 = time.time() recorder = LogRecorder() try: pb.apply_transaction(blk2, tx) except: print 'exception' pass trace = recorder.pop_records() ops = [x['op'] for x in trace if x['event'] == 'vm'] opdict = {} for op in ops: opdict[op] = opdict.get(op, 0) + 1 return {"ops": opdict, "time": t2 - t1}
### From here is pasted together from earlier version of pyetherem import serpent from pyethereum import transactions, blocks, processblock, utils #processblock.print_debug = 1 from pyethereum import slogging slogging.set_level('eth.tx', "DEBUG") code = serpent.compile(namecoin_code) key = utils.sha3('cow') addr = utils.privtoaddr(key) genesis = blocks.genesis(new_db(), {addr: 10**18}) tx1 = transactions.contract(nonce=0, gasprice=10**12, startgas=10000, endowment=0, code=code).sign(key) result, contract = processblock.apply_transaction(genesis, tx1) print genesis.to_dict() tx2 = transactions.Transaction(nonce=1, gasprice=10**12, startgas=10000, to=contract, value=0, data=serpent.encode_abi(0, 1, 45)).sign(key) result, ans = processblock.apply_transaction(genesis, tx2) serpent.decode_datalist(ans) #print genesis.to_dict()
endowment[x] = 10**18 genesis = blocks.genesis(endowment) tx1 = transactions.contract(0, 10**12, 100000, 0, root_code).sign(root_key) result, contract = processblock.apply_transaction(genesis, tx1) nonce = 1 for address in keys: longitude = random.randint(1000, 110000) latitude = random.randint(1000, 110000) datalist = serpent.encode_datalist([0, longitude, latitude]) tx = transactions.Transaction(0, 10**12, 10000, contract, 1000, datalist).sign(keys[address]) #nonce = nonce + 1 result, ans = processblock.apply_transaction(genesis, tx) storage = genesis.to_dict()["state"][contract]["storage"] integers = {} for k in storage: integers[int(k, 16)] = int(storage[k], 16) print(json.dumps(integers, sort_keys=True, indent=4, separators=(',', ': ')))