def ecrecover(msg, signature, address=None): """ Returns None on failure, returns the recovered address on success. If address is provided: Returns True if the recovered address matches it, otherwise False. """ rawhash = sha3(msg) if len(signature) >= 65: v = safe_ord(signature[64]) + 27 r = big_endian_to_int(signature[0:32]) s = big_endian_to_int(signature[32:64]) else: if address: return False else: return None pk = PublicKey(flags=ALL_FLAGS) pk.public_key = pk.ecdsa_recover( rawhash, pk.ecdsa_recoverable_deserialize( zpad(bytearray_to_bytestr(int_to_32bytearray(r)), 32) + zpad(bytearray_to_bytestr(int_to_32bytearray(s)), 32), v - 27), raw=True) pub = pk.serialize(compressed=False) recaddr = data_encoder(sha3(pub[1:])[-20:]) if address: if not address.startswith("0x"): recaddr = recaddr[2:] return recaddr == address return recaddr
def add_signature_to_transaction(tx, signature): if isinstance(tx, str): tx = decode_transaction(tx) encode_at_end = True else: encode_at_end = False if isinstance(signature, str): signature = data_decoder(signature) if hasattr(tx, 'v') and tx.v > 1: if tx.r == 0 and tx.s == 0: vee = 8 + tx.v * 2 else: raise Exception("transaction is already signed") else: vee = 0 tx.v = safe_ord(signature[64]) + 27 + vee tx.r = big_endian_to_int(signature[0:32]) tx.s = big_endian_to_int(signature[32:64]) if tx._cached_rlp: tx._cached_rlp = None if encode_at_end: return encode_transaction(tx) return tx
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 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 recover(self, rawhash): assert isinstance(self, EcdsaSignature) v, r, s = self if coincurve and hasattr(coincurve, "PublicKey"): try: pk = coincurve.PublicKey.from_signature_and_message( ''.join([r, s, ascii_chr(v - 27)]), rawhash, hasher=None, ) pub = pk.format(compressed=False)[1:] except BaseException: pub = b"\x00" * 64 else: r = big_endian_to_int(r) s = big_endian_to_int(s) result = ecdsa_raw_recover(rawhash, (v, r, s)) if result: x, y = result pub = encode_int32(x) + encode_int32(y) else: raise ValueError('Invalid VRS') assert len(pub) == 64 # Convert to Ethereum address return keccak_256(pub).digest()[12:]
def mk_test(b, e, m, execgas): encoded = mk_modexp_data(b, e, m) s = c.snapshot() x = c.contract(kode % (len(encoded) + 36, max(intlen(m), 1), max(intlen(m), 1)), language='viper') pre = tester.mk_state_test_prefill(c) try: o = x.foo( encoded, startgas=21000 + intrinsic_gas_of_data(x.translator.encode('foo', [encoded])) + execgas) if big_endian_to_int(o[:intlen(m)]) != (pow(b, e, m) if m else 0): raise Exception( "Mismatch! %d %d %d expected %d computed %d" % (b, e, m, pow(b, e, m), big_endian_to_int(o[:intlen(m)]))) print("Succeeded %d %d %d sg %d" % (b, e, m, execgas)) except tester.TransactionFailed: print('OOG %d %d %d sg %d' % (b, e, m, execgas)) o = tester.mk_state_test_postfill(c, pre) o2 = tester.mk_state_test_postfill(c, pre, filler_mode=True) assert new_statetest_utils.verify_state_test(o) c.revert(s) return o, o2
def test_ecrecover(): s = tester.state() c = s.abi_contract(ecrecover_code) priv = utils.sha3('some big long brainwallet password') pub = bitcoin.privtopub(priv) msghash = utils.sha3('the quick brown fox jumps over the lazy dog') pk = PrivateKey(priv, raw=True) signature = pk.ecdsa_recoverable_serialize( pk.ecdsa_sign_recoverable(msghash, raw=True)) signature = signature[0] + utils.bytearray_to_bytestr([signature[1]]) V = utils.safe_ord(signature[64]) + 27 R = big_endian_to_int(signature[0:32]) S = big_endian_to_int(signature[32:64]) assert bitcoin.ecdsa_raw_verify(msghash, (V, R, S), pub) addr = utils.big_endian_to_int( utils.sha3(bitcoin.encode_pubkey(pub, 'bin')[1:])[12:]) assert utils.big_endian_to_int(utils.privtoaddr(priv)) == addr result = c.test_ecrecover(utils.big_endian_to_int(msghash), V, R, S) assert result == addr
def _check_pow(header): number = big_endian_to_int(header[8]) difficulty = big_endian_to_int(header[7]) mixhash = header[13] nonce = header[14] mining_hash = sha3(rlp.encode(header[:13])) assert check_pow(number, mining_hash, mixhash, nonce, difficulty)
def sign(self, privkey): """Sign this with a private key""" if self.v: raise InvalidSignature("already signed") if privkey in (0, '', '\x00' * 32): raise InvalidSignature("Zero privkey cannot sign") rawhash = sha3( rlp.encode(self, self.__class__.exclude(['v', 'r', 's']))) if len(privkey) == 64: privkey = encode_privkey(privkey, 'bin') pk = PrivateKey(privkey, raw=True) signature = pk.ecdsa_recoverable_serialize( pk.ecdsa_sign_recoverable(rawhash, raw=True)) signature = signature[0] + chr(signature[1]) self.v = ord(signature[64]) + 27 self.r = big_endian_to_int(signature[0:32]) self.s = big_endian_to_int(signature[32:64]) self._sender = None return self
def decode_single(typ, data): base, sub, _ = typ if base == 'address': return encode_hex(data[12:]) elif base == 'hash': return data[32 - int(sub):] elif base == 'string' or base == 'bytes': if len(sub): return data[:int(sub)] else: l = big_endian_to_int(data[0:32]) return data[32:][:l] elif base == 'uint': return big_endian_to_int(data) elif base == 'int': o = big_endian_to_int(data) return (o - 2 ** int(sub)) if o >= 2 ** (int(sub) - 1) else o elif base == 'ureal': high, low = [int(x) for x in sub.split('x')] return big_endian_to_int(data) * 1.0 // 2 ** low elif base == 'real': high, low = [int(x) for x in sub.split('x')] o = big_endian_to_int(data) i = (o - 2 ** (high + low)) if o >= 2 ** (high + low - 1) else o return (i * 1.0 // 2 ** low) elif base == 'bool': return bool(int(encode_hex(data), 16))
def test_ecrecover(): s = tester.state() c = s.abi_contract(ecrecover_code) priv = utils.sha3('some big long brainwallet password') pub = bitcoin.privtopub(priv) msghash = utils.sha3('the quick brown fox jumps over the lazy dog') pk = PrivateKey(priv, raw=True) signature = pk.ecdsa_recoverable_serialize( pk.ecdsa_sign_recoverable(msghash, raw=True) ) signature = signature[0] + utils.bytearray_to_bytestr([signature[1]]) V = utils.safe_ord(signature[64]) + 27 R = big_endian_to_int(signature[0:32]) S = big_endian_to_int(signature[32:64]) assert bitcoin.ecdsa_raw_verify(msghash, (V, R, S), pub) addr = utils.big_endian_to_int(utils.sha3(bitcoin.encode_pubkey(pub, 'bin')[1:])[12:]) assert utils.big_endian_to_int(utils.privtoaddr(priv)) == addr result = c.test_ecrecover(utils.big_endian_to_int(msghash), V, R, S) assert result == addr
def ecrecover(msg, signature, address=None): """ Returns None on failure, returns the recovered address on success. If address is provided: Returns True if the recovered address matches it, otherwise False. """ rawhash = sha3(msg) if isinstance(signature, str): signature = data_decoder(signature) if len(signature) >= 65: v = safe_ord(signature[64]) r = big_endian_to_int(signature[0:32]) s = big_endian_to_int(signature[32:64]) else: if address: return False else: return None if v == 0 or v == 1: v += 27 pub = ecrecover_to_pub(rawhash, v, r, s) recaddr = data_encoder(sha3(pub)[-20:]) if address: if not address.startswith("0x"): recaddr = recaddr[2:] return recaddr == address return recaddr
def decode_single(typ, data): base, sub, _ = typ if base == 'address': return encode_hex(data[12:]) elif base == 'hash': return data[32 - int(sub):] elif base == 'string' or base == 'bytes': if len(sub): return data[:int(sub)] else: l = big_endian_to_int(data[0:32]) return data[32:][:l] elif base == 'uint': return big_endian_to_int(data) elif base == 'int': o = big_endian_to_int(data) return (o - 2**int(sub)) if o >= 2**(int(sub) - 1) else o elif base == 'ufixed': high, low = [int(x) for x in sub.split('x')] return big_endian_to_int(data) * 1.0 // 2**low elif base == 'fixed': high, low = [int(x) for x in sub.split('x')] o = big_endian_to_int(data) i = (o - 2**(high + low)) if o >= 2**(high + low - 1) else o return (i * 1.0 // 2**low) elif base == 'bool': return bool(int(encode_hex(data), 16))
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 state_from_genesis_declaration(genesis_data, env, block=None, allow_empties=False): if block: assert isinstance(block, Block) else: block = block_from_genesis_declaration(genesis_data, env) state = State(env=env) for addr, data in genesis_data["alloc"].items(): addr = normalize_address(addr) assert len(addr) == 20 if 'wei' in data: state.set_balance(addr, parse_as_int(data['wei'])) if 'balance' in data: state.set_balance(addr, parse_as_int(data['balance'])) if 'code' in data: state.set_code(addr, parse_as_bin(data['code'])) if 'nonce' in data: state.set_nonce(addr, parse_as_int(data['nonce'])) if 'storage' in data: for k, v in data['storage'].items(): state.set_storage_data(addr, big_endian_to_int(parse_as_bin(k)), big_endian_to_int(parse_as_bin(v))) get_consensus_strategy(state.config).initialize(state, block) state.commit(allow_empties=allow_empties) print('deleting %d' % len(state.deletes)) rdb = RefcountDB(state.db) for delete in state.deletes: rdb.delete(delete) block.header.state_root = state.trie.root_hash state.prev_headers=[block.header] return state
def consume_length_prefix(rlp, start): """Read a length prefix from an RLP string. :param rlp: the rlp string to read from :param start: the position at which to start reading :returns: a tuple ``(type, length, end)``, where ``type`` is either ``str`` or ``list`` depending on the type of the following payload, ``length`` is the length of the payload in bytes, and ``end`` is the position of the first payload byte in the rlp string """ b0 = safe_ord(rlp[start]) if b0 < 128: # single byte return (str, 1, start) elif b0 < 128 + 56: # short string return (str, b0 - 128, start + 1) elif b0 < 192: # long string ll = b0 - 128 - 56 + 1 l = big_endian_to_int(rlp[start + 1:start + 1 + ll]) return (str, l, start + 1 + ll) elif b0 < 192 + 56: # short list return (list, b0 - 192, start + 1) else: # long list ll = b0 - 192 - 56 + 1 l = big_endian_to_int(rlp[start + 1:start + 1 + ll]) return (list, l, start + 1 + ll)
def test_javascript_signatures(): # The zero address will cause `approve` to default to valid signatures zero_address = "0x0000000000000000000000000000000000000000" accounts = ["0x776ba14735ff84789320718cf0aa43e91f7a8ce1", "0x095ce4e4240fa66ff90282c26847456e3f3b5002"] # The address that will receive the transaction recipient = "0x776ba14735ff84789320718cf0aa43e91f7a8ce1" # These are the matching sigs to the accounts raw_sigs = [ "0x4a89507bf71749fb338ed13fba623a683d9ecab0fb9c389a4298525c043e38281a00ab65628bb18a382eb8c8b4fb4dae95ccc993cf49f617c60d8051180778601c", "0xc84fe5d2a600e033930e0cf73f26e78f4c65b134f9c9992f60f08ce0863abdbe0548a6e8aa2d952659f29c67106b59fdfcd64d67df03c1df620c70c85578ae701b" ] # Turns the raw sigs into sigs sigs = [(utils.big_endian_to_int(x[64:]), utils.big_endian_to_int(x[:32]), utils.big_endian_to_int(x[32:64])) for x in map(lambda z: utils.decode_hex(z[2:]), raw_sigs)] h = utils.sha3(utils.encode_int32(0) + b'\x00' * 12 + utils.decode_hex(recipient[2:]) + utils.encode_int32(25) + b'') h2 = utils.sha3(b"\x19Ethereum Signed Message:\n32" + h) # Check to make sure the signatures are valid assert '0x'+utils.encode_hex(utils.sha3(utils.ecrecover_to_pub(h2, sigs[0][0], sigs[0][1], sigs[0][2]))[12:]) == accounts[0] assert '0x'+utils.encode_hex(utils.sha3(utils.ecrecover_to_pub(h2, sigs[1][0], sigs[1][1], sigs[1][2]))[12:]) == accounts[1] # Set the owners to zero addresses x2 = t.s.contract(open('examples/wallet/wallet.v.py').read(), args=[accounts + [t.a3, zero_address, zero_address], 2], language='viper') t.s.tx(sender=t.k1, to=x2.address, value=10**17) # There's no need to pass in signatures because the owners are 0 addresses causing them to default to valid signatures assert x2.approve(0, recipient, 25, "", sigs + [[0, 0, 0]] * 3, value=25, sender=t.k1) print("Javascript signature tests passed")
def build_dao_header(config): return BlockHeader( prevhash=decode_hex( 'a218e2c611f21232d857e3c8cecdcdf1f65f25a4477f98f6f47e4063807f2308' ), uncles_hash=decode_hex( '1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347' ), coinbase=decode_hex('bcdfc35b86bedf72f0cda046a3c16829a2ef41d1'), state_root=decode_hex( 'c5e389416116e3696cce82ec4533cce33efccb24ce245ae9546a4b8f0d5e9a75' ), tx_list_root=decode_hex( '7701df8e07169452554d14aadd7bfa256d4a1d0355c1d174ab373e3e2d0a3743' ), receipts_root=decode_hex( '26cf9d9422e9dd95aedc7914db690b92bab6902f5221d62694a2fa5d065f534b' ), bloom=int256.deserialize( decode_hex( '00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000' ), ), difficulty=big_endian_to_int(decode_hex('38c3bf2616aa')), number=config['DAO_FORK_BLKNUM'], gas_limit=big_endian_to_int(decode_hex('47e7c0')), gas_used=big_endian_to_int(decode_hex('014820')), timestamp=big_endian_to_int(decode_hex('578f7aa8')), extra_data=config['DAO_FORK_BLKEXTRA'], mixhash=decode_hex( '5b5acbf4bf305f948bd7be176047b20623e1417f75597341a059729165b92397' ), nonce=decode_hex('bede87201de42426'))
def test_request_multiple_entropy_tickets_different_senders(self): assert self.c.request_entropy(value=self.ENTROPY_COST) == [0, 4] assert self.c.request_entropy(sender=tester.k1, value=self.ENTROPY_COST) == [1, 4] assert self.c.get_entropy_ticket(0) == [utils.big_endian_to_int(tester.a0), 0, self.s.block.number + 1, 0] assert self.c.get_entropy_ticket(1) == [utils.big_endian_to_int(tester.a1), 0, self.s.block.number + 1, 0] assert self.c.get_block(self.s.block.number + 1) == [0, 0, 0, 2]
def _db_encode_type(cls, value_type, val): if value_type in ('string', 'bytes', 'binary', 'address'): assert len(val) <= 32 assert isinstance(val, bytes) return big_endian_to_int(val) data = abi.encode_abi([value_type], [val]) assert len(data) <= 32 return big_endian_to_int(data)
def get_tx_position(self, tx): if not isinstance(tx, (str, bytes)): tx = tx.hash if b'txindex:' + tx in self.db: data = rlp.decode(self.db.get(b'txindex:' + tx)) return big_endian_to_int(data[0]), big_endian_to_int(data[1]) else: return None
def test_request_entropy_target_depends_on_block_number(self): self.s.mine() assert self.c.request_entropy(value=self.ENTROPY_COST) == [0, 5] assert self.c.get_entropy_ticket(0) == [utils.big_endian_to_int(tester.a0), 0, self.s.block.number + 1, 0] self.s.mine(10) assert self.c.request_entropy(value=self.ENTROPY_COST) == [1, 15] assert self.c.get_entropy_ticket(1) == [utils.big_endian_to_int(tester.a0), 0, self.s.block.number + 1, 0]
def sign(data: bytes, private_key_seed_ascii: str, hash_function=bitcoin.bin_sha256): """Sign data using Ethereum private key. :param private_key_seed_ascii: Private key seed as ASCII string """ msghash = hash_function(data) priv = utils.sha3(private_key_seed_ascii) pub = bitcoin.privtopub(priv) # Based on ethereum/tesrt_contracts.py test_ecrecover pk = PrivateKey(priv, raw=True) signature = pk.ecdsa_recoverable_serialize( pk.ecdsa_sign_recoverable(msghash, raw=True)) signature = signature[0] + utils.bytearray_to_bytestr([signature[1]]) # Enforce non-tightly-packed arguments for signing # (0x00 left pad) # https://github.com/ethereum/web3.py/issues/466 v = utils.safe_ord(signature[64]) + 27 r_bytes = signature[0:32] r_bytes = pad_left(r_bytes, 32, b"\0") r = big_endian_to_int(r_bytes) s_bytes = signature[32:64] s_bytes = pad_left(s_bytes, 32, b"\0") s = big_endian_to_int(s_bytes) # Make sure we use bytes data and zero padding stays # good across different systems r_hex = binascii.hexlify(r_bytes).decode("ascii") s_hex = binascii.hexlify(s_bytes).decode("ascii") # Convert to Etheruem address format addr = utils.big_endian_to_int( utils.sha3(bitcoin.encode_pubkey(pub, 'bin')[1:])[12:]) # Return various bits about signing so it's easier to debug return { "signature": signature, "v": v, "r": r, "s": s, "r_bytes": r_bytes, "s_bytes": s_bytes, "r_hex": "0x" + r_hex, "s_hex": "0x" + s_hex, "address_bitcoin": addr, "address_ethereum": get_ethereum_address_from_private_key(priv), "public_key": pub, "hash": msghash, "payload": binascii.hexlify(bytes([v] + list(r_bytes) + list(s_bytes, ))) }
def sign_eth(rawhash, priv): pk = PrivateKey(priv, raw=True) signature = pk.ecdsa_recoverable_serialize( pk.ecdsa_sign_recoverable(rawhash, raw=True)) signature = signature[0] + utils.bytearray_to_bytestr([signature[1]]) v = utils.safe_ord(signature[64]) + 27 r = utils.big_endian_to_int(signature[0:32]) s = utils.big_endian_to_int(signature[32:64]) return (v, r, s)
def read_account(self): rlpdata = self.chain.storage.get(self.address) if not rlpdata: self.write_account(0, 0) return self.read_account() nonce, balance, s, c = rlp.decode(rlpdata) nonce = big_endian_to_int(nonce) balance = big_endian_to_int(balance) return nonce, balance
def from_snapshot(cls, snapshot_data, env, executing_on_head=False): state = State(env=env) if "alloc" in snapshot_data: for addr, data in snapshot_data["alloc"].items(): if len(addr) == 40: addr = decode_hex(addr) assert len(addr) == 20 if 'wei' in data: state.set_balance(addr, parse_as_int(data['wei'])) if 'balance' in data: state.set_balance(addr, parse_as_int(data['balance'])) if 'code' in data: state.set_code(addr, parse_as_bin(data['code'])) if 'nonce' in data: state.set_nonce(addr, parse_as_int(data['nonce'])) if 'storage' in data: for k, v in data['storage'].items(): state.set_storage_data( addr, big_endian_to_int(parse_as_bin(k)), big_endian_to_int(parse_as_bin(v))) elif "state_root" in snapshot_data: state.trie.root_hash = parse_as_bin(snapshot_data["state_root"]) else: raise Exception( "Must specify either alloc or state root parameter") for k, default in STATE_DEFAULTS.items(): default = copy.copy(default) v = snapshot_data[k] if k in snapshot_data else None if is_numeric(default): setattr(state, k, parse_as_int(v) if k in snapshot_data else default) elif is_string(default): setattr(state, k, parse_as_bin(v) if k in snapshot_data else default) elif k == 'prev_headers': if k in snapshot_data: headers = [dict_to_prev_header(h) for h in v] else: headers = default setattr(state, k, headers) elif k == 'recent_uncles': if k in snapshot_data: uncles = {} for height, _uncles in v.items(): uncles[int(height)] = [] for uncle in _uncles: uncles[int(height)].append(parse_as_bin(uncle)) else: uncles = default setattr(state, k, uncles) if executing_on_head: state.executing_on_head = True state.commit() state.changed = {} return state
def sign_eth(rawhash, priv): pk = PrivateKey(priv, raw=True) signature = pk.ecdsa_recoverable_serialize( pk.ecdsa_sign_recoverable(rawhash, raw=True) ) signature = signature[0] + utils.bytearray_to_bytestr([signature[1]]) v = utils.safe_ord(signature[64]) + 27 r = utils.big_endian_to_int(signature[0:32]) s = utils.big_endian_to_int(signature[32:64]) return (v, r, s)
def profile_vm_test(params, _): pre = params['pre'] exek = params['exec'] env = params['env'] index = 0 # setup env blkh = block.BlockHeader(prevhash=codecs.decode(env['previousHash'], 'hex'), number=int(env['currentNumber']), coinbase=env['currentCoinbase'], difficulty=int(env['currentDifficulty']), gas_limit=int(env['currentGasLimit']), timestamp=int(env['currentTimestamp'])) block.Block(blkh, db=_env) state = State(env=_env, block_number=int(env['currentNumber']), block_coinbase=env['currentCoinbase'], block_difficulty=int(env['currentDifficulty']), gas_limit=int(env['currentGasLimit']), timestamp=int(env['currentTimestamp'])) # setup state for address, h in pre.items(): state.set_nonce(address, int(h['nonce'])) state.set_balance(address, int(h['balance'])) state.set_balance("cd1722f3947def4cf144679da39c4c32bdc35681", int(h['balance'])) state.set_code(address, codecs.decode(h['code'][2:], 'hex')) for k, v in h['storage'].items(): state.set_storage_data( address, u.big_endian_to_int(codecs.decode(k[2:], 'hex')), u.big_endian_to_int(codecs.decode(v[2:], 'hex'))) for curr_row in range(1, num_tx + 1, 1): state = State(env=_env, block_number=int(env['currentNumber']), block_coinbase=env['currentCoinbase'], block_difficulty=int(env['currentDifficulty']), gas_limit=int(env['currentGasLimit']), timestamp=int(env['currentTimestamp'])) nonce = 0 conBench(state, exek, curr_row, nonce, index) nonce = nonce + 1 index += 1 df = pd.DataFrame(result) df.columns = [ 'TX', 'Type', 'Used gas', 'minTime', 'maxTime', 'avgTime', 'medTime', 'stdevTime', 'CI(95%)' ] writer = pd.ExcelWriter('BenchmarkResults8U.xlsx', engine='xlsxwriter') df.to_excel(writer, sheet_name='Set8') writer.save()
def get_transaction(self, tx): if not isinstance(tx, (str, bytes)): tx = tx.hash if b'txindex:' + tx in self.db: data = rlp.decode(self.db.get(b'txindex:' + tx)) blk, index = self.get_block_by_number(big_endian_to_int( data[0])), big_endian_to_int(data[1]) tx = blk.transactions[index] return tx, blk, index else: return None
def verify(msghash: bytes, signature, public_key): """Verify that data has been signed with Etheruem private key. :param signature: :return: """ V = utils.safe_ord(signature[64]) + 27 R = big_endian_to_int(signature[0:32]) S = big_endian_to_int(signature[32:64]) return bitcoin.ecdsa_raw_verify(msghash, (V, R, S), public_key)
def test_ecrecover(self): priv = b.sha256('some big long brainwallet password') pub = b.privtopub(priv) msghash = b.sha256('the quick brown fox jumps over the lazy dog') V, R, S = b.ecdsa_raw_sign(msghash, priv) assert b.ecdsa_raw_verify(msghash, (V, R, S), pub) addr = utils.sha3(b.encode_pubkey(pub, 'bin')[1:])[12:] assert utils.privtoaddr(priv) == addr result = self.c.test_ecrecover(utils.big_endian_to_int(msghash.decode('hex')), V, R, S) assert result == utils.big_endian_to_int(addr)
def test_change_ownership_with_invalid_address_should_fail(self): # Should succeed with valid address assert self.c.change_ownership(tester.a1, sender=tester.k0) == 1 assert self.s.block.get_storage_data(self.c.address, 0) == utils.big_endian_to_int(tester.a1) # Should then fail with invalid address assert self.c.change_ownership(0, sender=tester.k1) == 0 assert self.c.change_ownership(-1000, sender=tester.k1) == 0 assert self.s.block.get_storage_data(self.c.address, 0) == utils.big_endian_to_int(tester.a1) # Should succeed again with valid address assert self.c.change_ownership(tester.a0, sender=tester.k1) == 1 assert self.s.block.get_storage_data(self.c.address, 0) == utils.big_endian_to_int(tester.a0)
def test_ecrecover(self): priv = b.sha256('some big long brainwallet password') pub = b.privtopub(priv) msghash = b.sha256('the quick brown fox jumps over the lazy dog') V, R, S = b.ecdsa_raw_sign(msghash, priv) assert b.ecdsa_raw_verify(msghash, (V, R, S), pub) addr = utils.sha3(b.encode_pubkey(pub, 'bin')[1:])[12:] assert utils.privtoaddr(priv) == addr result = self.c.test_ecrecover( utils.big_endian_to_int(msghash.decode('hex')), V, R, S) assert result == utils.big_endian_to_int(addr)
def read_update(self, update_counter): "first update has update_counter=1" # assert update_counter > 0 self.journal_index.seek((update_counter - 1) * 4) log_end_pos = big_endian_to_int(self.journal_index.read(4)) self.journal.seek(log_end_pos - 2) log_len = big_endian_to_int(self.journal.read(2)) self.journal.seek(-log_len, 1) state_digest = self.journal.read(32) # state_digest after change log = self.journal.read(-32 + log_len - 2) key, value, prev_update_counter = rlp.decode(log) prev_update_counter = big_endian_to_int(prev_update_counter) return dict(key=key, value=value, prev_update_counter=prev_update_counter, state_digest=state_digest, log_hash=sha3(log), update_counter=update_counter)
def newFilter(self, filter_dict): log.debug('in newFilter', filter_dict=filter_dict) if not isinstance(filter_dict, dict): raise BadRequestError('Filter must be an object') address = filter_dict.get('address', None) if is_string(address): addresses = [address_decoder(address)] elif isinstance(address, Iterable): addresses = [address_decoder(addr) for addr in address] elif address is None: addresses = None else: raise JSONRPCInvalidParamsError('Parameter must be address or list of addresses') if 'topics' in filter_dict: topics = [] for topic in filter_dict['topics']: if topic is not None: log.debug('with topic', topic=topic) log.debug('decoded', topic=data_decoder(topic)) log.debug('int', topic=big_endian_to_int(data_decoder(topic))) topics.append(big_endian_to_int(data_decoder(topic))) else: topics.append(None) else: topics = None fromBlock = filter_dict.get('fromBlock') toBlock = filter_dict.get('toBlock') or 'latest' if toBlock in ('latest', 'pending'): assert fromBlock in (None, toBlock) , 'latest/pending does not support ranges' filter_ = Filter(self.chain.chain, blocks=[], addresses=addresses, topics=topics, pending=bool(toBlock==b'pending'), latest=bool(toBlock==b'latest')) else: assert fromBlock not in ('latest', 'pending') b0 = self.json_rpc_server.get_block(block_id_decoder(fromBlock)) b1 = self.json_rpc_server.get_block(block_id_decoder(toBlock)) if b1.number < b0.number: raise BadRequestError('fromBlock must be prior or equal to toBlock') blocks = [b1] while blocks[-1] != b0: blocks.append(blocks[-1].get_parent()) filter_ = Filter(self.chain.chain, blocks=list( reversed(blocks)), addresses=addresses, topics=topics) self.filters[self.next_id] = filter_ self.next_id += 1 return self.next_id - 1
def dec(typ, arg): base, sub, arrlist = typ sz = get_size(typ) # Dynamic-sized strings are encoded as <len(str)> + <str> if base in ('string', 'bytes') and not sub: L = big_endian_to_int(arg[:32]) assert len(arg[32:]) == ceil32( L ), "Wrong data size for string/bytes object: expected %d actual %d" % ( ceil32(L), len(arg[32:])) return arg[32:][:L] # Dynamic-sized arrays elif sz is None: L = big_endian_to_int(arg[:32]) subtyp = base, sub, arrlist[:-1] subsize = get_size(subtyp) # If children are dynamic, use the head/tail mechanism. Fortunately, # here the code is simpler since we do not have to worry about # mixed dynamic and static children, as we do in the top-level multi-arg # case if subsize is None: assert len(arg) >= 32 + 32 * L, "Not enough data for head" start_positions = [ big_endian_to_int(arg[32 + 32 * i:64 + 32 * i]) for i in range(L) ] + [len(arg)] outs = [ arg[start_positions[i]:start_positions[i + 1]] for i in range(L) ] return [dec(subtyp, out) for out in outs] # If children are static, then grab the data slice for each one and # sequentially decode them manually else: return [ dec(subtyp, arg[32 + subsize * i:32 + subsize * (i + 1)]) for i in range(L) ] # Static-sized arrays: decode piece-by-piece elif len(arrlist): L = arrlist[-1][0] subtyp = base, sub, arrlist[:-1] subsize = get_size(subtyp) return [ dec(subtyp, arg[subsize * i:subsize * (i + 1)]) for i in range(L) ] else: return decode_single(typ, arg)
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 read(self, k): k = k % self.storage_slots r = self.chain.storage.get(self.address+str(k)) if not r: # create storage self.store(k, 1) return self.read(k) return big_endian_to_int(r)
def hash_array(arr): o = '' for x in arr: if isinstance(x, (int, long)): x = utils.zpad(utils.encode_int(x), 32) o += x return utils.big_endian_to_int(utils.sha3(o))
def test_request_entropy(self): assert self.c.request_entropy(value=self.ENTROPY_COST) == [0, 4] assert self.c.get_entropy_ticket(0) == [utils.big_endian_to_int(tester.a0), 0, self.s.block.number + 1, 0] assert self.c.get_entropy(0) == [0, 0] # pending assert self.c.get_block(self.s.block.number + 1) == [0, 0, 0, 1] assert self.s.block.get_balance(tester.a0) == 10 ** 24 - self.ENTROPY_COST
def test_returnten(): s = tester.state() open(filename, 'w').write(mul2_code) c = s.contract(returnten_code) o1 = s.send(tester.k0, c, 0) os.remove(filename) assert utils.big_endian_to_int(o1) == 10
def test_send_with_invalid_recipient_should_not_overwrite_internal_settings(self): # assert self.c.set_exchange(0xdeadbeef, 999) assert self.c.sendCoin(1, 0) == 0 assert self.s.block.get_storage_data(self.c.address, 0) == utils.big_endian_to_int(tester.a0) assert self.c.sendCoin(1, -1000) == 0
def test_callcode(): s = tester.state() open(filename3, 'w').write(add1_code) c = s.contract(callcode_test_code) o1 = s.send(tester.k0, c, 0) os.remove(filename3) assert utils.big_endian_to_int(o1) == 64
def __init__(self, ctx, *args): assert isinstance(ctx, NativeABIContract) assert len(self.args) == len(args), \ "%s called with wrong number of args" % self.__class__.__name__ # topic0 sha3(EventName + signature) topics = [self.event_id()] indexed_args = [] non_indexed_args = [] for val, arg in zip(args, self.args): if arg['indexed']: indexed_args.append((arg['type'], val)) else: non_indexed_args.append((arg['type'], val)) assert len(indexed_args) <= 3 # topics 1-n for typ, val in indexed_args: topics.append(big_endian_to_int(abi.encode_abi([typ], [val]))) # remaining non indexed data data = abi.encode_abi([a[0] for a in non_indexed_args], [a[1] for a in non_indexed_args]) # add log ctx._ext.log(ctx.address, topics, data)
def rollback(self, update_counter, verify=False): """ rollback to the state after update_counter based on the local journal In practice this file based rollback should not be used, but instead updates for young blocks which are probably not final yet should be held in memory """ # read log backwards jr = JournalReader(self.db) for uc in reversed(range(update_counter + 1, self.update_counter+1)): u = jr.read_update(uc) key = u['key'] # update with old value prev_uc = u['prev_update_counter'] if prev_uc > 0: v = jr.read_update(prev_uc)['value'] self.db.put(key, v) else: self.db.delete(key) # read state before the update we reverted if uc > 1: state_digest = jr.read_update(uc-1)['state_digest'] assert sha3(state_digest, u['log_hash']) == u['state_digest'] self.state_digest = state_digest else: self.state_digest = self.empty_state_digest # truncate the logfile and index self.journal_index.seek((update_counter - 1) * 4) log_end_pos = big_endian_to_int(self.journal_index.read(4)) self.journal_index.truncate() self.journal.seek(log_end_pos) self.journal.truncate()
def newFilter(self, filter_dict): if not isinstance(filter_dict, dict): raise BadRequestError('Filter must be an object') b0 = self.json_rpc_server.get_block( block_id_decoder(filter_dict.get('fromBlock', 'latest'))) b1 = self.json_rpc_server.get_block( block_id_decoder(filter_dict.get('toBlock', 'latest'))) if b1.number < b0.number: raise BadRequestError('fromBlock must be prior or equal to toBlock') address = filter_dict.get('address', None) if is_string(address): addresses = [address_decoder(address)] elif isinstance(address, Iterable): addresses = [address_decoder(addr) for addr in address] elif address is None: addresses = None else: raise JSONRPCInvalidParamsError('Parameter must be address or list of addresses') if 'topics' in filter_dict: topics = [] for topic in filter_dict['topics']: if topic is not None: topics.append(big_endian_to_int(data_decoder(topic))) else: topics.append(None) else: topics = None blocks = [b1] while blocks[-1] != b0: blocks.append(blocks[-1].get_parent()) filter_ = Filter(self.chain.chain, reversed(blocks), addresses, topics) self.filters[self.next_id] = filter_ self.next_id += 1 return self.next_id - 1
def test_initialize(self, block=None): # NameReg Alice ans = self.namereg.register(self.ALICE['address'], "Alice") assert ans == SUCCESS assert self._storage( self.namereg, "0x" + self.ALICE['address']) == "0x" + "Alice".encode('hex') assert self.namereg.getname( self.ALICE['address']) == utils.big_endian_to_int("Alice") # NameReg EtherEx ans = self.namereg.register(self.contract.address, "EtherEx") assert ans == SUCCESS assert self._storage(self.namereg, "0x" + self.contract.address.encode('hex') ) == "0x" + "EtherEx".encode('hex') # NameReg ETX ans = self.namereg.register(self.etx_contract.address, "ETX") assert ans == SUCCESS assert self._storage(self.namereg, "0x" + self.etx_contract.address.encode('hex') ) == "0x" + "ETX".encode('hex') # Register ETX ans = self.contract.add_market("ETX", self.etx_contract.address, 5, 10**8, 10**18, 1, sender=self.ALICE['key']) assert ans == SUCCESS
def test_initialize(self, block=None): # NameReg Alice ans = self.namereg.register(self.ALICE['address'], "Alice") assert ans == SUCCESS assert self._storage(self.namereg, "0x" + self.ALICE['address']) == "0x" + "Alice".encode('hex') assert self.namereg.getname(self.ALICE['address']) == utils.big_endian_to_int("Alice") # NameReg EtherEx ans = self.namereg.register(self.contract.address, "EtherEx") assert ans == SUCCESS assert self._storage(self.namereg, "0x" + self.contract.address.encode('hex')) == "0x" + "EtherEx".encode('hex') # NameReg ETX ans = self.namereg.register(self.etx_contract.address, "ETX") assert ans == SUCCESS assert self._storage(self.namereg, "0x" + self.etx_contract.address.encode('hex')) == "0x" + "ETX".encode('hex') # Register ETX ans = self.contract.add_market( "ETX", self.etx_contract.address, 5, 10 ** 8, 10 ** 18, 1, sender=self.ALICE['key']) assert ans == SUCCESS
def test_ecrecover(): s = tester.state() c = s.abi_contract(ecrecover_code) priv = encode_hex(utils.sha3('some big long brainwallet password')) pub = bitcoin.privtopub(priv) msghash = encode_hex(utils.sha3('the quick brown fox jumps over the lazy dog')) V, R, S = bitcoin.ecdsa_raw_sign(msghash, priv) assert bitcoin.ecdsa_raw_verify(msghash, (V, R, S), pub) addr = utils.big_endian_to_int(utils.sha3(bitcoin.encode_pubkey(pub, 'bin')[1:])[12:]) assert utils.big_endian_to_int(utils.privtoaddr(priv)) == addr result = c.test_ecrecover(utils.big_endian_to_int(decode_hex(msghash)), V, R, S) assert result == addr
def test_prevhashes(): s = tester.state() c = s.abi_contract(prevhashes_code) s.mine(7) # Hashes of last 14 blocks including existing one o1 = [x % 2 ** 256 for x in c.get_prevhashes(14)] # hash of self = 0, hash of blocks back to genesis block as is, hash of # blocks before genesis block = 0 t1 = [0] + [utils.big_endian_to_int(b.hash) for b in s.blocks[-2::-1]] \ + [0] * 6 assert o1 == t1 s.mine(256) # Test 256 limit: only 1 <= g <= 256 generation ancestors get hashes shown o2 = [x % 2 ** 256 for x in c.get_prevhashes(270)] t2 = [0] + [utils.big_endian_to_int(b.hash) for b in s.blocks[-2:-258:-1]] \ + [0] * 13 assert o2 == t2
def decint(n): if is_numeric(n) and n < 2**256 and n > -2**255: return n elif is_numeric(n): raise Exception("Number out of range: %r" % n) elif is_string(n) and len(n) == 40: return big_endian_to_int(decode_hex(n)) elif is_string(n) and len(n) <= 32: return big_endian_to_int(n) elif is_string(n) and len(n) > 32: raise Exception("String too long: %r" % n) elif n is True: return 1 elif n is False or n is None: return 0 else: raise Exception("Cannot encode integer: %r" % n)
def get_raw(self, key): "returns (value, update_counter)" try: v = self.db.get(key) val, counter = rlp.decode(v) counter = big_endian_to_int(counter) return val, counter except KeyError: return b'', 0
def abi_function_signature(self): """ Compute the bytes4 signature for the function. """ signature = "{func_name}({arg_types})".format( func_name=self.name, arg_types=','.join(self.input_types), ) return ethereum_utils.big_endian_to_int(ethereum_utils.sha3(signature)[:4])
def decode(self, name, data): # print 'out', utils.encode_hex(data) fdata = self.function_data[name] if fdata['is_unknown_type']: o = [utils.to_signed(utils.big_endian_to_int(data[i:i + 32])) for i in range(0, len(data), 32)] return [0 if not o else o[0] if len(o) == 1 else o] o = decode_abi(fdata['decode_types'], data) return o