def test_uniswap_factory(t, uni_token, swap_token, uniswap_factory, contract_tester, assert_tx_failed): t.s.mine() # Create UNI token exchange uni_exchange_address = uniswap_factory.createExchange(uni_token.address) abi = json.load(open(EXCHANGE_ABI)) uni_token_exchange = t.ABIContract(t.s, abi, uni_exchange_address) assert uniswap_factory.getExchangeCount() == 1 assert uni_exchange_address == uniswap_factory.tokenToExchangeLookup(uni_token.address) assert uniswap_factory.tokenToExchangeLookup(uni_token.address) == uni_exchange_address assert u.remove_0x_head(uniswap_factory.exchangeToTokenLookup(uni_exchange_address)) == uni_token.address.hex(); # Test UNI token exchange initial state assert uni_token_exchange.FEE_RATE() == 500 assert uni_token_exchange.ethInMarket() == 0 assert uni_token_exchange.tokensInMarket() == 0 assert uni_token_exchange.invariant() == 0 assert uni_token_exchange.ethFees() == 0 assert uni_token_exchange.tokenFees() == 0 assert u.remove_0x_head(uni_token_exchange.tokenAddress()) == uni_token.address.hex() assert uni_token_exchange.totalShares() == 0 t.s.mine() # Deploy SWAP token exchange contract with factory swap_exchange_address = uniswap_factory.createExchange(swap_token.address) swap_token_exchange = t.ABIContract(t.s, abi, swap_exchange_address) assert uniswap_factory.getExchangeCount() == 2 assert swap_exchange_address == uniswap_factory.tokenToExchangeLookup(swap_token.address) assert uniswap_factory.tokenToExchangeLookup(swap_token.address) == swap_exchange_address assert u.remove_0x_head(uniswap_factory.exchangeToTokenLookup(swap_exchange_address)) == swap_token.address.hex(); # create exchange fails if sent ether assert_tx_failed(t, lambda: uniswap_factory.createExchange(uni_token.address, value=10)) # create exchange fails if parameters are missing or empty assert_tx_failed(t, lambda: uniswap_factory.createExchange()) assert_tx_failed(t, lambda: uniswap_factory.createExchange('0000000000000000000000000000000000000000'))
def compute_state_test_unit(state, txdata, indices, konfig): state.env.config = konfig s = state.snapshot() try: # Create the transaction tx = transactions.Transaction( nonce=parse_int_or_hex(txdata['nonce'] or b"0"), gasprice=parse_int_or_hex(txdata['gasPrice'] or b"0"), startgas=parse_int_or_hex( txdata['gasLimit'][indices["gas"]] or b"0"), to=decode_hex(remove_0x_head(txdata['to'])), value=parse_int_or_hex(txdata['value'][indices["value"]] or b"0"), data=decode_hex(remove_0x_head(txdata['data'][indices["data"]]))) if 'secretKey' in txdata: tx.sign(decode_hex(remove_0x_head(txdata['secretKey']))) else: tx.v = parse_int_or_hex(txdata['v']) # Run it prev = state.to_dict() success, output = apply_transaction(state, tx) print("Applied tx") except InvalidTransaction as e: print("Exception: %r" % e) success, output = False, b'' # state.set_code('0x3e180b1862f9d158abb5e519a6d8605540c23682', b'') state.commit() post = state.to_dict() # print('pozt', post) output_decl = { "hash": '0x' + encode_hex(state.trie.root_hash), "indexes": indices, "diff": mk_state_diff(prev, post) } state.revert(s) return output_decl
def test_bid(auction_tester, assert_tx_failed): auction_tester.s.mine() # Bidder cannot bid 0 assert_tx_failed(lambda: auction_tester.c.bid(value=0, sender=auction_tester.k1)) # Bidder can bid auction_tester.c.bid(value=1, sender=auction_tester.k1) # Check that higest bidder and highest bid have changed accordingly assert utils.remove_0x_head(auction_tester.c.get_highest_bidder()) == auction_tester.accounts[1].hex() assert auction_tester.c.get_highest_bid() == 1 # Bidder bid cannot equal current highest bid assert_tx_failed(lambda: auction_tester.c.bid(value=1, sender=auction_tester.k1)) # Higher bid can replace current highest bid auction_tester.c.bid(value=2, sender=auction_tester.k2) # Check that higest bidder and highest bid have changed accordingly assert utils.remove_0x_head(auction_tester.c.get_highest_bidder()) == auction_tester.accounts[2].hex() assert auction_tester.c.get_highest_bid() == 2 # Multiple bidders can bid auction_tester.c.bid(value=3, sender=auction_tester.k3) auction_tester.c.bid(value=4, sender=auction_tester.k4) auction_tester.c.bid(value=5, sender=auction_tester.k5) # Check that higest bidder and highest bid have changed accordingly assert utils.remove_0x_head(auction_tester.c.get_highest_bidder()) == auction_tester.accounts[5].hex() assert auction_tester.c.get_highest_bid() == 5 auction_tester.c.bid(value=1 * 10**10, sender=auction_tester.k1) balance_before_out_bid = auction_tester.s.head_state.get_balance(auction_tester.accounts[1]) auction_tester.c.bid(value=2 * 10**10, sender=auction_tester.k2) balance_after_out_bid = auction_tester.s.head_state.get_balance(auction_tester.accounts[1]) # Account has more money after its bid is out bid assert balance_after_out_bid > balance_before_out_bid
def init_state(env, pre): # Setup env state = State( env=Env(config=konfig), block_prevhash=decode_hex(remove_0x_head(env['previousHash'])), prev_headers=[mk_fake_header(i) for i in range(parse_int_or_hex(env['currentNumber']) - 1, max(-1, parse_int_or_hex(env['currentNumber']) - 257), -1)], block_number=parse_int_or_hex(env['currentNumber']), block_coinbase=decode_hex(remove_0x_head(env['currentCoinbase'])), block_difficulty=parse_int_or_hex(env['currentDifficulty']), gas_limit=parse_int_or_hex(env['currentGasLimit']), timestamp=parse_int_or_hex(env['currentTimestamp'])) # Fill up pre for address, h in list(pre.items()): assert len(address) in (40, 42) address = decode_hex(remove_0x_head(address)) assert set(h.keys()) == set(['code', 'nonce', 'balance', 'storage']) state.set_nonce(address, parse_int_or_hex(h['nonce'])) state.set_balance(address, parse_int_or_hex(h['balance'])) state.set_code(address, decode_hex(remove_0x_head(h['code']))) for k, v in h['storage'].items(): state.set_storage_data(address, big_endian_to_int(decode_hex(k[2:])), big_endian_to_int(decode_hex(v[2:]))) state.commit(allow_empties=True) # state.commit() return state
def compute_state_test_unit(state, txdata, konfig): state.env.config = konfig s = state.snapshot() try: # Create the transaction tx = transactions.Transaction( nonce=parse_int_or_hex(txdata['nonce'] or b"0"), gasprice=parse_int_or_hex(txdata['gasPrice'] or b"0"), startgas=parse_int_or_hex(txdata['gasLimit'] or b"0"), to=decode_hex(remove_0x_head(txdata['to'])), value=parse_int_or_hex(txdata['value'] or b"0"), data=decode_hex(remove_0x_head(txdata['data']))) if 'secretKey' in txdata: tx.sign(decode_hex(remove_0x_head(txdata['secretKey']))) else: tx.v = parse_int_or_hex(txdata['v']) # Run it prev = state.to_dict() print("calling apply_transaction") success, output = apply_transaction(state, tx) print("Applied tx") except InvalidTransaction as e: print("Exception: %r" % e) success, output = False, b'' state.commit() post = state.to_dict() output_decl = { "hash": '0x' + encode_hex(state.trie.root_hash), #"indexes": indices, #"diff": mk_state_diff(prev, post) } state.revert(s) return output_decl
def decode_log(self, log): """ Decodes an ethereum log and returns the recovered parameters along with the method from the abi that was used in decoding. Raises a LookupError if the log's topic is unknown, :param log: ethereum log :return: dictionary of decoded parameters, decoding method reference """ method_id = log[u'topics'][0][2:] if method_id not in self.methods: raise LookupError("Unknown log topic.") # method item has the event name, inputs and types method = self.methods[method_id] decoded_params = [] data_i = 0 topics_i = 1 data_types = [] # get param types from properties not indexed for param in method[u'inputs']: if not param[u'indexed']: data_types.append(param[u'type']) decoded_data = decode_abi(data_types, log[u'data']) for param in method[u'inputs']: decoded_p = {u'name': param[u'name']} if param[u'indexed']: decoded_p[u'value'] = log[u'topics'][topics_i] topics_i += 1 else: decoded_p[u'value'] = decoded_data[data_i] data_i += 1 if u'[]' in param[u'type']: if u'address' in param[u'type']: decoded_p[u'value'] = list([ remove_0x_head(account) for account in decoded_p[u'value'] ]) else: decoded_p[u'value'] = list(decoded_p[u'value']) elif u'address' == param[u'type']: address = remove_0x_head(decoded_p[u'value']) if len(address) == 40: decoded_p[u'value'] = address elif len(address) == 64: decoded_p[u'value'] = decoded_p[u'value'][26::] decoded_params.append(decoded_p) decoded_event = { u'params': decoded_params, u'name': method[u'name'], u'address': remove_0x_head(log[u'address']) } return decoded_event
def getIntrinsicGas(test_tx): tx = transactions.Transaction( nonce=parse_int_or_hex(test_tx['nonce'] or b"0"), gasprice=parse_int_or_hex(test_tx['gasPrice'] or b"0"), startgas=parse_int_or_hex(test_tx['gasLimit'] or b"0"), to=decode_hex(remove_0x_head(test_tx['to'])), value=parse_int_or_hex(test_tx['value'] or b"0"), data=decode_hex(remove_0x_head(test_tx['data']))) return tx.intrinsic_gas_used
def getTxSender(test_tx): tx = transactions.Transaction( nonce=parse_int_or_hex(test_tx['nonce'] or b"0"), gasprice=parse_int_or_hex(test_tx['gasPrice'] or b"0"), startgas=parse_int_or_hex(test_tx['gasLimit'] or b"0"), to=decode_hex(remove_0x_head(test_tx['to'])), value=parse_int_or_hex(test_tx['value'] or b"0"), data=decode_hex(remove_0x_head(test_tx['data']))) if 'secretKey' in test_tx: tx.sign(decode_hex(remove_0x_head(test_tx['secretKey']))) return encode_hex(tx.sender)
def contract_hash_to_address(self, contract_hash): """Tries to find corresponding account address""" address_hash = binascii.a2b_hex(utils.remove_0x_head(contract_hash)) indexer = AccountIndexer(self) return _encode_hex(indexer.get_contract_by_hash(address_hash))
def test_coinbase(app, account): s = app.services.accounts # coinbase not configured at all assert s.coinbase == DEFAULT_COINBASE # coinbase from first account s.add_account(account, store=False) app.config['accounts']['must_include_coinbase'] = True assert s.coinbase == account.address app.config['accounts']['must_include_coinbase'] = False assert s.coinbase == account.address # coinbase configured app.config['pow'] = {'coinbase_hex': account.address.encode('hex')} app.config['accounts']['must_include_coinbase'] = True assert s.coinbase == account.address app.config['accounts']['must_include_coinbase'] = False assert s.coinbase == account.address for invalid_coinbase in [123, '\x00' * 20, '\x00' * 40, '', 'aabbcc', 'aa' * 19, 'ff' * 21]: app.config['pow'] = {'coinbase_hex': invalid_coinbase} app.config['accounts']['must_include_coinbase'] = False with pytest.raises(ValueError): s.coinbase app.config['accounts']['must_include_coinbase'] = True with pytest.raises(ValueError): s.coinbase for valid_coinbase in ['00' * 20, 'ff' * 20, '0x' + 'aa' * 20]: app.config['pow'] = {'coinbase_hex': valid_coinbase} app.config['accounts']['must_include_coinbase'] = False assert s.coinbase == decode_hex(remove_0x_head(valid_coinbase)) app.config['accounts']['must_include_coinbase'] = True with pytest.raises(ValueError): s.coinbase
def coinbase(self): """Return the address that should be used as coinbase for new blocks. The coinbase address is given by the config field pow.coinbase_hex. If this does not exist or is `None`, the address of the first account is used instead. If there are no accounts, the coinbase is `DEFAULT_COINBASE`. :raises: :exc:`ValueError` if the coinbase is invalid (no string, wrong length) or there is no account for it and the config flag `accounts.check_coinbase` is set (does not apply to the default coinbase) """ cb_hex = self.app.config.get('pow', {}).get('coinbase_hex') if cb_hex is None: if not self.accounts_with_address: return DEFAULT_COINBASE cb = self.accounts_with_address[0].address else: if not is_string(cb_hex): raise ValueError('coinbase must be string') try: cb = decode_hex(remove_0x_head(cb_hex)) except (ValueError, TypeError): raise ValueError('invalid coinbase') if len(cb) != 20: raise ValueError('wrong coinbase length') if self.config['accounts']['must_include_coinbase']: if cb not in (acct.address for acct in self.accounts): raise ValueError('no account for coinbase') return cb
def _get_account(self, address): ''' gets account by address ''' state = self._get_head_state() accountAddress = binascii.a2b_hex(utils.remove_0x_head(address)) return state.get_and_cache_account(accountAddress)
def parseCode(code): code = remove_0x_head(code) codes = [c for c in decode_hex(code)] instructions = collections.OrderedDict() pc = 0 length = None while pc < len(codes): try: opcode = opcodes[codes[pc]] except KeyError: opcode = ['INVALID', 0, 0, 0] if opcode[0][:4] == 'PUSH': opcode = copy(opcode) length = codes[pc] - 0x5f pushData = codes[pc + 1:pc + length + 1] pushData = "0x" + encode_hex( bytearray_to_bytestr(pushData)).decode() opcode.append(pushData) instructions[pc] = opcode if length is not None: pc += length length = None pc += 1 return instructions
def test_createBurnablePayment(self): id = self.c.createBurnablePayment("need help !!!", 100, 1000, sender=self.t.k0, value=2) assert self.c.bpsCount() == 1 assert self.c.bps__title(id) == b'need help !!!' assert utils.remove_0x_head(self.c.bps__payer(id)) == self.t.a0.hex() assert self.c.bps__worker( id) == '0x0000000000000000000000000000000000000000' assert self.c.bps__amountBurned(id) == 0 assert self.c.bps__amountReleased(id) == 0 assert self.c.bps___balance(id) == 2 assert self.c.bps__state(id) == 0 assert self.c.bps__commitThreshold(id) == 100 assert self.c.bps__autoreleaseInterval(id) == 1000 assert self.c.bps__amountDeposited(id) == 2 # assert self.c.bps__autoreleaseTime(id) == self.c.addFunds(id, sender=self.t.k0, value=8) assert self.c.bps___balance(id) == 10 self.c.recoverFunds(id) assert self.c.bps___balance(id) == 0
def update_config_from_genesis_json(config, genesis_json_filename): with open(genesis_json_filename, "r") as genesis_json_file: genesis_dict = yaml.load(genesis_json_file) config.setdefault('eth', {}).setdefault('block', {}) cfg = config['eth']['block'] cfg['GENESIS_INITIAL_ALLOC'] = genesis_dict['alloc'] cfg['GENESIS_DIFFICULTY'] = parse_int_or_hex(genesis_dict['difficulty']) cfg['GENESIS_TIMESTAMP'] = parse_int_or_hex(genesis_dict['timestamp']) cfg['GENESIS_EXTRA_DATA'] = decode_hex(remove_0x_head(genesis_dict['extraData'])) cfg['GENESIS_GAS_LIMIT'] = parse_int_or_hex(genesis_dict['gasLimit']) cfg['GENESIS_MIXHASH'] = decode_hex(remove_0x_head(genesis_dict['mixhash'])) cfg['GENESIS_PREVHASH'] = decode_hex(remove_0x_head(genesis_dict['parentHash'])) cfg['GENESIS_COINBASE'] = decode_hex(remove_0x_head(genesis_dict['coinbase'])) cfg['GENESIS_NONCE'] = decode_hex(remove_0x_head(genesis_dict['nonce'])) return config
def low_level_parse_logs(ct, tx_result, events=None): if events is None: events = ['Error(bytes32)', 'Success(bytes32)'] sha3_events = {to_hex(utils.sha3(event)): re.search('.*?(?=\()', event).group(0).encode('utf-8') for event in events} for log in tx_result['logs']: if log['topics'][0] in sha3_events: yield sha3_events[log['topics'][0]], utils.remove_0x_head(log['data']).rstrip('0')
def _get_account(self, address): """Get account by address. :param address: :return: """ state = self._get_head_state() account_address = binascii.a2b_hex(utils.remove_0x_head(address)) return state.get_and_cache_account(account_address)
def getIntrinsicGas(data): import ethereum.transactions as transactions tx = transactions.Transaction(nonce=0, gasprice=0, startgas=0, to=b"", value=0, data=decode_hex(remove_0x_head(data))) return tx.intrinsic_gas_used
def test_exchange_initial_state(t, uni_token, uniswap_exchange, contract_tester, assert_tx_failed): assert uniswap_exchange.FEE_RATE() == 500 assert uniswap_exchange.ethInMarket() == 0 assert uniswap_exchange.tokensInMarket() == 0 assert uniswap_exchange.invariant() == 0 assert uniswap_exchange.ethFees() == 0 assert uniswap_exchange.tokenFees() == 0 assert u.remove_0x_head( uniswap_exchange.tokenAddress()) == uni_token.address.hex() assert uniswap_exchange.totalShares() == 0
def contract_hash_to_address(self, hash): ''' tries to find corresponding account address ''' indexer = AccountIndexer(self) addressHash = binascii.a2b_hex(utils.remove_0x_head(hash)) address = indexer.get_contract_by_hash(addressHash) if address: return _encode_hex(address) else: return "Not found"
def submit_signed_takeorder_txn(self, address, utxopos, amount, orig_takeorder_txn_hex, signature): takeorder_txn, takeorder_txn_hex = self.get_takeorder_txn(address, utxopos, amount) if (takeorder_txn_hex != orig_takeorder_txn_hex): return False else: takeorder_txn.sigtype = Transaction.SigType.txn takeorder_txn.txnsig = utils.decode_hex(utils.remove_0x_head(signature)) self.apply_transaction(rlp.encode(takeorder_txn, Transaction).hex()) return True
def submit_signed_makeorder_txn(self, address, currency, amount, tokenprice, orig_makeorder_txn_hex, signature): makeorder_txn, makeorder_txn_hex = self.get_makeorder_txn(address, currency, amount, tokenprice) if (makeorder_txn_hex != orig_makeorder_txn_hex): return False else: makeorder_txn.sigtype = Transaction.SigType.txn makeorder_txn.txnsig = utils.decode_hex(utils.remove_0x_head(signature)) self.apply_transaction(rlp.encode(makeorder_txn, Transaction).hex()) return True
def update_config_from_genesis_json(config, genesis_json_filename): with open(genesis_json_filename, "r") as genesis_json_file: genesis_dict = yaml.load(genesis_json_file) config.setdefault('eth', {}).setdefault('block', {}) cfg = config['eth']['block'] cfg['GENESIS_INITIAL_ALLOC'] = genesis_dict['alloc'] cfg['GENESIS_DIFFICULTY'] = parse_int_or_hex(genesis_dict['difficulty']) cfg['GENESIS_TIMESTAMP'] = parse_int_or_hex(genesis_dict['timestamp']) cfg['GENESIS_EXTRA_DATA'] = decode_hex( remove_0x_head(genesis_dict['extraData'])) cfg['GENESIS_GAS_LIMIT'] = parse_int_or_hex(genesis_dict['gasLimit']) cfg['GENESIS_MIXHASH'] = decode_hex(remove_0x_head( genesis_dict['mixhash'])) cfg['GENESIS_PREVHASH'] = decode_hex( remove_0x_head(genesis_dict['parentHash'])) cfg['GENESIS_COINBASE'] = decode_hex( remove_0x_head(genesis_dict['coinbase'])) cfg['GENESIS_NONCE'] = decode_hex(remove_0x_head(genesis_dict['nonce'])) return config
def run_genesis_test(params, mode): params = copy.deepcopy(params) if 'difficulty' not in params: params['difficulty'] = int_to_hex(2**34) if 'mixhash' not in params: params['mixhash'] = '0x' + '0' * 64 if 'nonce' not in params: params['nonce'] = '0x0000000000000042' if 'timestamp' not in params: params['timestamp'] = int_to_hex(5000) if 'parentHash' not in params: params['parentHash'] = '0x' + '0' * 64 if 'gasLimit' not in params: params['gasLimit'] = int_to_hex(5000) if 'extraData' not in params: params['extraData'] = '0x' if 'coinbase' not in params: params['coinbase'] = '0x' + '3' * 40 x = time.time() b = blocks.genesis( EphemDB(), start_alloc=params['alloc'], difficulty=parse_int_or_hex(params['difficulty']), timestamp=parse_int_or_hex(params['timestamp']), extra_data=decode_hex(remove_0x_head(params['extraData'])), gas_limit=parse_int_or_hex(params['gasLimit']), mixhash=decode_hex(remove_0x_head(params['mixhash'])), prevhash=decode_hex(remove_0x_head(params['parentHash'])), coinbase=decode_hex(remove_0x_head(params['coinbase'])), nonce=decode_hex(remove_0x_head(params['nonce']))) assert b.difficulty == parse_int_or_hex(params['difficulty']) assert b.timestamp == parse_int_or_hex(params['timestamp']) assert b.extra_data == decode_hex(remove_0x_head(params['extraData'])) assert b.gas_limit == parse_int_or_hex(params['gasLimit']) assert b.mixhash == decode_hex(remove_0x_head(params['mixhash'])) assert b.prevhash == decode_hex(remove_0x_head(params['parentHash'])) assert b.nonce == decode_hex(remove_0x_head(params['nonce'])) print 9 if mode == FILL: params['result'] = encode_hex(rlp.encode(b)) return params elif mode == VERIFY: assert params['result'] == encode_hex(rlp.encode(b)) elif mode == TIME: return {'creation': time.time() - x}
def run_genesis_test(params, mode): params = copy.deepcopy(params) if 'difficulty' not in params: params['difficulty'] = int_to_hex(2 ** 34) if 'mixhash' not in params: params['mixhash'] = '0x' + '0' * 64 if 'nonce' not in params: params['nonce'] = '0x0000000000000042' if 'timestamp' not in params: params['timestamp'] = int_to_hex(5000) if 'parentHash' not in params: params['parentHash'] = '0x' + '0' * 64 if 'gasLimit' not in params: params['gasLimit'] = int_to_hex(5000) if 'extraData' not in params: params['extraData'] = '0x' if 'coinbase' not in params: params['coinbase'] = '0x' + '3' * 40 x = time.time() b = blocks.genesis(EphemDB(), start_alloc=params['alloc'], difficulty=parse_int_or_hex(params['difficulty']), timestamp=parse_int_or_hex(params['timestamp']), extra_data=decode_hex(remove_0x_head(params['extraData'])), gas_limit=parse_int_or_hex(params['gasLimit']), mixhash=decode_hex(remove_0x_head(params['mixhash'])), prevhash=decode_hex(remove_0x_head(params['parentHash'])), coinbase=decode_hex(remove_0x_head(params['coinbase'])), nonce=decode_hex(remove_0x_head(params['nonce']))) assert b.difficulty == parse_int_or_hex(params['difficulty']) assert b.timestamp == parse_int_or_hex(params['timestamp']) assert b.extra_data == decode_hex(remove_0x_head(params['extraData'])) assert b.gas_limit == parse_int_or_hex(params['gasLimit']) assert b.mixhash == decode_hex(remove_0x_head(params['mixhash'])) assert b.prevhash == decode_hex(remove_0x_head(params['parentHash'])) assert b.nonce == decode_hex(remove_0x_head(params['nonce'])) print(9) if mode == FILL: params['result'] = encode_hex(rlp.encode(b)) return params elif mode == VERIFY: assert params['result'] == encode_hex(rlp.encode(b)) elif mode == TIME: return { 'creation': time.time() - x }
def test_initial_state(auction_tester): # Check beneficiary is correct assert utils.remove_0x_head(auction_tester.c.get_beneficiary()) == auction_tester.accounts[0].hex() # Check bidding time is 5 days assert auction_tester.c.get_auction_end() == auction_tester.s.head_state.timestamp + 432000 # Check start time is current block timestamp assert auction_tester.c.get_auction_start() == auction_tester.s.head_state.timestamp # Check auction has not ended assert not auction_tester.c.get_ended() # Check highest bidder is empty assert auction_tester.c.get_highest_bidder() == '0x0000000000000000000000000000000000000000' # Check highest bid is 0 assert auction_tester.c.get_highest_bid() == 0
def test_initial_state(srp_tester, assert_tx_failed): assert check_balance(srp_tester) == [INIT_BAL, INIT_BAL] #Inital deposit has to be divisible by two assert_tx_failed(lambda: srp_tester.s.contract(contract_code, language = "viper", args = [], value = 1)) #Seller puts item up for sale srp_tester.c = tester.s.contract(contract_code, language = "viper", args = [], value=2) #Check that the seller is set correctly assert utils.remove_0x_head(srp_tester.c.get_seller()) == srp_tester.accounts[0].hex() #Check if item value is set correctly (Half of deposit) assert srp_tester.c.get_value() == 1 #Check if unlocked() works correctly after initialization assert srp_tester.c.get_unlocked() == True #Check that sellers (and buyers) balance is correct assert check_balance(srp_tester) == [INIT_BAL-2, INIT_BAL]
def test_purchase(srp_tester, assert_tx_failed): srp_tester.c = srp_tester.s.contract(contract_code, language = "viper", args = [], value=2) #Purchase for too low/high price assert_tx_failed(lambda: srp_tester.c.purchase(value=1, sender=srp_tester.k1)) assert_tx_failed(lambda: srp_tester.c.purchase(value=3, sender=srp_tester.k1)) #Purchase for the correct price srp_tester.c.purchase(value=2, sender=srp_tester.k1) #Check if buyer is set correctly assert utils.remove_0x_head(srp_tester.c.get_buyer()) == srp_tester.accounts[1].hex() #Check if contract is locked correctly assert srp_tester.c.get_unlocked() == False #Check balances, both deposits should have been deducted assert check_balance(srp_tester) == [INIT_BAL-2, INIT_BAL-2] #Allow nobody else to purchase assert_tx_failed(lambda: srp_tester.c.purchase(value=2, sender=srp_tester.k3))
def test_initial_state(self): # Check chairperson is msg.sender self.assertEqual(utils.remove_0x_head(self.c.get_chairperson()), self.t.a0.hex()) # Check propsal names are correct self.assertEqual(self.c.get_proposals__name(0), b'Clinton\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00') self.assertEqual(self.c.get_proposals__name(1), b'Trump\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00') # Check proposal vote_count is 0 self.assertEqual(self.c.get_proposals__vote_count(0), 0) self.assertEqual(self.c.get_proposals__vote_count(1), 0) # Check voter_count is 0 self.assertEqual(self.c.get_voter_count(), 0) # Check voter starts empty self.assertEqual(self.c.get_voters__delegate(), '0x0000000000000000000000000000000000000000') self.assertEqual(self.c.get_voters__vote(), 0) self.assertEqual(self.c.get_voters__voted(), False) self.assertEqual(self.c.get_voters__weight(), 0)
def test_commit(self): id = self.c.createBurnablePayment("need help !!!", 100, 1000, sender=self.t.k2, value=20) assert_tx_failed(self, lambda: self.c.commit(id, sender=self.t.k0, value=1)) self.c.commit(id, sender=self.t.k0, value=100) assert utils.remove_0x_head(self.c.bps__worker(id)) == self.t.a0.hex() assert self.c.bps__state(id) == self.c.State__Committed() assert self.c.bps___balance(id) == 120 self.c.burn(id, 20, sender=self.t.k2) assert self.c.bps___balance(id) == 100 assert self.c.bps__amountBurned(id) == 20 self.c.release(id, 50, sender=self.t.k2) assert self.c.bps___balance(id) == 50 assert self.c.bps__amountReleased(id) == 50 assert_tx_failed( self, lambda: self.c.triggerAutorelease(id, sender=self.t.k0)) assert_tx_failed(self, lambda: self.c.burn(id, 45, sender=self.t.k1)) assert_tx_failed(self, lambda: self.c.release(id, 63, sender=self.t.k1))
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
def safe_lstrip_hex(val): if isinstance(val, basestring): return remove_0x_head(val) return val
def safe_lstrip_hex(val): if isinstance(val, str): return remove_0x_head(val) return val
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']), gas_limit=parse_int_or_hex(env['currentGasLimit']), timestamp=parse_int_or_hex(env['currentTimestamp'])) blk = blocks.Block(header, env=db_env) # 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=decode_hex(exek['to'][2:] if exek['to'][:2] == b'0x' else exek['to']), 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: success, output = pb.apply_transaction(blk, tx) blk.commit_state() except pb.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) assert 'post' in params # we always have a post state in the tests 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: raise Exception("Mismatch: " + k + ':\n shouldbe %r\n reallyis %r' % (shouldbe, reallyis)) elif mode == TIME: return time_post - time_pre