Onchain.Block (onchain v0.16.0)

Copy Markdown View Source

Represents a block from the Ethereum JSON-RPC endpoint.

Defined here: https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_getblockbyhash

Fields are nullable when they belong to a hard-fork upgrade and may be absent on pre-upgrade blocks: base_fee_per_gas (London, EIP-1559), withdrawals_root / withdrawals (Shanghai, EIP-4895), and parent_beacon_block_root / blob_gas_used / excess_blob_gas (Cancun, EIP-4788 + EIP-4844). mix_hash is present pre-Merge as the PoW mix hash and post-Merge as PREVRANDAO (EIP-4399).

API Functions

FunctionArityDescriptionParam Kinds
find_by_timestamp!2Binary search for block ≤ target timestamp. Raises on error.target_timestamp: value, opts: value
find_by_timestamp2Binary search for the highest block with timestamp ≤ target.target_timestamp: value, opts: value
get_by_number!2Fetch and parse a block by number or tag. Raises on error.block_id: value, opts: value
get_by_number2Fetch and parse a block by number or tag.block_id: value, opts: value
deserialize1Decode an Ethereum block JSON-RPC object into a Onchain.Block struct.params: exchange_data

Summary

Functions

Deserializes a block object from JSON-RPC.

Binary search for the highest block with timestamp ≤ target.

Binary search for block ≤ target timestamp. Raises on error.

Fetch and parse a block by number or tag.

Fetch and parse a block by number or tag. Raises on error.

Types

t()

@type t() :: %Onchain.Block{
  base_fee_per_gas: integer() | nil,
  blob_gas_used: integer() | nil,
  difficulty: integer(),
  excess_blob_gas: integer() | nil,
  extra_data: binary(),
  gas_limit: integer(),
  gas_used: integer(),
  hash: <<_::256>> | nil,
  logs_bloom: <<_::1024>> | nil,
  miner: <<_::160>>,
  mix_hash: <<_::256>> | nil,
  nonce: integer() | nil,
  number: integer() | nil,
  parent_beacon_block_root: <<_::256>> | nil,
  parent_hash: <<_::256>> | nil,
  receipts_root: <<_::256>>,
  requests_hash: <<_::256>> | nil,
  sha3_uncles: <<_::256>>,
  size: integer(),
  state_root: <<_::256>>,
  timestamp: integer(),
  total_difficulty: integer(),
  transactions: [
    String.t()
    | Onchain.Transaction.V1.t()
    | Onchain.Transaction.V_2930.t()
    | Onchain.Transaction.V2.t()
    | Onchain.Transaction.V3.t()
    | Onchain.Transaction.V4.t()
  ],
  transactions_root: <<_::256>>,
  uncles: [<<_::256>>],
  withdrawals: [Onchain.Block.Withdrawal.t()] | nil,
  withdrawals_root: <<_::256>> | nil
}

Functions

deserialize(params)

@spec deserialize(map() | nil) :: t() | nil

Deserializes a block object from JSON-RPC.

Examples

