示例#1
0
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
示例#2
0
def get_receipt_from_jsonrpc(response):
    if MODULE_DEBUG:
        print(response)
    assert response['jsonrpc'] == '2.0'
    assert 'id' in response
    assert 'result' in response
    receipt = response['result']
    logs = []
    for log in receipt['logs']:
        topics = [decode_int_from_hex(x) for x in log['topics']]
        logs.append(messages.Log(
            address = utils.normalize_address(log['address']),
            topics = topics,
            data = utils.decode_hex(log['data'])))
    # pre Byzantium returns a root
    if 'root' in receipt:
        return messages.Receipt(
            state_root = normalize_bytes(receipt['root']),
            gas_used = utils.parse_as_int(receipt['cumulativeGasUsed']),
            bloom = utils.parse_as_int(receipt['logsBloom']),
            logs = logs)
    receipt = messages.Receipt(
        state_root = (b'\x01' if receipt['status'] else b''),
        gas_used = utils.parse_as_int(receipt['cumulativeGasUsed']),
        bloom = utils.parse_as_int(receipt['logsBloom']),
        logs = logs)
    if MODULE_DEBUG:
        print("Rlp encoded receipt:")
        print(rec_hex(rlp.encode(receipt)))
    return receipt
示例#3
0
def block_header(block_dict: dict):
    b = block.BlockHeader(
        normalize_bytes(block_dict["parentHash"]),
        normalize_bytes(block_dict["sha3Uncles"]),
        utils.normalize_address(block_dict["miner"]),
        normalize_bytes(block_dict["stateRoot"]),
        normalize_bytes(block_dict["transactionsRoot"]),
        normalize_bytes(block_dict["receiptsRoot"]),
        utils.bytes_to_int(normalize_bytes(block_dict["logsBloom"])),
        utils.parse_as_int(block_dict['difficulty']),
        utils.parse_as_int(block_dict['number']),
        utils.parse_as_int(block_dict['gasLimit']),
        utils.parse_as_int(block_dict['gasUsed']),
        utils.parse_as_int(block_dict['timestamp']),
        normalize_bytes(block_dict["extraData"]),
        normalize_bytes(block_dict["mixHash"]),
        normalize_bytes(block_dict["nonce"]),
    )
    if normalize_bytes(block_dict["hash"]) != b.hash:
        raise ValueError(
            """Blockhash does not match.
            Received invalid block header? {} vs {}""".format(
                str(normalize_bytes(block_dict["hash"])),
                str(b.hash)))
    return b
示例#4
0
def dict_to_prev_header(h):
    return FakeHeader(hash=parse_as_bin(h['hash']),
                      number=parse_as_int(h['number']),
                      timestamp=parse_as_int(h['timestamp']),
                      difficulty=parse_as_int(h['difficulty']),
                      gas_used=parse_as_int(h.get('gas_used', '0')),
                      gas_limit=parse_as_int(h['gas_limit']),
                      uncles_hash=parse_as_bin(h.get('uncles_hash', '0x' + encode_hex(BLANK_UNCLES_HASH))))
示例#5
0
 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
