Public testnet · ethrex

Hegotá testnet faucet

A test network for the frame-transaction family of EIPs, where one transaction carries a list of frames instead of a single call. The consensus is real and the ETH is worthless.

New to these EIPs? Start with the illustrated guide to the stack, or read what changes below. Built on ethrex.

What this chain changes

EIP-8141 Frame transactions: a new type 0x06 whose payload is a list of frames, each executed with its own target, gas limit and mode, with payment authorised by an APPROVE in a validation prefix.
EIP-8250 Keyed nonces: a transaction picks its own nonce domains, so one shared sender address stops being a throughput bottleneck. Useful for privacy pools and relayers.
EIP-8272 Recent roots: a transaction declares verified (source_id, slot, root) commitments in its signed envelope, readable from execution without touching another account's mutable storage.
EIP-7805 FOCIL: each slot a committee publishes inclusion lists that the next block must satisfy, so a builder cannot quietly censor a transaction. The only feature here that the consensus layer implements too.
EIP-8369 VOPS profiles for FOCIL eligibility: the rule deciding which frame transactions an inclusion list may demand, and when omitting one is unjustified. Activates with the rest and has no off switch.

All five activate at one timestamp. Two EIPs are in the ethrex binary but not part of this chain's rules: EIP-8312 (UTXO frames) never activates because utxoFramesTime is unset, and EIP-7906 (transaction assertions) is not in the build at all. Do not implement either against this network.

Inherited from Amsterdam

EIP-7928 Block-level access lists.
EIP-8037 Two-dimensional gas: state growth is priced separately from execution, so a transfer to a fresh account costs far more than 21,000 gas.
EIP-8038 Amsterdam repricing of the access, storage and access-list constants.
EIP-7843 A beacon slot number available to execution.
EIP-8282 Builder deposits and exits via predeploys.

Sending transactions

Ordinary transactions work normally. The ETH above is plain ETH: point any wallet or library at the RPC endpoint with the chain ID above and send transfers, deploy contracts, call them.

Frame transactions are a different matter. EIP-8141 is a draft, so no wallet and no released version of the common libraries can encode or sign a type 0x06 envelope yet; a wallet asked to send one has no representation for it. Submitting one today means building the envelope yourself and handing the signed bytes to eth_sendRawTransaction. The ethrex repository carries reference submitters that do exactly that, and the same is true of the extensions on this network: keyed nonces, recent-root references and assertion frames are all fields inside that envelope, reachable only through the same route.

Budget more gas than you expect. Under EIP-8037 a plain transfer that creates an account is far more expensive than the historical 21,000, closer to 210,000 on this chain, because account creation is charged as state growth. Estimate gas rather than hardcoding it; tooling with a baked-in 21,000 fails here, and it fails specifically when paying someone new.

Build a frame transaction

The smallest useful transaction is two frames: authorise, then execute.

0x06 envelope · two frames

  1. 0

    VERIFY flags 0x03tx.sender

    Static. Runs the sender's default code path, which checks the outer signature and executes APPROVE for both execution and payment. Without an APPROVE the transaction has no payer and is invalid.

  2. 1

    SENDER your target

    Executes with tx.sender as the caller: the call you actually wanted to make.

The order is the point. An APPROVE has to be in place before the frame it pays for runs.

The exact envelope is a type byte followed by an 11-field RLP list:

0x06 || rlp([chain_id, nonce_keys, nonce_seq, sender, frames, signatures,
             max_priority_fee, max_fee, max_fee_per_blob_gas, blob_hashes,
             recent_root_references])

frame     = [mode, flags, target, gas_limit, value, data]
signature = [scheme, signer, msg, signature]      # scheme 1 = secp256k1
sig_hash  = keccak256(0x06 || rlp(envelope))      # empty-msg signature bytes elided
DEFAULT Mode 0. Called by the entry point.
VERIFY Mode 1. Static; where authorisation happens.
SENDER Mode 2. Executes with tx.sender as the caller.
mode 3 Unassigned on this chain. EIP-7906 would have put its read-only POST_TX assertion suffix here, but that EIP is not in the build.

flags bits 0 and 1 are the APPROVE scope; bit 2 marks an atomic batch, which must be terminated by a following non-batch frame.

The signature is not in EVM form. Each entry is 65 bytes of v ‖ r ‖ s where v is the bare recovery id, 0 or 1, not 27/28. Anything above 1 is rejected, and it is the single most common reason a hand-built frame transaction is refused.

Run a node

Anyone may sync, peer and transact here without permission. You need both an execution client and a consensus client: an execution client alone will peer and then sit at genesis, because nothing is driving fork choice.

Start from the published artifact bundle, which carries the genesis, the consensus config and the bootnode lists. A consensus client consumes that directory as a whole, so a missing file fails at startup rather than at first use.

ethrex --network genesis.json \
       --bootnodes "$(paste -sd, bootnodes.txt)" \
       --nat.extip <your public IP> \
       --syncmode full

