Cryo Explorer Ethereum Mainnet

Address Contract Verified

Address 0xAA25602bccF3bBdE8E2F0F09f3a1f6DEF54593c0
Balance 0 ETH
Nonce 1
Code Size 738 bytes
Indexed Transactions 0
External Etherscan · Sourcify

Contract Bytecode

738 bytes
0x608060405234801561001057600080fd5b506004361061004c5760003560e01c80636057361d1461005157806383b6d6b714610070578063e9413d3814610078578063fadff0e1146100a7575b600080fd5b61006e6004803603602081101561006757600080fd5b5035610154565b005b61006e6101b0565b6100956004803603602081101561008e57600080fd5b50356101bf565b60408051918252519081900360200190f35b61006e600480360360408110156100bd57600080fd5b813591908101906040810160208201356401000000008111156100df57600080fd5b8201836020820111156100f157600080fd5b8035906020019184600183028401116401000000008311171561011357600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550610226945050505050565b80408061019e576040805162461bcd60e51b8152602060048201526013602482015272189b1bd8dada185cda0a1b8a4819985a5b1959606a1b604482015290519081900360640190fd5b60009182526020829052604090912055565b6101bd6101004303610154565b565b60008181526020819052604081205480610220576040805162461bcd60e51b815260206004820152601c60248201527f626c6f636b68617368206e6f7420666f756e6420696e2073746f726500000000604482015290519081900360640190fd5b92915050565b60008083600101815260200190815260200160002054818051906020012014610296576040805162461bcd60e51b815260206004820152601c60248201527f6865616465722068617320756e6b6e6f776e20626c6f636b6861736800000000604482015290519081900360640190fd5b602401516000918252602082905260409091205556fea2646970667358221220abdf30c7ff36f3e37f20137b753f00ed2b677cb4992ca7a999b971aaacff062864736f6c63430006060033

Verified Source Code Full Match

Compiler: v0.6.6+commit.6c089d02 EVM: istanbul Optimization: Yes (200 runs)
BlockhashStore.sol 80 lines
// File: contracts/dev/BlockhashStore.sol

pragma solidity 0.6.6;

/**
 * @title BlockhashStore
 * @notice This contract provides a way to access blockhashes older than
 *   the 256 block limit imposed by the BLOCKHASH opcode.
 *   You may assume that any blockhash stored by the contract is correct.
 *   Note that the contract depends on the format of serialized Ethereum
 *   blocks. If a future hardfork of Ethereum changes that format, the 
 *   logic in this contract may become incorrect and an updated version 
 *   would have to be deployed.
 */
contract BlockhashStore {

  mapping(uint => bytes32) internal s_blockhashes;

  /**
   * @notice stores blockhash of a given block, assuming it is available through BLOCKHASH
   * @param n the number of the block whose blockhash should be stored
   */
  function store(uint256 n) public {
    bytes32 h = blockhash(n);
    require(h != 0x0, "blockhash(n) failed");
    s_blockhashes[n] = h;
  }


  /**
   * @notice stores blockhash of the earliest block still available through BLOCKHASH.
   */
  function storeEarliest() external {
    store(block.number - 256);
  }

  /**
   * @notice stores blockhash after verifying blockheader of child/subsequent block
   * @param n the number of the block whose blockhash should be stored
   * @param header the rlp-encoded blockheader of block n+1. We verify its correctness by checking
   *   that it hashes to a stored blockhash, and then extract parentHash to get the n-th blockhash.
   */
  function storeVerifyHeader(uint256 n, bytes memory header) public {
    require(keccak256(header) == s_blockhashes[n + 1], "header has unknown blockhash");

    // At this point, we know that header is the correct blockheader for block n+1.

    // The header is an rlp-encoded list. The head item of that list is the 32-byte blockhash of the parent block.
    // Based on how rlp works, we know that blockheaders always have the following form:
    // 0xf9____a0PARENTHASH...
    //   ^ ^   ^
    //   | |   |
    //   | |   +--- PARENTHASH is 32 bytes. rlpenc(PARENTHASH) is 0xa || PARENTHASH.
    //   | |
    //   | +--- 2 bytes containing the sum of the lengths of the encoded list items
    //   |
    //   +--- 0xf9 because we have a list and (sum of lengths of encoded list items) fits exactly into two bytes.
    //
    // As a consequence, the PARENTHASH is always at offset 4 of the rlp-encoded block header.

    bytes32 parentHash;
    assembly {
      parentHash := mload(add(header, 36)) // 36 = 32 byte offset for length prefix of ABI-encoded array
                                           //    +  4 byte offset of PARENTHASH (see above)
    }

    s_blockhashes[n] = parentHash;
  }

  /**
   * @notice gets a blockhash from the store. If no hash is known, this function reverts.
   * @param n the number of the block whose blockhash should be returned
   */
  function getBlockhash(uint256 n) external view returns (bytes32) {
    bytes32 h = s_blockhashes[n];
    require(h != 0x0, "blockhash not found in store");
    return h;
  }
}

Read Contract

getBlockhash 0xe9413d38 → bytes32

Write Contract 3 functions

These functions modify contract state and require a wallet transaction to execute.

store 0x6057361d
uint256 n
storeEarliest 0x83b6d6b7
No parameters
storeVerifyHeader 0xfadff0e1
uint256 n
bytes header

Recent Transactions

No transactions found for this address