示例#6
0
    def help_test_entire_block(self, path_to_jsonrpc_response):
        PRESENT = self.verifier_contract.TX_PROOF_RESULT_PRESENT()
        ABSENT = self.verifier_contract.TX_PROOF_RESULT_ABSENT()
        with open(path_to_jsonrpc_response, 'r') as f:
            jsonrpc = json.load(f)
        block_dict = jsonrpc['result']
        for i in range(len(block_dict['transactions']) + 20):
            proof_blob = proveth.generate_proof_blob_from_jsonrpc_response(
                jsonrpc, i)
            result, index, nonce, gas_price, gas, to, value, data, v, r, s, contract_creation = self.verifier_contract.txProof(
                utils.decode_hex(block_dict['hash']),
                proof_blob,
                startgas=10**7)
            print(i)
            present = i < len(block_dict['transactions'])
            self.assertEqual(result, PRESENT if present else ABSENT)
            self.assertEqual(index, i)
            if present:

                self.assertEqual(
                    nonce,
                    utils.parse_as_int(block_dict['transactions'][i]['nonce']))
                self.assertEqual(
                    gas_price,
                    utils.parse_as_int(
                        block_dict['transactions'][i]['gasPrice']))
                self.assertEqual(
                    gas,
                    utils.parse_as_int(block_dict['transactions'][i]['gas']))
                # contract creation corner case
                if utils.normalize_address(block_dict['transactions'][i]['to']
                                           or '',
                                           allow_blank=True) == b'':
                    self.assertEqual(
                        utils.normalize_address(to),
                        utils.normalize_address(
                            "0x0000000000000000000000000000000000000000"))
                    self.assertEqual(utils.parse_as_int(contract_creation), 1)
                else:
                    self.assertEqual(
                        utils.normalize_address(to),
                        utils.normalize_address(
                            block_dict['transactions'][i]['to']))
                    self.assertEqual(utils.parse_as_int(contract_creation), 0)
                self.assertEqual(
                    value,
                    utils.parse_as_int(block_dict['transactions'][i]['value']))
                self.assertEqual(
                    data,
                    utils.decode_hex(block_dict['transactions'][i]['input']))
                self.assertEqual(
                    v, utils.parse_as_int(block_dict['transactions'][i]['v']))
                self.assertEqual(
                    r, utils.parse_as_int(block_dict['transactions'][i]['r']))
                self.assertEqual(
                    s, utils.parse_as_int(block_dict['transactions'][i]['s']))
            if i > 0 and i % 100 == 0:
                self.chain.mine()
示例#7
0
def block_from_genesis_declaration(genesis_data, env):
    h = BlockHeader(nonce=parse_as_bin(genesis_data["nonce"]),
                    difficulty=parse_as_int(genesis_data["difficulty"]),
                    mixhash=parse_as_bin(genesis_data.get("mixhash", genesis_data.get("mixHash", "0"*64))),
                    coinbase=parse_as_bin(genesis_data["coinbase"]),
                    bloom=parse_as_int(genesis_data.get("bloom", "0")),
                    timestamp=parse_as_int(genesis_data["timestamp"]),
                    prevhash=parse_as_bin(genesis_data["parentHash"]),
                    extra_data=parse_as_bin(genesis_data["extraData"]),
                    gas_used=parse_as_int(genesis_data.get("gasUsed", "0")),
                    gas_limit=parse_as_int(genesis_data["gasLimit"]))
    return Block(h, [], [])
示例#8
0
def transaction(tx_dict: dict) -> transactions.Transaction:
    t = transactions.Transaction(
        utils.parse_as_int(tx_dict['nonce']),
        utils.parse_as_int(tx_dict['gasPrice']),
        utils.parse_as_int(tx_dict['gas']),
        normalize_bytes(tx_dict['to'] or ''),
        utils.parse_as_int(tx_dict['value']),
        utils.decode_hex(tx_dict['input']),
        utils.parse_as_int(tx_dict['v']),
        utils.bytes_to_int(normalize_bytes(tx_dict['r'])),
        utils.bytes_to_int(normalize_bytes(tx_dict['s'])),
    )
    if normalize_bytes(tx_dict['hash']) != t.hash:
        raise ValueError(
            "Tx hash does not match. Received invalid transaction?")
    return t
示例#9
0
 def rlp_transaction(tx_dict: dict):
     t = transactions.Transaction(
         utils.parse_as_int(tx_dict['nonce']),
         utils.parse_as_int(tx_dict['gasPrice']),
         utils.parse_as_int(tx_dict['gas']),
         normalize_bytes(tx_dict['to'] or ''),
         utils.parse_as_int(tx_dict['value']),
         utils.decode_hex(tx_dict['input']),
         utils.parse_as_int(tx_dict['v']),
         utils.bytes_to_int(normalize_bytes(tx_dict['r'])),
         utils.bytes_to_int(normalize_bytes(tx_dict['s'])),
     )
     if normalize_bytes(tx_dict['hash']) != t.hash:
         print("False transaction hash")
         return None
     return rlp.encode(t)