iex> %{
...>   "difficulty" => "0x4ea3f27bc",
...>   "extraData" => "0x476574682f4c5649562f76312e302e302f6c696e75782f676f312e342e32",
...>   "gasLimit" => "0x1388",
...>   "gasUsed" => "0x0",
...>   "hash" => "0xdc0818cf78f21a8e70579cb46a43643f78291264dda342ae31049421c82d21ae",
...>   "logsBloom" => "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
...>   "miner" => "0xbb7b8287f3f0a933474a79eae42cbca977791171",
...>   "mixHash" => "0x4fffe9ae21f1c9e15207b1f472d5bbdd68c9595d461666602f2be20daf5e7843",
...>   "nonce" => "0x689056015818adbe",
...>   "number" => "0x1b4",
...>   "parentHash" => "0xe99e022112df268087ea7eafaf4790497fd21dbeeb6bd7a1721df161a6657a54",
...>   "receiptsRoot" => "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
...>   "sha3Uncles" => "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
...>   "size" => "0x220",
...>   "stateRoot" => "0xddc8b0234c2e0cad087c8b389aa7ef01f7d79b2570bccb77ce48648aa61c904d",
...>   "timestamp" => "0x55ba467c",
...>   "totalDifficulty" => "0x78ed983323d",
...>   "transactions" => [],
...>   "transactionsRoot" => "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
...>   "uncles" => []
...> }
...> |> Onchain.Block.deserialize()
%Onchain.Block{
  difficulty: 0x4ea3f27bc,
  extra_data: ~h[0x476574682f4c5649562f76312e302e302f6c696e75782f676f312e342e32],
  gas_limit: 0x1388,
  gas_used: 0x0,
  hash: ~h[0xdc0818cf78f21a8e70579cb46a43643f78291264dda342ae31049421c82d21ae],
  logs_bloom: ~h[0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000],
  miner: ~h[0xbb7b8287f3f0a933474a79eae42cbca977791171],
  mix_hash: ~h[0x4fffe9ae21f1c9e15207b1f472d5bbdd68c9595d461666602f2be20daf5e7843],
  nonce: 0x689056015818adbe,
  number: 0x1b4,
  parent_hash: ~h[0xe99e022112df268087ea7eafaf4790497fd21dbeeb6bd7a1721df161a6657a54],
  receipts_root: ~h[0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421],
  sha3_uncles: ~h[0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347],
  size: 0x220,
  state_root: ~h[0xddc8b0234c2e0cad087c8b389aa7ef01f7d79b2570bccb77ce48648aa61c904d],
  timestamp: 0x55ba467c,
  total_difficulty: 0x78ed983323d,
  transactions: [],
  transactions_root: ~h[0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421],
  uncles: [],
  base_fee_per_gas: nil,
  withdrawals_root: nil,
  withdrawals: nil,
  parent_beacon_block_root: nil,
  blob_gas_used: nil,
  excess_blob_gas: nil
}

Post-Cancun block with all fork-tier fields populated:

iex> %{
...>   "number" => "0x1312d00",
...>   "hash" => "0xd24fd73f794058a3807db926d8898c6481e902b7edb91ce0d479d6760f276183",
...>   "parentHash" => "0xb390d63aac03bbef75de888d16bd56b91c9291c2a7e38d36ac24731351522bd1",
...>   "nonce" => "0x0000000000000000",
...>   "sha3Uncles" => "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
...>   "logsBloom" => "0x" <> String.duplicate("00", 256),
...>   "transactionsRoot" => "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
...>   "stateRoot" => "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
...>   "receiptsRoot" => "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
...>   "miner" => "0x95222290dd7278aa3ddd389cc1e1d165cc4bafe5",
...>   "difficulty" => "0x0",
...>   "totalDifficulty" => "0xc70d815d562d3cfa955",
...>   "extraData" => "0x",
...>   "size" => "0x220",
...>   "gasLimit" => "0x1c9c380",
...>   "gasUsed" => "0xa9371c",
...>   "timestamp" => "0x665ba27f",
...>   "transactions" => [],
...>   "uncles" => [],
...>   "mixHash" => "0x4fffe9ae21f1c9e15207b1f472d5bbdd68c9595d461666602f2be20daf5e7843",
...>   "baseFeePerGas" => "0x6f4f8d96",
...>   "withdrawalsRoot" => "0x9d56fa5a08e21cd3ff7f8b6f5b6cb6f5b6cb6f5b6cb6f5b6cb6f5b6cb6f5b6cb",
...>   "withdrawals" => [
...>     %{
...>       "index" => "0x4d8f7d",
...>       "validatorIndex" => "0xc8a5f",
...>       "address" => "0x1f9090aae28b8a3dceadf281b0f12828e676c326",
...>       "amount" => "0x111c8c2"
...>     }
...>   ],
...>   "parentBeaconBlockRoot" => "0xb390d63aac03bbef75de888d16bd56b91c9291c2a7e38d36ac24731351522bd1",
...>   "blobGasUsed" => "0x80000",
...>   "excessBlobGas" => "0x4a0000"
...> }
...> |> Onchain.Block.deserialize()
...> |> Map.take([:number, :base_fee_per_gas, :withdrawals, :parent_beacon_block_root, :blob_gas_used, :excess_blob_gas])
%{
  number: 20_000_000,
  base_fee_per_gas: 0x6f4f8d96,
  withdrawals: [
    %Onchain.Block.Withdrawal{
      index: 0x4d8f7d,
      validator_index: 0xc8a5f,
      address: ~h[0x1f9090aae28b8a3dceadf281b0f12828e676c326],
      amount: 0x111c8c2
    }
  ],
  parent_beacon_block_root: ~h[0xb390d63aac03bbef75de888d16bd56b91c9291c2a7e38d36ac24731351522bd1],
  blob_gas_used: 0x80000,
  excess_blob_gas: 0x4a0000
}