--nat.extip is what your node advertises in discovery and in its ENR. --p2p.addr is the bind address and is not a substitute: omit --nat.extip and you advertise whatever local address was found, which no external peer can dial back.

Peers as published, also served as JSON at /bootnodes:

Execution --bootnodes

  • enode://5d723d03bd9320cc33b9cb9c4dd8c53443a7b97ef5c9946ff655e85a878caca4656d8de18aa2ef6224fb1250bd82494066bd629118eef8bfe69ed474b14eae97@57.129.136.74:32000
  • enode://e2e1670c4a817ba2af978c5ac08b26ba99d267ea070f65a5e98039ff0bd720475f9bd00c17c5e64c62e907866134749ef72d2908351c507161a262201a51b2be@57.129.136.74:32007
  • enode://dbc207e0a6cf6f545e66f209e5fa17c734a48d6b5b2c8150ccc8d71ca24f848e2a153134c70f5e00863662595d9275b72de63978f9f8bc3f4191333b91dc53c3@57.129.136.74:32014

Consensus --boot-nodes

  • enr:-Oy4QP3x_K6J7t8nd8QRcNVHlhkmXa5989hufYGJ3nYgLOH0QvT4nVLrWj9fd_gjPcVsX9ju5xSNAWLirrG-WomG8r8Lh2F0dG5ldHOIAAAAYAAAAACDY2djgYCGY2xpZW500YpMaWdodGhvdXNlhTguMS4zhGV0aDKQ1lZDh5AAADj__________4JpZIJ2NIJpcIQ5gYhKg25mZIQAAAAAhHF1aWOCeRuJc2VjcDI1NmsxoQLNtbnDLuVS1qiqtuMl1_zPdYLg8AlktAT8qL5-kOofeohzeW5jbmV0cw-DdGNwgnkYg3VkcIJ5GA
  • enr:-Ou4QHvHPADHSetdiL5oOkUQ9yZ0v3gQ7EBDQakX357_ZKRWcHlrXN2T1CxfCw3FER1JXhkBiS49yiSz7hts8QnjIDkMh2F0dG5ldHOIAAAAAAAMAACDY2djIIZjbGllbnTRikxpZ2h0aG91c2WFOC4xLjOEZXRoMpDWVkOHkAAAOP__________gmlkgnY0gmlwhDmBiEqDbmZkhAAAAACEcXVpY4J5IolzZWNwMjU2azGhA4iy5gpAVD45x0xSaKOepGISDwuEc-4q3DW4Rvg9nANViHN5bmNuZXRzD4N0Y3CCeR-DdWRwgnkf
  • enr:-Ou4QAr8K8BOAcUHcfMmJx2Ixapr-QsJobU03Vzgk-cXyGnwceT6AKfgfnSnrdagzkGmZ5wifSU-_CJSwuODj0RnVy8Mh2F0dG5ldHOIBgAAAAAAAACDY2djIIZjbGllbnTRikxpZ2h0aG91c2WFOC4xLjOEZXRoMpDWVkOHkAAAOP__________gmlkgnY0gmlwhDmBiEqDbmZkhAAAAACEcXVpY4J5KYlzZWNwMjU2azGhAzmBGbHZ9nEZGYgUHMEem4SPEGDoG08wdyEMLSlkP_CPiHN5bmNuZXRzD4N0Y3CCeSaDdWRwgnkm
The consensus client must be FOCIL-aware. From the Hegotá fork on, this chain rejects engine_newPayloadV5 and engine_forkchoiceUpdatedV4, because only the V6/V5 pair carries inclusion lists. A client speaking only the older pair halts at the boundary — there is no inert intermediate state. Discovery also needs both TCP and UDP; opening only TCP gives you a node nobody discovers, which reads as slow peering rather than as a firewall mistake.

Become a validator

Validator entry is the one permissioned thing on this network. Depositing requires a token held by the address that sends the deposit transaction — not the withdrawal address, and not the validator public key. That is the most common mistake. Ask the operators to mint one to your depositing address; without it the deposit reverts with Not enough tokens.

Withdrawal credentials. BLS credentials are blocked outright, so use an execution-layer form:

0x00BLS — blocked, the deposit reverts.
0x01Execution-layer withdrawal address. The usual choice.
0x02Compounding.
0x03Builder, since this chain runs Gloas.
0xffffTop-up to an existing validator. Never gated, no token needed.

Generate deposit data signed against this chain's genesis fork version 0x10000038, then send it to the deposit contract with 32 ETH. A successful deposit burns exactly one token and emits the standard DepositEvent. It then enters the pending-deposit queue and is processed at an epoch boundary, so activation is not immediate.

Run a validator client for it. A deposited validator with nothing signing on its behalf starts accruing missed-attestation penalties the moment it activates. Exiting is possible either through a consensus-layer voluntary exit or the EIP-7002 predeploy, but only after the validator has been active for 256 epochs, about 14 hours here. An exit request made before then is accepted and paid for by the execution layer and then silently ignored, so a successful transaction is not evidence that the exit took.