示例#10
0
 def verify_transaction(self, tx_hash, swap_id, initial_addr, target_addr, swap_money):
     target_tx = self.web3.eth.getTransaction(tx_hash)
     if target_tx is None:
         return False
     print(target_tx)
     if target_tx["from"].lower() != initial_addr.lower():
         return False
     if target_tx["to"].lower() != target_addr.lower():
         return False
     if target_tx["value"] != int(swap_money):
         return False
     if swap_id == "":
         if target_tx["input"] != "0x":
             return False
     else:
         if int(target_tx["input"], 0) != int(swap_id):
             return False
     block_info = self.web3.eth.getBlock(target_tx.blockHash, True)
     # verify the block hash
     if not self.verify_block(block_info):
         return False
     # verify the following 15 block hash
     block_num = utils.parse_as_int(block_info["number"])
     parent_block_hash = normalize_bytes(block_info.hash)
     for i in range(1, 15):
         temp_block_info = self.web3.eth.getBlock(block_num + i)
         cur_block_parent_hash = normalize_bytes(temp_block_info["parentHash"])
         if parent_block_hash != cur_block_parent_hash:
             return False
         parent_block_hash = normalize_bytes(temp_block_info.hash)
         self.verify_block(temp_block_info)
     # verify the transaction
     if not self.verify_transaction_hash(block_info, tx_hash):
         return False
     return True
示例#11
0
def generate_proof_blob(block_dict, tx_index):
    header = block_header(block_dict)

    mpt = HexaryTrie(db={})
    for tx_dict in block_dict["transactions"]:
        key = rlp.encode(utils.parse_as_int(tx_dict['transactionIndex']))
        mpt.set(key, rlp_transaction(tx_dict))

    if mpt.root_hash != normalize_bytes(block_dict['transactionsRoot']):
        raise ValueError(
            "Tx trie root hash does not match. Calculated: {} Sent: {}".format(
                mpt.root_hash.hex(),
                normalize_bytes(block_dict['transactionsRoot']).hex()))

    mpt_key_nibbles = bytes_to_nibbles(rlp.encode(tx_index))
    mpt_path, stack_indexes, stack = generate_proof(mpt, mpt_key_nibbles)

    proof_blob = rlp.encode([
        1,  # proof_type
        header,
        tx_index,
        bytes(mpt_path),
        bytes(stack_indexes),
        stack,
    ])
    return proof_blob
示例#12
0
 def verify_block(block_info):
     # verify the difficulty
     if utils.parse_as_int(block_info['difficulty']) < 10000000:
         return False
     if int(normalize_bytes(block_info["nonce"]).hex(), 16) * utils.parse_as_int(block_info['difficulty']) \
             > pow(2, 256):
         return False
     # get block header from block info
     header = block.BlockHeader(
         normalize_bytes(block_info["parentHash"]),
         normalize_bytes(block_info["sha3Uncles"]),
         utils.normalize_address(block_info["miner"]),
         normalize_bytes(block_info["stateRoot"]),
         normalize_bytes(block_info["transactionsRoot"]),
         normalize_bytes(block_info["receiptsRoot"]),
         utils.bytes_to_int(normalize_bytes(block_info["logsBloom"])),
         utils.parse_as_int(block_info['difficulty']),
         utils.parse_as_int(block_info['number']),
         utils.parse_as_int(block_info['gasLimit']),
         utils.parse_as_int(block_info['gasUsed']),
         utils.parse_as_int(block_info['timestamp']),
         normalize_bytes(block_info["extraData"]),
         normalize_bytes(block_info["mixHash"]),
         normalize_bytes(block_info["nonce"]),
     )
     # calculate the block hash
     # compare the block hash with trusted block hash
     if normalize_bytes(block_info.hash) != header.hash:
         return False
     else:
         return True