find_by_timestamp(target_timestamp, opts \\ [])

@spec find_by_timestamp(non_neg_integer(), keyword()) :: {:ok, t()} | {:error, term()}

Binary search for the highest block with timestamp ≤ target.

Parameters

  • target_timestamp - Unix timestamp (seconds) to search for (value)
  • opts - Options: :rpc_url, :timeout, :floor (block number integer), :ceil (block number integer) (default: [], value)

Returns

Full block struct with highest timestamp ≤ target ({:ok, Onchain.Block.t()} | {:error, term})

# descripex:contract
%{
  params: %{
    opts: %{
      default: [],
      description: "Options: :rpc_url, :timeout, :floor (block number integer), :ceil (block number integer)",
      kind: :value
    },
    target_timestamp: %{
      description: "Unix timestamp (seconds) to search for",
      kind: :value
    }
  },
  returns: %{
    type: "{:ok, Onchain.Block.t()} | {:error, term}",
    description: "Full block struct with highest timestamp ≤ target"
  }
}

find_by_timestamp!(target_timestamp, opts \\ [])

@spec find_by_timestamp!(non_neg_integer(), keyword()) :: t()

Binary search for block ≤ target timestamp. Raises on error.

Parameters

  • target_timestamp - Unix timestamp (seconds) (value)
  • opts - Options: :rpc_url, :timeout, :floor, :ceil (default: [], value)

Returns

Full decoded block struct (map)

# descripex:contract
%{
  params: %{
    opts: %{
      default: [],
      description: "Options: :rpc_url, :timeout, :floor, :ceil",
      kind: :value
    },
    target_timestamp: %{description: "Unix timestamp (seconds)", kind: :value}
  },
  returns: %{type: :map, description: "Full decoded block struct"}
}

get_by_number(block_id, opts \\ [])

@spec get_by_number(integer() | String.t(), keyword()) ::
  {:ok, t()} | {:error, term()}

Fetch and parse a block by number or tag.

Parameters

  • block_id - Block number (integer) or tag string ("latest", "finalized", etc.) (value)
  • opts - Options: :rpc_url, :timeout (default: [], value)

Returns

Full block struct with integer quantities and binary hashes ({:ok, Onchain.Block.t()} | {:error, term})

# descripex:contract
%{
  params: %{
    opts: %{
      default: [],
      description: "Options: :rpc_url, :timeout",
      kind: :value
    },
    block_id: %{
      description: "Block number (integer) or tag string (\"latest\", \"finalized\", etc.)",
      kind: :value
    }
  },
  returns: %{
    type: "{:ok, Onchain.Block.t()} | {:error, term}",
    description: "Full block struct with integer quantities and binary hashes"
  }
}

get_by_number!(block_id, opts \\ [])

@spec get_by_number!(integer() | String.t(), keyword()) :: t()

Fetch and parse a block by number or tag. Raises on error.

Parameters

  • block_id - Block number (integer) or tag string (value)
  • opts - Options: :rpc_url, :timeout (default: [], value)

Returns

Full decoded block struct (map)

# descripex:contract
%{
  params: %{
    opts: %{
      default: [],
      description: "Options: :rpc_url, :timeout",
      kind: :value
    },
    block_id: %{
      description: "Block number (integer) or tag string",
      kind: :value
    }
  },
  returns: %{type: :map, description: "Full decoded block struct"}
}