def test_transaction(filename, testname, testdata): testdata = fixture_to_bytes(testdata) try: rlpdata = decode_hex(testdata["rlp"][2:]) o = {} tx = rlp.decode(rlpdata, transactions.Transaction) blknum = int(testdata["blocknumber"]) if blknum >= config.default_config["HOMESTEAD_FORK_BLKNUM"]: tx.check_low_s() o["sender"] = tx.sender o["transaction"] = { "data": b'0x' * (len(tx.data) > 0) + encode_hex(tx.data), "gasLimit": str_to_bytes(str(tx.startgas)), "gasPrice": str_to_bytes(str(tx.gasprice)), "nonce": str_to_bytes(str(tx.nonce)), "r": b'0x' + encode_hex(utils.zpad(utils.int_to_big_endian(tx.r), 32)), "s": b'0x' + encode_hex(utils.zpad(utils.int_to_big_endian(tx.s), 32)), "v": str_to_bytes(str(tx.v)), "value": str_to_bytes(str(tx.value)), "to": encode_hex(tx.to), } except Exception as e: tx = None sys.stderr.write(str(e)) if 'transaction' not in testdata: # expected to fail assert tx is None else: assert set(o['transaction'].keys()) == set( testdata.get("transaction", dict()).keys()) o.get("transaction", None) == testdata.get("transaction", None) assert encode_hex(o.get("sender", '')) == testdata.get("sender", '')
def sign(self, unsigned_tx, privtKey): before_hash = utils.sha3(binascii.unhexlify(unsigned_tx.encode())) v, r, s = ecsign(before_hash, normalize_key(privtKey)) signature = binascii.hexlify( int_to_big_endian(r) + int_to_big_endian(s) + bytes(chr(v).encode())).decode() return signature
def _db_decode_type(cls, value_type, data): if value_type in ('string', 'bytes', 'binary'): return int_to_big_endian(data) if value_type == 'address': return zpad(int_to_big_endian(data), 20) return abi.decode_abi([value_type], zpad(int_to_big_endian(data), 32))[0]
def run_test(filename, testname, testdata): testdata = fixture_to_bytes(testdata) try: rlpdata = decode_hex(testdata["rlp"][2:]) print rlpdata.encode('hex') o = {} tx = rlp.decode(rlpdata, transactions.Transaction) o["sender"] = tx.sender o["transaction"] = { "data": b'0x' * (len(tx.data) > 0) + encode_hex(tx.data), "gasLimit": str_to_bytes(str(tx.startgas)), "gasPrice": str_to_bytes(str(tx.gasprice)), "nonce": str_to_bytes(str(tx.nonce)), "r": b'0x' + encode_hex(utils.zpad(utils.int_to_big_endian(tx.r), 32)), "s": b'0x' + encode_hex(utils.zpad(utils.int_to_big_endian(tx.s), 32)), "v": str_to_bytes(str(tx.v)), "value": str_to_bytes(str(tx.value)), "to": encode_hex(tx.to), } except: tx = None if 'transaction' not in testdata: # expected to fail assert tx is None else: assert set(o['transaction'].keys()) == set( testdata.get("transaction", dict()).keys()) o.get("transaction", None) == testdata.get("transaction", None) assert encode_hex(o.get("sender", '')) == testdata.get("sender", '')
def run_test(filename, testname, testdata): testdata = fixture_to_bytes(testdata) try: rlpdata = decode_hex(testdata["rlp"][2:]) print rlpdata.encode("hex") o = {} tx = rlp.decode(rlpdata, transactions.Transaction) o["sender"] = tx.sender o["transaction"] = { "data": b"0x" * (len(tx.data) > 0) + encode_hex(tx.data), "gasLimit": str_to_bytes(str(tx.startgas)), "gasPrice": str_to_bytes(str(tx.gasprice)), "nonce": str_to_bytes(str(tx.nonce)), "r": b"0x" + encode_hex(utils.zpad(utils.int_to_big_endian(tx.r), 32)), "s": b"0x" + encode_hex(utils.zpad(utils.int_to_big_endian(tx.s), 32)), "v": str_to_bytes(str(tx.v)), "value": str_to_bytes(str(tx.value)), "to": encode_hex(tx.to), } except: tx = None if "transaction" not in testdata: # expected to fail assert tx is None else: assert set(o["transaction"].keys()) == set(testdata.get("transaction", dict()).keys()) o.get("transaction", None) == testdata.get("transaction", None) assert encode_hex(o.get("sender", "")) == testdata.get("sender", "")
def test_transaction(filename, testname, testdata): testdata = fixture_to_bytes(testdata) try: rlpdata = decode_hex(testdata["rlp"][2:]) o = {} tx = rlp.decode(rlpdata, transactions.Transaction) blknum = int(testdata["blocknumber"]) if blknum >= config.default_config["HOMESTEAD_FORK_BLKNUM"]: tx.check_low_s() o["sender"] = tx.sender o["transaction"] = { "data": b'0x' * (len(tx.data) > 0) + encode_hex(tx.data), "gasLimit": str_to_bytes(str(tx.startgas)), "gasPrice": str_to_bytes(str(tx.gasprice)), "nonce": str_to_bytes(str(tx.nonce)), "r": b'0x' + encode_hex(utils.zpad(utils.int_to_big_endian(tx.r), 32)), "s": b'0x' + encode_hex(utils.zpad(utils.int_to_big_endian(tx.s), 32)), "v": str_to_bytes(str(tx.v)), "value": str_to_bytes(str(tx.value)), "to": encode_hex(tx.to), } except Exception as e: tx = None sys.stderr.write(str(e)) if 'transaction' not in testdata: # expected to fail assert tx is None else: assert set(o['transaction'].keys()) == set(testdata.get("transaction", dict()).keys()) o.get("transaction", None) == testdata.get("transaction", None) assert encode_hex(o.get("sender", '')) == testdata.get("sender", '')
def test_update(chain, accounts, storage_slots): counter = 0 while True: for k in accounts: counter += 1 v = int_to_big_endian(counter) # r = chain.storage.get(k+v) # assert r == v, (r, v) v2 = int_to_big_endian(counter + 1) chain.storage.update(k+v, v2) if counter == storage_slots: return chain
def sign_args(self, typeList, valueList, privtKey): ''' :param typeList: ['bytes32', 'bytes32', 'uint256', 'uint256'] :param valueList: ["0x3ae88fe370c39384fc16da2c9e768cf5d2495b48", "0x9da26fc2e1d6ad9fdd46138906b0104ae68a65d8", 1, 1] :param privtKey: "095e53c9c20e23fd01eaad953c01da9e9d3ed9bebcfed8e5b2c2fce94037d963" :return: ''' data_hash = Web3.soliditySha3(typeList, valueList) v, r, s = ecsign(data_hash, normalize_key(privtKey)) signature = binascii.hexlify(int_to_big_endian(r) + int_to_big_endian(s) + bytes(chr(v - 27).encode())) return signature
def get_state_variable_from_storage(self, address, params=[]): (position, length, mappings) = (0, 1, []) try: if params[0] == "mapping": if len(params) < 3: raise CriticalError("Invalid number of parameters.") position = int(params[1]) position_formatted = utils.zpad(utils.int_to_big_endian(position), 32) for i in range(2, len(params)): key = bytes(params[i], 'utf8') key_formatted = utils.rzpad(key, 32) mappings.append(int.from_bytes(utils.sha3(key_formatted + position_formatted), byteorder='big')) length = len(mappings) if length == 1: position = mappings[0] else: if len(params) >= 4: raise CriticalError("Invalid number of parameters.") if len(params) >= 1: position = int(params[0]) if len(params) >= 2: length = int(params[1]) if len(params) == 3 and params[2] == "array": position_formatted = utils.zpad(utils.int_to_big_endian(position), 32) position = int.from_bytes(utils.sha3(position_formatted), byteorder='big') except ValueError: raise CriticalError("Invalid storage index. Please provide a numeric value.") outtxt = [] try: if length == 1: outtxt.append("{}: {}".format(position, self.eth.eth_getStorageAt(address, position))) else: if len(mappings) > 0: for i in range(0, len(mappings)): position = mappings[i] outtxt.append("{}: {}".format(hex(position), self.eth.eth_getStorageAt(address, position))) else: for i in range(position, position + length): outtxt.append("{}: {}".format(hex(i), self.eth.eth_getStorageAt(address, i))) except FileNotFoundError as e: raise CriticalError("IPC error: " + str(e)) except ConnectionError as e: raise CriticalError("Could not connect to RPC server. Make sure that your node is running and that RPC parameters are set correctly.") return '\n'.join(outtxt)
def mine(block_number, difficulty, mining_hash, start_nonce=0, rounds=1000): assert isinstance(start_nonce, (int, long)) cache = get_cache(block_number) nonce = start_nonce target = utils.zpad(utils.int_to_big_endian(2**256 // (difficulty or 1)), 32) for i in range(1, rounds + 1): bin_nonce = utils.zpad(utils.int_to_big_endian((nonce + i) & TT64M1), 8) o = hashimoto_light(block_number, cache, mining_hash, bin_nonce) if o["result"] <= target: log.debug("nonce found") assert len(bin_nonce) == 8 assert len(o["mix digest"]) == 32 return bin_nonce, o["mix digest"] return None, None
def mine(block_number, difficulty, mining_hash, start_nonce=0, rounds=1000): assert utils.is_numeric(start_nonce) cache = get_cache(block_number) nonce = start_nonce target = utils.zpad( utils.int_to_big_endian(2**256 // (difficulty or 1) - 1), 32) for i in range(1, rounds + 1): bin_nonce = utils.zpad(utils.int_to_big_endian((nonce + i) & TT64M1), 8) o = hashimoto_light(block_number, cache, mining_hash, bin_nonce) if o[b'result'] <= target: log.debug('nonce found: {}'.format(bin_nonce)) assert len(bin_nonce) == 8 assert len(o[b'mix digest']) == 32 return bin_nonce, o[b'mix digest'] return None, None
def loglist_encoder(loglist): """Encode a list of log""" l = [] if len(loglist) > 0 and loglist[0] is None: assert all(element is None for element in l) return l result = [] for log, index, block in loglist: result.append({ 'logIndex': quantity_encoder(index), 'transactionIndex': None, 'transactionHash': None, 'blockHash': data_encoder(block.hash), 'blockNumber': quantity_encoder(block.number), 'address': address_encoder(log.address), 'data': data_encoder(log.data), 'topics': [ data_encoder(int_to_big_endian(topic), 32) for topic in log.topics ] }) return result
def proc_modexp(ext, msg): if not ext.post_metropolis_hardfork(): return 1, msg.gas, [] print('modexp proc', msg.gas) baselen = msg.data.extract32(0) explen = msg.data.extract32(32) modlen = msg.data.extract32(64) first_exp_bytes = msg.data.extract32(96 + baselen) >> (8 * max(32 - explen, 0)) bitlength = -1 while first_exp_bytes: bitlength += 1 first_exp_bytes >>= 1 adjusted_explen = max(bitlength, 0) + 8 * max(explen - 32, 0) gas_cost = (max(modlen, baselen)**2 * max(adjusted_explen, 1)) // opcodes.GMODEXPQUADDIVISOR print(baselen, explen, modlen, 'expected gas cost', gas_cost) if msg.gas < gas_cost: return 0, 0, [] base = bytearray(baselen) msg.data.extract_copy(base, 0, 96, baselen) exp = bytearray(explen) msg.data.extract_copy(exp, 0, 96 + baselen, explen) mod = bytearray(modlen) msg.data.extract_copy(mod, 0, 96 + baselen + explen, modlen) if utils.big_endian_to_int(mod) == 0: return 1, msg.gas - gas_cost, [0] * modlen o = pow(utils.big_endian_to_int(base), utils.big_endian_to_int(exp), utils.big_endian_to_int(mod)) return 1, msg.gas - gas_cost, [ safe_ord(x) for x in utils.zpad(utils.int_to_big_endian(o), modlen) ]
def test_lottery_payer_deposit_owner(self): self.deploy_contract(9) payer = tester.a6 w0 = self.state.block.get_balance(payer) lottery = Lottery({tester.a1: 11 * eth, tester.a2: 39 * eth}) g1 = self.lottery_init(6, lottery) v = 50 * eth deposit = v / 10 assert self.lottery_get_value(lottery) == v assert self.lottery_get_maturity(lottery) == 10 b = self.state.block.get_balance(payer) - w0 assert b == -(v + deposit + g1) self.state.mine(256 + 11) expected_rand = self.state.block.get_parent().hash[-4:] # Owner gets the deposit self.lottery_randomise(8, lottery) r = self.lottery_get_rand(lottery) r = zpad(int_to_big_endian(r), 4) assert r == expected_rand assert b == -(v + deposit + g1) assert self.lottery_get_owner_deposit() == deposit b0 = self.state.block.get_balance(tester.a9) self.lottery_owner_payout() b = self.state.block.get_balance(tester.a9) - b0 assert b == deposit assert self.lottery_get_owner_deposit() == 0
def mod_exp(data: List[int]) -> List[int]: """ TODO: Some symbolic parts can be handled here Modular Exponentiation :param data: Data with <length_of_BASE> <length_of_EXPONENT> <length_of_MODULUS> <BASE> <EXPONENT> <MODULUS> :return: modular exponentiation """ bytes_data = bytearray(data) baselen = extract32(bytes_data, 0) explen = extract32(bytes_data, 32) modlen = extract32(bytes_data, 64) if baselen == 0: return [0] * modlen if modlen == 0: return [] first_exp_bytes = extract32(bytes_data, 96 + baselen) >> (8 * max(32 - explen, 0)) while first_exp_bytes: first_exp_bytes >>= 1 base = bytearray(baselen) extract_copy(bytes_data, base, 0, 96, baselen) exp = bytearray(explen) extract_copy(bytes_data, exp, 0, 96 + baselen, explen) mod = bytearray(modlen) extract_copy(bytes_data, mod, 0, 96 + baselen + explen, modlen) if big_endian_to_int(mod) == 0: return [0] * modlen o = pow(big_endian_to_int(base), big_endian_to_int(exp), big_endian_to_int(mod)) return [safe_ord(x) for x in zpad(int_to_big_endian(o), modlen)]
def mine(self, start_nonce=0): cache = get_cache(self._block_number_int) nonce = start_nonce i = 0 difficulty = int(bin_to_hex_b(self._target_bin)[2:], 16) print('Difficulty: ', difficulty) print('Block Number: ', self._block_number_int) cnt = 0 start = time.time() while True: i += 1 cnt += 1 bin_nonce = utils.zpad(utils.int_to_big_endian((nonce + i)), 8) k = sha3.keccak_256() k.update(self._mining_hash_bin) k.update(bin_nonce) hash1 = int(k.hexdigest(), 16) # o = hashimoto_light(self._block_number_int, cache, self._mining_hash_bin, bin_nonce) if hash1 <= difficulty: end = time.time() self._nonce_bin = bin_nonce print('Hashes Done: ', cnt) # for x in self._mining_hash_bin: # print(x) # for x in bin_nonce: # print(x) # print('Nonce: ', bin_nonce, len( bin_nonce)) print('Block Mining Time: ', end - start) return
def encode_int(v): s = encode_hex(int_to_big_endian(int(v))) if s[:1] == '0': # remove leading zero s = s[1:] if not s: s = '0' return '0x' + s
def block_encoder(block, include_transactions, pending=False): """Encode a block as JSON object. :param block: a :class:`ethereum.blocks.Block` :param include_transactions: if true transactions are included, otherwise only their hashes :returns: a json encodable dictionary """ d = { 'number': quantity_encoder(block.number), 'hash': data_encoder(block.hash), 'parentHash': data_encoder(block.prevhash), 'nonce': data_encoder(block.nonce), 'sha3Uncles': data_encoder(block.uncles_hash), 'logsBloom': data_encoder(int_to_big_endian(block.bloom)), 'transactionsRoot': data_encoder(block.tx_list_root), 'stateRoot': data_encoder(block.state_root), 'miner': data_encoder(block.coinbase), 'difficulty': quantity_encoder(block.difficulty), 'totalDifficulty': quantity_encoder(block.chain_difficulty()), 'extraData': data_encoder(block.extra_data), 'size': quantity_encoder(len(rlp.encode(block))), 'gasLimit': quantity_encoder(block.gas_limit), 'minGasPrice': quantity_encoder(0), # TODO quantity_encoder(block.gas_price), 'gasUsed': quantity_encoder(block.gas_used), 'timestamp': quantity_encoder(block.timestamp), 'uncles': [data_encoder(u.hash) for u in block.uncles] } if include_transactions: d['transactions'] = [] for i, tx in enumerate(block.get_transactions()): d['transactions'].append(tx_encoder(tx, block, i, pending)) else: d['transactions'] = [quantity_encoder(tx.hash) for x in block.get_transactions()] return d
def signature_from_transaction(tx): if isinstance(tx, str): tx = decode_transaction(tx) p1 = int_to_big_endian(tx.r) p2 = int_to_big_endian(tx.s) # make sure each string is 32 bytes long, padding with 0 when it's not if len(p1) < 32: p1 = bytes([0] * (32 - len(p1))) + p1 if len(p2) < 32: p2 = bytes([0] * (32 - len(p2))) + p2 signature = p1 + p2 + bytes([tx.v - 27]) return signature
def test_ssv(chain, accounts, storage_slots): # get log reader sj = chain.storage.db # state journal sj.commit() lr = statejournal.JournalReader(sj.db) # validate full chain if False: state = lr.validate_state(sj.update_counter) assert state == sj.state_digest assert state == lr.last_update()['state_digest'] # get ssv ################ # read first (oldest entry) counter = 1 k = accounts[0] v = int_to_big_endian(counter) k += v # get the proof val, update_counter = sj.get_raw(k) proof = lr.get_ssv(update_counter) assert proof['value'] == val, (big_endian_to_int(proof['value']), val) hash_chain = proof['hash_chain'] assert len(hash_chain) s = hash_chain[0] for h in hash_chain[1:]: s = sha3(s + h) assert s == sj.state_digest
def test_lottery_payer_deposit_sender(self): self.deploy_contract() payer = tester.a6 w0 = self.state.block.get_balance(payer) lottery = Lottery({tester.a1: 11 * eth, tester.a2: 39 * eth}) g1 = self.lottery_init(6, lottery) v = 50 * eth deposit = v / 10 assert self.lottery_get_value(lottery) == v assert self.lottery_get_maturity(lottery) == 10 b = self.state.block.get_balance(payer) - w0 assert b == -(v + deposit + g1) self.state.mine(11) expected_rand = self.state.block.get_parent().hash[-4:] self.state.mine(255) s0 = self.state.block.get_balance(tester.a8) # Sender gets the deposit g2 = self.lottery_randomise(8, lottery, deposit) assert g2 > 0 and g2 <= 32000 r = self.lottery_get_rand(lottery) r = zpad(int_to_big_endian(r), 4) assert r == expected_rand b = self.state.block.get_balance(payer) - w0 assert b == -(v + deposit + g1) s = self.state.block.get_balance(tester.a8) - s0 assert s == deposit - g2
def validate_proof(lottery, ticket, proof): start = zpad(int_to_big_endian(ticket.begin), 4) assert len(start) == 4 length = zpad(int_to_big_endian(ticket.length), 4) assert len(length) == 4 h = sha3(ticket.address + start + length) assert h == ticket.node.hash for p in proof: xor = b''.join(chr(ord(a) ^ ord(b)) for a, b in zip(h, p)) h = sha3(xor) assert h == lottery.root.hash h = sha3(lottery.nonce + h) assert h == lottery.hash
def getWork(self): print 'Sending work...' h = self.chain.chain.head_candidate return [ encode_hex(h.header.mining_hash), encode_hex(h.header.seed), encode_hex(zpad(int_to_big_endian(2**256 // h.header.difficulty), 32)) ]
def test_delete(chain, accounts, storage_slots): counter = 0 while True: for k in accounts: counter += 1 v = int_to_big_endian(counter) chain.storage.delete(k+v) if counter == storage_slots: return chain
def test_batch_transfer_to_zero(chain): owner_addr, receiver_addr, gnt, gntb, cdep = mysetup(chain) addr = b'\0' * 20 vv = zpad(int_to_big_endian(1), 12) mix = vv + addr payments = [mix] assert len(mix) == 32 with pytest.raises(TransactionFailed): gntb.transact({'from': owner_addr}).batchTransfer(payments, 123)
def encode_payment(p: Payment) -> bytes: max_value = 2**96 if p.amount >= max_value: raise ValueError("Payment should be less than {}".format(max_value)) v = zpad(int_to_big_endian(p.amount), 12) pair = v + decode_hex(p.payee) if len(pair) != 32: raise ValueError("Incorrect pair length: {}. Should be 32".format( len(pair))) return pair
def test_reads(chain, accounts, storage_slots): counter = 0 while True: for k in accounts: counter += 1 v = int_to_big_endian(counter) r = chain.storage.get(k+v) assert v == r, repr((v, r, counter)) if counter == storage_slots: return chain
def __init__(self, shard_id=int_to_big_endian(0), prev_state_root=trie.BLANK_ROOT, tx_list_root=trie.BLANK_ROOT, coinbase=sharding_config['GENESIS_COINBASE'], post_state_root=trie.BLANK_ROOT, receipt_root=trie.BLANK_ROOT, children=[], state_branch_node=utils.sha3rlp([]), signatures=[], mixhash='', nonce='', source_block_numeber=int_to_big_endian(0), source_block_hash=utils.sha3rlp([])): fields = {k: v for k, v in locals().items() if k != 'self'} if len(fields['coinbase']) == 40: fields['coinbase'] = decode_hex(fields['coinbase']) assert len(fields['coinbase']) == 20 super(CollationHeader, self).__init__(**fields)
def __init__(self, left=None, right=None, value=None): self.parent = None if value: begin = zpad(int_to_big_endian(value.begin), 4) assert len(begin) == 4 length = zpad(int_to_big_endian(value.length), 4) assert len(length) == 4 data = value.address + begin + length assert len(data) == 20 + 4 + 4 self.hash = sha3(data) self.value = value self.value.node = self else: xor = b''.join(chr(ord(a) ^ ord(b)) for a, b in zip(left.hash, right.hash)) self.hash = sha3(xor) self.left = left self.right = right self.left.parent = self self.right.parent = self
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 length_prefix(length, offset): """Construct the prefix to lists or strings denoting their length. :param length: the length of the item in bytes :param offset: ``0x80`` when encoding raw bytes, ``0xc0`` when encoding a list """ if length < 56: return chr(offset + length) else: length_string = int_to_big_endian(length) return chr(offset + 56 - 1 + len(length_string)) + length_string
def test_writes(chain, accounts, storage_slots, commit_interval=1000): print 'created hashes' counter = 0 while True: for k in accounts: counter += 1 v = int_to_big_endian(counter) chain.storage.update(k+v, v) if counter == storage_slots: return chain if counter % commit_interval == 0: chain.storage.commit()
def __init__(self, left=None, right=None, value=None): self.parent = None if value: begin = zpad(int_to_big_endian(value.begin), 4) assert len(begin) == 4 length = zpad(int_to_big_endian(value.length), 4) assert len(length) == 4 data = value.address + begin + length assert len(data) == 20 + 4 + 4 self.hash = sha3(data) self.value = value self.value.node = self else: xor = b''.join( chr(ord(a) ^ ord(b)) for a, b in zip(left.hash, right.hash)) self.hash = sha3(xor) self.left = left self.right = right self.left.parent = self self.right.parent = self
def test_decint(): assert decint(True) == 1 assert decint(False) == 0 assert decint(None) == 0 # unsigned upper boundary assert decint(2**256 - 1, signed=False) == 2**256 - 1 assert decint(int_to_big_endian(2**256 - 1), signed=False) == 2**256 - 1 with pytest.raises(EncodingError): decint(2**256, signed=False) decint(int_to_big_endian(2**256), signed=False) # unsigned lower boundary assert decint(0) == 0 assert decint(int_to_big_endian(0)) == 0 with pytest.raises(EncodingError): decint(-1, signed=False) decint(int_to_big_endian(-1), signed=False) # signed upper boundary assert decint(2**255 - 1, signed=True) == 2**255 - 1 assert decint(int_to_big_endian(2**255 - 1), signed=True) == 2**255 - 1 with pytest.raises(EncodingError): decint(2**255, signed=True) decint(int_to_big_endian(2**255), signed=True) # signed lower boundary assert decint(-2**255, signed=True) == -2**255 # assert decint(int_to_big_endian(-2 ** 255), signed=True) == -2 ** 255 with pytest.raises(EncodingError): decint(-2**255 - 1, signed=True)
def test_transaction(filename, testname, testdata): try: rlpdata = decode_hex(testdata["rlp"][2:]) o = {} tx = rlp.decode(rlpdata, transactions.Transaction) blknum = int(testdata["blocknumber"]) # if blknum >= config.default_config["HOMESTEAD_FORK_BLKNUM"]: # tx.check_low_s_homestead() assert config_fork_specific_validation(konfig, blknum, tx) assert tx.startgas >= tx.intrinsic_gas_used if tx.sender == null_address: assert tx.value == 0 and tx.gasprice == 0 and tx.nonce == 0 o["sender"] = tx.sender o["transaction"] = { "data": '0x' * (len(tx.data) > 0) + encode_hex(tx.data), "gasLimit": str(tx.startgas), "gasPrice": str(tx.gasprice), "nonce": str(tx.nonce), "r": '0x' + encode_hex(utils.zpad(utils.int_to_big_endian(tx.r), 32)), "s": '0x' + encode_hex(utils.zpad(utils.int_to_big_endian(tx.s), 32)), "v": str(tx.v), "value": str(tx.value), "to": encode_hex(tx.to), } except Exception as e: tx = None sys.stderr.write(str(e)) if 'transaction' not in testdata: # expected to fail # print(tx.to_dict(), testdata) assert tx is None else: assert set(o['transaction'].keys()) == set( testdata.get("transaction", dict()).keys()) o.get("transaction", None) == testdata.get("transaction", None) assert str_to_bytes(encode_hex(o.get("sender", ''))) == str_to_bytes( testdata.get("sender", ''))
def run_test(filename, testname, testdata): testdata = fixture_to_bytes(testdata) try: rlpdata = decode_hex(testdata["rlp"][2:]) o = {} tx = rlp.decode(rlpdata, transactions.Transaction) o["sender"] = tx.sender o["transaction"] = { "data": b'0x' * (len(tx.data) > 0) + encode_hex(tx.data), "gasLimit": str_to_bytes(str(tx.startgas)), "gasPrice": str_to_bytes(str(tx.gasprice)), "nonce": str_to_bytes(str(tx.nonce)), "r": b'0x' + encode_hex(utils.zpad(utils.int_to_big_endian(tx.r), 32)), "s": b'0x' + encode_hex(utils.zpad(utils.int_to_big_endian(tx.s), 32)), "v": str_to_bytes(str(tx.v)), "value": str_to_bytes(str(tx.value)), "to": encode_hex(tx.to), } except Exception, e: tx = None sys.stderr.write(str(e))
def update(self, key, value): """ - increases the update counter - retrieves the the old_update_counter for the key - stores the value in leveldb - generates a log: rlp[key, value, old_update_counter] - computes the new state_digest as: H(last_state_digest, H(log)) - adds to the journal: state_digest | log | journal_entry_length - updates index with the postion of the end of above journal_entry """ self.update_counter += 1 old_value, old_counter = self.get_raw(key) # store in leveldb if value: _stored_value = rlp.encode([value, self.update_counter]) self.db.put(key, _stored_value) else: self.db.delete(key) # generate log log = rlp.encode([key, value, old_counter]) # update state self.state_digest = sha3(self.state_digest + sha3(log)) # state_digest | [key, value, old_counter] | journal_entry_length self.journal.write(self.state_digest) self.journal.write(log) journal_entry_length = 32 + len(log) + 2 assert journal_entry_length < b16, journal_entry_length self.journal.write(zpad(int_to_big_endian(journal_entry_length), 2)) # 2 bytes # write index pos = self.journal.tell() assert pos < b32 idx = zpad(int_to_big_endian(pos), 4) # 4 bytes self.journal_index.write(idx)
def format_message(msg, kwargs, highlight, level): if 'memory' in kwargs: vm.log_vm_op.memory = '0x' + kwargs['memory'] if 'storage' in kwargs: s = [] storage = kwargs['storage']['storage'] for k in sorted(storage.keys()): v = '0x' + encode_hex(zpad(int_to_big_endian(scan_int(storage[k])),32)) k = '0x' + encode_hex(zpad(int_to_big_endian(scan_int(k)),32)) s.append(k + ': ' + v) s = ','.join(s) vm.log_vm_op.storage = s return '{"pc":%s,"op":%s,"gas":"%s","gasCost":"%s","memory":"%s","stack":[%s],"storage":{%s},"depth":%s}' % ( kwargs['pc'], kwargs['inst'], encode_int(int(kwargs['gas'])), encode_int(kwargs['gas_cost']), vm.log_vm_op.memory, ','.join(['"%s"' % encode_int(v) for v in kwargs['stack']]), vm.log_vm_op.storage, kwargs['depth']+1 )
def block_encoder(block, include_transactions=False, pending=False, is_header=False): """Encode a block as JSON object. :param block: a :class:`ethereum.blocks.Block` :param include_transactions: if true transactions are included, otherwise only their hashes :param pending: if `True` the block number of transactions, if included, is set to `None` :param is_header: if `True` the following attributes are ommitted: size, totalDifficulty, transactions and uncles (thus, the function can be called with a block header instead of a full block) :returns: a json encodable dictionary """ assert not (include_transactions and is_header) d = { 'number': quantity_encoder(block.number), 'hash': data_encoder(block.hash), 'parentHash': data_encoder(block.prevhash), 'nonce': data_encoder(block.nonce), 'sha3Uncles': data_encoder(block.uncles_hash), 'logsBloom': data_encoder(int_to_big_endian(block.bloom), 256), 'transactionsRoot': data_encoder(block.tx_list_root), 'stateRoot': data_encoder(block.state_root), 'difficulty': quantity_encoder(block.difficulty), 'extraData': data_encoder(block.extra_data), 'gasLimit': quantity_encoder(block.gas_limit), 'gasUsed': quantity_encoder(block.gas_used), 'timestamp': quantity_encoder(block.timestamp), } if not is_header: d['totalDifficulty'] = quantity_encoder(block.chain_difficulty()) d['size'] = quantity_encoder(len(rlp.encode(block))) d['uncles'] = [data_encoder(u.hash) for u in block.uncles] if include_transactions: d['transactions'] = [] for i, tx in enumerate(block.get_transactions()): d['transactions'].append(tx_encoder(tx, block, i, pending)) else: d['transactions'] = [ data_encoder(tx.hash) for tx in block.get_transactions() ] if not pending: d['miner'] = data_encoder(block.coinbase) d['nonce'] = data_encoder(block.nonce) else: d['miner'] = '0x0000000000000000000000000000000000000000' d['nonce'] = '0x0000000000000000' return d
def encode_payments(payments): args = [] value_sum = 0L for idx, v in payments: addr = tester.accounts[idx] value_sum += v v = long(v) assert v < 2**96 vv = zpad(int_to_big_endian(v), 12) mix = vv + addr assert len(mix) == 32 print encode_hex(mix), "v: ", v, "addr", encode_hex(addr) args.append(mix) return args, value_sum
def account_to_dict(self, address, with_storage_root=False, with_storage=True): """Serialize an account to a dictionary with human readable entries. :param address: the 20 bytes account address :param with_storage_root: include the account's storage root :param with_storage: include the whole account's storage """ if len(address) == 40: address = decode_hex(address) assert len(address) == 20 if with_storage_root: # if there are uncommited account changes the current storage root # is meaningless assert len(self.journal) == 0 med_dict = {} account = self._get_acct(address) for field in ('balance', 'nonce'): value = self.caches[field].get(address, getattr(account, field)) med_dict[field] = to_string(value) code = self.caches['code'].get(address, account.code) med_dict['code'] = b'0x' + encode_hex(code) storage_trie = SecureTrie(Trie(self.db, account.storage)) if with_storage_root: med_dict['storage_root'] = encode_hex(storage_trie.get_root_hash()) if with_storage: med_dict['storage'] = {} d = storage_trie.to_dict() subcache = self.caches.get(b'storage:' + address, {}) subkeys = [utils.zpad(utils.coerce_to_bytes(kk), 32) for kk in list(subcache.keys())] for k in list(d.keys()) + subkeys: v = d.get(k, None) v2 = subcache.get(utils.big_endian_to_int(k), None) hexkey = b'0x' + encode_hex(utils.zunpad(k)) if v2 is not None: if v2 != 0: med_dict['storage'][hexkey] = \ b'0x' + encode_hex(utils.int_to_big_endian(v2)) elif v is not None: med_dict['storage'][hexkey] = b'0x' + encode_hex(rlp.decode(v)) return med_dict
def block_encoder(block, include_transactions=False, pending=False, is_header=False): """Encode a block as JSON object. :param block: a :class:`ethereum.blocks.Block` :param include_transactions: if true transactions are included, otherwise only their hashes :param pending: if `True` the block number of transactions, if included, is set to `None` :param is_header: if `True` the following attributes are ommitted: size, totalDifficulty, transactions and uncles (thus, the function can be called with a block header instead of a full block) :returns: a json encodable dictionary """ assert not (include_transactions and is_header) d = { 'number': quantity_encoder(block.number), 'hash': data_encoder(block.hash), 'parentHash': data_encoder(block.prevhash), 'nonce': data_encoder(block.nonce), 'sha3Uncles': data_encoder(block.uncles_hash), 'logsBloom': data_encoder(int_to_big_endian(block.bloom), 256), 'transactionsRoot': data_encoder(block.tx_list_root), 'stateRoot': data_encoder(block.state_root), 'difficulty': quantity_encoder(block.difficulty), 'extraData': data_encoder(block.extra_data), 'gasLimit': quantity_encoder(block.gas_limit), 'gasUsed': quantity_encoder(block.gas_used), 'timestamp': quantity_encoder(block.timestamp), } if not is_header: d['totalDifficulty'] = quantity_encoder(block.chain_difficulty()) d['size'] = quantity_encoder(len(rlp.encode(block))) d['uncles'] = [data_encoder(u.hash) for u in block.uncles] if include_transactions: d['transactions'] = [] for i, tx in enumerate(block.get_transactions()): d['transactions'].append(tx_encoder(tx, block, i, pending)) else: d['transactions'] = [data_encoder(tx.hash) for tx in block.get_transactions()] if not pending: d['miner'] = data_encoder(block.coinbase) d['nonce'] = data_encoder(block.nonce) else: d['miner'] = '0x0000000000000000000000000000000000000000' d['nonce'] = '0x0000000000000000' return d
def _encode_payments(payments): paymap = {} for p in payments: if p.payee in paymap: paymap[p.payee] += p.value else: paymap[p.payee] = p.value args = [] value = 0L for to, v in paymap.iteritems(): value += v assert v < 2**96 v = utils.zpad(utils.int_to_big_endian(v), 12) pair = v + to assert len(pair) == 32 args.append(pair) return args, value
def test_lottery_randomise(self): self.deploy_contract() lottery = Lottery({tester.a1: 50 * eth, tester.a2: 50 * eth}) assert lottery.value == 100 * eth self.lottery_init(3, lottery) assert self.lottery_get_value(lottery) == lottery.value self.state.mine(11) assert self.state.block.number == 11 assert self.state.block.number > self.lottery_get_maturity(lottery) r = self.lottery_get_rand(lottery) assert r == 0 g = self.lottery_randomise(3, lottery) assert g <= 44919 r = self.lottery_get_rand(lottery) r = zpad(int_to_big_endian(r), 4) assert r == self.state.block.get_parent().hash[-4:] assert self.lottery_get_maturity(lottery) == 0 assert self.lottery_get_value(lottery) == lottery.value
def loglist_encoder(loglist): """Encode a list of log""" # l = [] # if len(loglist) > 0 and loglist[0] is None: # assert all(element is None for element in l) # return l result = [] for l in loglist: result.append({ 'logIndex': quantity_encoder(l['log_idx']), 'transactionIndex': quantity_encoder(l['tx_idx']), 'transactionHash': data_encoder(l['txhash']), 'blockHash': data_encoder(l['block'].hash), 'blockNumber': quantity_encoder(l['block'].number), 'address': address_encoder(l['log'].address), 'data': data_encoder(l['log'].data), 'topics': [data_encoder(int_to_big_endian(topic), 32) for topic in l['log'].topics] }) return result
def test_reveal_returns_entropy(self): assert self.c.commit(1, self.COW_HASH, value=self.DEPOSIT_COST) == 1 assert self.c.request_entropy(sender=tester.k1, value=self.ENTROPY_COST) == [0, 4] assert self.c.get_block(self.s.block.number + 1) == [0, 1, 0, 1] self.s.mine(2) COW_SEED = utils.big_endian_to_int(utils.sha3(utils.sha3(utils.zpad('cow', 32)) + utils.zpad('cow', 32))) COW_HASH_1 = utils.big_endian_to_int(utils.sha3(utils.int_to_big_endian(COW_SEED))) balance = self.s.block.get_balance(tester.a0) assert self.c.reveal(1, self.COW_INT) == 1 assert self.s.block.get_balance(tester.a0) - balance == self.DEPOSIT_COST + self.ENTROPY_COST # deposit return + payout of committer share assert self.c.get_block(1) == [COW_SEED, 1, 1, 1] # signed vs unsigned as introduced by tester.send assert self.c.get_entropy_ticket(0) == [utils.big_endian_to_int(tester.a1), 1, 1, COW_HASH_1 - 2 ** 256] assert self.c.get_entropy(0, sender=tester.k1) == [1, COW_HASH_1 - 2 ** 256] # ready
def loglist_encoder(loglist): """Encode a list of log""" l = [] if len(loglist) > 0 and loglist[0] is None: assert all(element is None for element in l) return l result = [] for log, index, block in loglist: result.append({ 'logIndex': quantity_encoder(index), 'transactionIndex': None, 'transactionHash': None, 'blockHash': data_encoder(block.hash), 'blockNumber': quantity_encoder(block.number), 'address': address_encoder(log.address), 'data': data_encoder(log.data), 'topics': [data_encoder(int_to_big_endian(topic), 32) for topic in log.topics] }) return result
def encode_loglist(loglist): """Encode a list of log""" # l = [] # if len(loglist) > 0 and loglist[0] is None: # assert all(element is None for element in l) # return l result = [] for l in loglist: result.append({ 'logIndex': encode_number(l['log_idx']), 'transactionIndex': encode_number(l['tx_idx']), 'transactionHash': encode_data(l['txhash']), 'blockHash': encode_data(l['block'].hash), 'blockNumber': encode_number(l['block'].number), 'address': encode_address(l['log'].address), 'data': encode_data(l['log'].data), 'topics': [encode_data(int_to_big_endian(topic), 32) for topic in l['log'].topics], 'type': 'pending' if l['pending'] else 'mined' }) return result
def test_lottery_payer_deposit(self): self.deploy_contract() payer = tester.a6 w0 = self.state.block.get_balance(payer) lottery = Lottery({tester.a1: 33 * eth, tester.a2: 17 * eth}) g1 = self.lottery_init(6, lottery) v = 50 * eth deposit = v / 10 assert self.lottery_get_value(lottery) == v assert self.lottery_get_maturity(lottery) == 10 b = self.state.block.get_balance(payer) - w0 assert b == -(v + deposit + g1) self.state.mine(11) expected_rand = self.state.block.get_parent().hash[-4:] self.state.mine(127) self.lottery_randomise(9, lottery) # Payer gets the deposit r = self.lottery_get_rand(lottery) r = zpad(int_to_big_endian(r), 4) assert r == expected_rand b = self.state.block.get_balance(payer) - w0 assert b == -(v + g1)