示例#13
0
def receipt(receipt_dict: dict) -> messages.Receipt:
    logs = [
        Log(utils.normalize_address(l['address']),
            [utils.parse_as_int(t.hex()) for t in l['topics']],
            utils.decode_hex(l['data'])) for l in receipt_dict['logs']
    ]
    root = receipt_dict.get('root')
    if root:
        state_root = normalize_bytes(root)
    elif receipt_dict['status'] == 1:
        state_root = bytes([1])
    else:
        state_root = bytes()
    r = messages.Receipt(
        state_root,
        utils.parse_as_int(receipt_dict['cumulativeGasUsed']),
        utils.bytes_to_int(normalize_bytes(receipt_dict['logsBloom'])),
        logs,
    )
    return r
示例#14
0
 def verify_transaction_hash(self, block_info, tx_hash):
     txns = block_info.transactions
     tx_index = 0
     # generate the mpt
     mpt = HexaryTrie(db={})
     for tx_dict in txns:
         if tx_dict.hash == tx_hash:
             tx_index = tx_dict.transactionIndex
         key = rlp.encode(utils.parse_as_int(tx_dict['transactionIndex']))
         mpt.set(key, self.rlp_transaction(tx_dict))
     # verify the tx root
     if mpt.root_hash != normalize_bytes(block_info.transactionsRoot):
         return False
     # generate the proof
     mpt_key_nibbles = bytes_to_nibbles(rlp.encode(tx_index))
     proof = tuple(self.generate_proof(mpt, mpt_key_nibbles))
     if HexaryTrie.get_from_proof(mpt.root_hash, rlp.encode(utils.parse_as_int(tx_index)), proof) \
             != self.rlp_transaction(txns[tx_index]):
         return False
     return True
示例#15
0
def block_header(block_dict: dict) -> block.BlockHeader:
    b = block.BlockHeader(
        normalize_bytes(block_dict['parentHash']),
        normalize_bytes(block_dict['sha3Uncles']),
        utils.normalize_address(block_dict['miner']),
        normalize_bytes(block_dict['stateRoot']),
        normalize_bytes(block_dict['transactionsRoot']),
        normalize_bytes(block_dict['receiptsRoot']),
        utils.bytes_to_int(normalize_bytes(block_dict['logsBloom'])),
        utils.parse_as_int(block_dict['difficulty']),
        utils.parse_as_int(block_dict['number']),
        utils.parse_as_int(block_dict['gasLimit']),
        utils.parse_as_int(block_dict['gasUsed']),
        utils.parse_as_int(block_dict['timestamp']),
        normalize_bytes(block_dict['extraData']),
        normalize_bytes(block_dict['mixHash']),
        normalize_bytes(block_dict['nonce']),
    )
    if normalize_bytes(block_dict['hash']) != b.hash:
        raise ValueError(
            'Blockhash does not match. Received invalid block header?')
    return b
示例#16
0
def rlp_transaction(tx_dict: dict):
    t = transactions.Transaction(
        utils.parse_as_int(tx_dict['nonce']),
        utils.parse_as_int(tx_dict['gasPrice']),
        utils.parse_as_int(tx_dict['gas']),
        normalize_bytes(tx_dict['to'] or ''),
        utils.parse_as_int(tx_dict['value']),
        utils.decode_hex(tx_dict['input']),
        utils.parse_as_int(tx_dict['v']),
        utils.bytes_to_int(normalize_bytes(tx_dict['r'])),
        utils.bytes_to_int(normalize_bytes(tx_dict['s'])),
    )
    if normalize_bytes(tx_dict['hash']) != t.hash:
        raise ValueError(
            """Tx hash does not match. Received invalid transaction?
        hashes:         {} {}
        nonce:          {}
        gasPrice:       {}
        gas:            {}
        to:             {}
        value:          {}
        input:          {}
        v:              {}
        r:              {}
        s:              {}
        """.format(
                tx_dict['hash'],
                t.hash,
                utils.parse_as_int(tx_dict['nonce']),
                utils.parse_as_int(tx_dict['gasPrice']),
                utils.parse_as_int(tx_dict['gas']),
                normalize_bytes(tx_dict['to'] or ''),
                utils.parse_as_int(tx_dict['value']),
                utils.decode_hex(tx_dict['input']),
                utils.parse_as_int(tx_dict['v']),
                utils.bytes_to_int(normalize_bytes(tx_dict['r'])),
                utils.bytes_to_int(normalize_bytes(tx_dict['s'])),
            ))
    return rlp.encode(t)
示例#17
0
def generate_proof_blob(block_dict, tx_index):
    header = block_header(block_dict)

    mpt = HexaryTrie(db={})
    for tx_dict in block_dict["transactions"]:
        key = rlp.encode(utils.parse_as_int(tx_dict['transactionIndex']))
        mpt.set(key, rlp_transaction(tx_dict))

    if mpt.root_hash != normalize_bytes(block_dict['transactionsRoot']):
        raise ValueError(
            "Tx trie root hash does not match. Calculated: {} Sent: {}"
            .format(mpt.root_hash.hex(),
                    normalize_bytes(block_dict['transactionsRoot']).hex()))

    return construct_proof_from_mpt(mpt, header, tx_index, 1)
示例#18
0
def generate_proof_blob_receipt(block_dict, tx_index, url):
    header = block_header(block_dict)

    mpt = HexaryTrie(db={})
    for tx_dict in block_dict["transactions"]:
        key = rlp.encode(utils.parse_as_int(tx_dict['transactionIndex']))
        receipt = get_receipt(url, tx_dict['hash'])
        mpt.set(key, rlp.encode(receipt))

    if mpt.root_hash != normalize_bytes(block_dict['receiptsRoot']):
        if MODULE_DEBUG:
            print("mpt.root_hash " + str(utils.encode_hex(mpt.root_hash)))
            print("receiptRoot " +
                  str(normalize_bytes(utils.encode_hex(block_dict['receiptsRoot']))))
        raise ValueError("Block receiptRoot hash does not match.")

    return construct_proof_from_mpt(mpt, header, tx_index, 2)
示例#19
0
 def verify_transaction_exist(self, tx_hash):
     target_tx = self.web3.eth.getTransaction(tx_hash)
     block_info = self.web3.eth.getBlock(target_tx.blockHash, True)
     # verify the block hash
     if not self.verify_block(block_info):
         return False
     # verify the following 15 block hash
     block_num = utils.parse_as_int(block_info["number"])
     parent_block_hash = normalize_bytes(block_info.hash)
     for i in range(1, 15):
         temp_block_info = self.web3.eth.getBlock(block_num + i)
         cur_block_parent_hash = normalize_bytes(temp_block_info["parentHash"])
         if parent_block_hash != cur_block_parent_hash:
             return False
         parent_block_hash = normalize_bytes(temp_block_info.hash)
         self.verify_block(temp_block_info)
     # verify the transaction
     if not self.verify_transaction_hash(block_info, tx_hash):
         return False
     return True
示例#20
0
def mk_basic_state(alloc, header=None, env=None, executing_on_head=False):
    env = env or Env()
    state = State(env=env, executing_on_head=executing_on_head)
    if not header:
        header = {
            "number": 0,
            "gas_limit": env.config['BLOCK_GAS_LIMIT'],
            "gas_used": 0,
            "timestamp": 1467446877,
            "difficulty": 1,
            "uncles_hash": '0x' + encode_hex(BLANK_UNCLES_HASH)
        }
    h = BlockHeader(number=parse_as_int(header['number']),
                    timestamp=parse_as_int(header['timestamp']),
                    difficulty=parse_as_int(header['difficulty']),
                    gas_limit=parse_as_int(header['gas_limit']),
                    uncles_hash=parse_as_bin(header['uncles_hash']))
    state.prev_headers = [h]

    for addr, data in 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, parse_as_bin(k), parse_as_bin(v))

    state.block_number = header["number"]
    state.gas_limit = header["gas_limit"]
    state.timestamp = header["timestamp"]
    state.block_difficulty = header["difficulty"]
    state.commit()
    return state