Hegotá privacy testnet faucet

A public test network running EIP-8141 frame transactions together with EIP-8250 keyed nonces, EIP-8272 recent roots and EIP-7805 inclusion lists, on ethrex. Test ETH has no value.

Latest change: 2026-09-25 · changelog

What this chain enables

EIP-8141
b75cbe6115
Frame transactions: a new type 0x06 whose payload is a list of frames, each executed with its own target, mode and two gas budgets, with payment authorised by an APPROVE in a validation prefix. Authentication becomes a program: a passkey, a multisig or a zero-knowledge proof can authorise a transaction, and the account that pays need not be the one that acts.
EIP-8250
f3079a09e8
Keyed nonces: up to 16 independent nonce keys per sender instead of one linear counter, tracked in a NONCE_MANAGER predeploy. A contract sender can have several transactions pending on different keys and none waits behind another.
EIP-8272
824cbc0b0e
Recent roots: verified (source, slot, root) tuples carried in a canonical VERIFY frame that leads the transaction and is checked by a RECENT_ROOT predeploy before application code runs; the prefix reads them back with FRAMEDATALOAD. A proof can be anchored to a root minutes old without the prefix touching storage.
EIP-7805
9a345f96c2
Fork-choice enforced inclusion lists, with EIP-8369's validation-only profiles (at 51dc7b939a, merged upstream) deciding which frame transactions are eligible: attesters replay only the validation prefix, under a fixed budget, so a builder cannot leave an eligible transaction out.

Together they are what a shielded pool needs from the base layer: a proof authorising a spend, the pool paying for it, concurrent spends, a fresh root to prove against, and an inclusion guarantee. Everything else is Glamsterdam. Each EIP is explained at length, with how they lean on each other, in the EIP guide.

The hash under each number is the ethereum/EIPs commit this chain implements. These drafts move often and the chain does not follow them live: what runs here is the text at those commits (git show <commit>:EIPS/eip-<n>.md), and a spec change only reaches the chain through a relaunch. The network spec records the pins, the fork schedule and what is being tested.

Connect

Chain ID
8141 (0x1fcd)
RPC
https://rpc1.privacy.ethrex.xyz
Explorer
dora.privacy.ethrex.xyz
Bundle
faucet.privacy.ethrex.xyz/artifacts

Sending transactions here

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 one; a wallet asked to send one simply has no representation for it. Submitting one 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 node offers ethrex_simulateFrameTransaction to dry-run the bytes before you send them.

Send one

Take the submitters from the hegota-testnet branch:

git clone --branch hegota-testnet --depth 1 https://github.com/lambdaclass/ethrex
cd ethrex/scripts/hegota-testnet && pip install eth-keys eth-hash[pycryptodome]

Only this branch speaks the wire format this chain runs: nested fees, a per-frame [execution, state] pair, keyed nonces, recent roots in a verifier frame. Released libraries, and rex for now, encode an older envelope and are rejected on decode (see the first error below).

# Self-verified transfer: a VERIFY frame approving execution and payment,
# then a SENDER frame that moves the value. Prints the sig hash, the tx hash,
# and the mined receipt with its per-frame receipts.
python3 frametx_submit.py https://rpc1.privacy.ethrex.xyz <YOUR_PRIVATE_KEY_HEX> 0xRecipientAddress 1000000000

# A sponsored transfer, where a second account pays:
python3 frametx_sponsor_submit.py https://rpc1.privacy.ethrex.xyz <SENDER_KEY> <PAYER_KEY> 0xRecipientAddress 1000000000

# Dry-run any raw 0x06 payload against the node before submitting it:
curl -s https://rpc1.privacy.ethrex.xyz -H 'content-type: application/json' \
  -d '{"jsonrpc":"2.0","id":1,"method":"ethrex_simulateFrameTransaction","params":["0x06…"]}'

# Decode a mined one, frame by frame:
curl -s https://rpc1.privacy.ethrex.xyz -H 'content-type: application/json' \
  -d '{"jsonrpc":"2.0","id":1,"method":"eth_getTransactionReceipt","params":["<TX_HASH>"]}'

The receipt carries frameReceipts, one per frame, each with its own status, gasUsed and stateGasUsed. The explorer renders the same breakdown. frametx.py next to the submitters is the encoder itself; build any frame shape from it.

Common errors

Error decoding field 'frames' … Error decoding field 'limits' of type (u64, u64): MalformedData

The encoder predates two-dimensional gas and is sending a frame's gas as one scalar. This chain accepts only the [execution, state] pair. The sibling Error decoding field 'fees' means the fees are flat where this chain expects one nested [max_priority_fee, max_fee, max_fee_per_blob_gas] list; a released rex produces exactly that.

A frame reverts having used exactly its execution budget, with stateGasUsed: 0x0

Missing state budget, not execution. Raising the frame's limits.execution will not help; raise its limits.state. A transfer to an address that does not exist yet needs 183,600 of it, the account-creation charge.

Invalid frame transaction signature

The layout is v ‖ r ‖ s with v a bare recovery id, 0 or 1 — not the 27/28 form ecrecover takes. r and s must also be canonical and low-s.

Frame transaction prefix gas budget (frames + sig cost) exceeds MAX_VERIFY_GAS

The validation prefix is bounded, at 500,000 here. Move work out of the prefix, or lower the prefix frames' limits.execution. The signature-verification variant means the signatures alone already exceed it — use fewer.

Building one

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

0x06 || rlp([chain_id, nonce_keys, nonce_seq, sender, frames, signatures, fees, blob_hashes])
nonce_keys = [0]                                  # the legacy account nonce; or 1..16 strictly increasing keys (EIP-8250)
frame      = [mode, flags, target, [execution, state], value, data]
fees       = [max_priority_fee, max_fee, max_fee_per_blob_gas]
signature  = [scheme, signer, msg, signature]     # scheme 1 = secp256k1
sig_hash   = keccak256(0x06 || rlp(envelope))     # empty-msg signature bytes elided
# recent roots (EIP-8272): a leading VERIFY frame to 0x…8272, flags 0, state 0,
#   data = (source_id ‖ uint64_be(slot) ‖ root) × 1..16
mode 0DEFAULT, called by the entry point.
mode 1VERIFY, static; where authorisation happens. A frame targeting tx.sender with flags = 0x03 runs the default code path, checks the outer signature and executes APPROVE for both execution and payment. Without an APPROVE the transaction has no payer and is invalid.
mode 2SENDER, executes with tx.sender as the caller.

The smallest useful transaction is therefore two frames: a VERIFY frame targeting the sender with flags = 0x03, then a SENDER frame carrying the actual call. 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.

A frame's two budgets are independent: execution pays for running code, state pays for state growth. Execution gas cannot cover state growth, so a frame that writes new state with state: 0 halts on that write and burns its whole execution budget — which looks exactly like an execution limit set too low. Check stateGasUsed on the receipt: if it is 0x0, the missing budget is the state one. Unused state gas is refunded.

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

Read the changelog before syncing: a relaunch means a fresh genesis, and a database from the previous chain has to be wiped.

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

Execution --bootnodes

  • enode://26e04c1ff1d4745d0477c1591be1eccabc2cdab91907fb1dff40c8bdeb0f61fa622da9513d3e2f219b10243876af70148a7d98d9dd5e2e2293ab469bd810993e@57.129.136.74:32000
  • enode://d768f201dad09f32ffecb0f834cb0efe85bcab52f164e12bb931b633f015e57bd6c1c69cab209a05b9dd2889c5dbb3ea89e1162f3c2a98772c28b34ac1a62d04@57.129.136.74:32007
  • enode://7db9510c6426b594c7a0cfd336fa2d6ffdeaf281a84f8c62d647572324d61c7e2fbe6c1208cd976730b31a30b16cd150098c8bcbf32f0e615b5a91c7970c7aa3@57.129.136.74:32014

Consensus --boot-nodes

  • enr:-Oy4QP6b9ZzfdY3NOuUQ9Wrra5FETjOob74tPGGq8Z1Itvs9MHMXboRuJ84OP4xOCDWv-BZqxH0qlHT33XNnGYKvAogLh2F0dG5ldHOIYAAAAAAAAACDY2djgYCGY2xpZW500YpMaWdodGhvdXNlhTguMS4zhGV0aDKQo8kMipAAADj__________4JpZIJ2NIJpcIQ5gYhKg25mZIQAAAAAhHF1aWOCeRuJc2VjcDI1NmsxoQJo04ZTNi1Yvg5GEUsPa5EZRsHjRazsAUx8-3eoqFeHEohzeW5jbmV0cw-DdGNwgnkYg3VkcIJ5GA
  • enr:-Oy4QMRMjUq2xZ8HoHmBHpCIyFpQqmOCv7i4w7f1FpCNwdQxfW4ROCfU5X2ikh75pj3ec7tIed6owlHcXtK8FAj6v9ILh2F0dG5ldHOIAAAAAAAAMACDY2djgYCGY2xpZW500YpMaWdodGhvdXNlhTguMS4zhGV0aDKQo8kMipAAADj__________4JpZIJ2NIJpcIQ5gYhKg25mZIQAAAAAhHF1aWOCeSKJc2VjcDI1NmsxoQM_KFcxReMc9dVkc_dhvSPnc5LiuwEaT8-thEoYmAMn8ohzeW5jbmV0cw-DdGNwgnkfg3VkcIJ5Hw
  • enr:-Oy4QPUn2L0bM3mUhmkHHvw_Irrt8mubx3yqyA7m292WvFhRRtLZnQbEsqfhPCCT8Pq7FUes6kcCGLtvPGocQT9qhRYLh2F0dG5ldHOIAIABAAAAAACDY2djgYCGY2xpZW500YpMaWdodGhvdXNlhTguMS4zhGV0aDKQo8kMipAAADj__________4JpZIJ2NIJpcIQ5gYhKg25mZIQAAAAAhHF1aWOCeSmJc2VjcDI1NmsxoQJ3_pVdQ2LiT9Lr9__8VDVHw7isL7P2VjB5zLCgxa43oYhzeW5jbmV0cw-DdGNwgnkmg3VkcIJ5Jg
The consensus client must be FOCIL-aware. From Hegotá on, ethrex serves only engine_newPayloadV6 and engine_forkchoiceUpdatedV5, the pair that carries inclusionListTransactions, and rejects the older V5/V4 pair. A client that speaks only those halts at the fork boundary with no inert state in between. ethpandaops/lighthouse:focil works; a stock release generally does not. Confirm the capability through engine_exchangeCapabilities before the boundary, not after.
# Execution layer, from the bundle's genesis.json and bootnodes.txt
ethrex --network genesis.json \
       --bootnodes "$(paste -sd, bootnodes.txt)" \
       --nat.extip <your public IP> \
       --syncmode full

# Consensus layer, against the execution client's engine port
lighthouse beacon_node \
  --testnet-dir=. \
  --execution-endpoint=http://127.0.0.1:8551 \
  --jwt-secrets=<path to the jwtsecret your EL generated> \
  --boot-nodes="$(paste -sd, bootnodes-cl.txt)"

--nat.extip is what the node advertises in discovery and in its ENR; --p2p.addr is only the bind address and is not a substitute. To confirm you are following the chain, compare a block hash against rpc1 at the same height, not just the height.

Become a validator

Validator entry is permissioned; everything else on this chain is not. Contact us with the address you will deposit from — not the withdrawal address, not the validator pubkey. We mint a deposit token to that address; ask for the 32 ETH stake at the same time, since it is beyond the faucet's drip. Without the token the deposit reverts with Not enough tokens; with it, the deposit burns the token and works.

1. Choose execution-layer withdrawal credentials. 0x01, 0x02 and 0x03 are allowed with a token; BLS 0x00 deposits are blocked outright. Top-ups to an existing validator (0xffff) need no token.

2. Generate deposit data against this chain's genesis fork version, 0x10000038. Signed against anything else, the execution transaction succeeds and the consensus layer rejects the deposit. With ethdo:

ethdo validator depositdata \
  --validatoraccount=<wallet>/<account> \
  --withdrawaladdress=<your 0x01 address> \
  --depositvalue="32 Ether" \
  --forkversion=0x10000038 \
  --raw

3. Deposit 32 ETH from the granted address, with the calldata --raw printed. Let the tool estimate gas:

cast send --rpc-url https://rpc1.privacy.ethrex.xyz \
  --private-key <DEPOSITOR_KEY> --value 32ether \
  0x00000000219ab540356cBB839Cbe05303d7705Fa <CALLDATA>

A successful deposit consumes exactly one token and emits the standard DepositEvent. Activation follows the protocol's queue, roughly an hour; watch the pubkey from your own beacon node or in the explorer, and run a validator client against your own node from "Run a node" before it activates, or it starts accruing missed-attestation penalties from its first active epoch.

Exiting. Send 56 bytes — the 48-byte pubkey then an 8-byte amount, 0 for a full exit — to the EIP-7002 predeploy 0x00000961Ef480Eb55e80D19ad83579A64c007002 from your 0x01 withdrawal address, with the current fee as value. Exits are only honoured 256 epochs after activation; before that the transaction succeeds and the consensus layer silently ignores it, so only the validator's own exit_epoch is evidence the exit took.

Changelog

2026-09-25
08:52 UTC
Node hotfix, no re-genesis. A frame transaction whose top-level frame called a precompile after an earlier frame had emitted a log crashed the execution client while it built a block, so the proposer produced nothing for that slot and every following one while the transaction stayed pending. The transaction shape is valid; the client mishandled it. All three network nodes now run hegota-testnet-hotfix at bf42186da, swapped in place with their chain databases and node keys unchanged: the bundle, the bootnodes and every balance are as before, and nothing has to be resynced or re-signed. Anyone running their own ethrex node should move to the same commit before sending that shape, since a node on the previous build fails to import a block that contains it. One slot was missed during the rolling restart. Reported by an external user; thank you.
2026-09-14
21:47 UTC
Fresh genesis on the current specs, the chain running now. Pins: EIP-8141 b75cbe6115, EIP-8250 f3079a09e8, EIP-8272 824cbc0b0e, EIP-7805 9a345f96c2, EIP-8369 51dc7b939a (merged upstream). For anyone building frame transactions: the first use of a keyed nonce costs 97,920 of state gas from the approving frame (195,840 for two fresh keys) instead of 20,000 execution gas, and the prefix's state budgets may not exceed 500,000. Recent roots have left the envelope for a canonical VERIFY frame to 0x…8272 carrying 72-byte (source_id, slot, root) tuples, so the envelope now has 8 fields, TXPARAM 0x11 and RECENTROOTREFLOAD are gone, and the predeploy runs a 345-byte two-operation runtime. That frame's gas counts toward the validation budget, so a proof-carrying transaction needs 352,800 rather than 322,800. A root published in slot S is referenceable from S+1, and admission judges it against the head slot plus one. EIP-8312 is not in this build. Every type 0x06 transaction signed for the previous chain is invalid here, and so is every account balance: wipe your database and resync from the new bundle, and request new funds from the faucet. The previous chain ended at block 160,854. The two EIP-8141 divergences flagged on 2026-09-04 (SIGPARAM(0x03) answered for every scheme; the value cost charged on frames that move nothing) are fixed in this build.
2026-09-04 The pages now show the ethereum/EIPs commit each EIP is implemented at, and the network spec is published: rule set and pins, endpoints, what is being tested, how to join, and every known divergence between the running nodes and the pinned text. Two such divergences in EIP-8141 (SIGPARAM(0x03) answered for every signature scheme; the value cost charged on frames that move nothing) were fixed on the branch and shipped with the 2026-09-14 relaunch; they could not be applied in place, because blocks already on that chain depended on the old behaviour.
2026-09-03 All three beacon nodes now custody every PeerDAS column, so a consensus client with default custody can range-sync; before this a joiner could stall waiting for columns no peer served. A read-only beacon API is published at checkpoint-sync.privacy.ethrex.xyz; the FOCIL Lighthouse build cannot checkpoint-sync from it yet on a Gloas chain, so sync from genesis (minutes). The bootnode bundle was re-published with the changed beacon records: refetch bootnodes-cl.txt.
2026-09-03
17:18 UTC
Fresh genesis on the updated specs, the chain running now. Pins: EIP-8141 7d1c8bfb94, EIP-8250 e5cf246ff1, EIP-8272 0231fb05f5, EIP-7805 9a345f96c2, EIP-8369 33724bd7da. For anyone building frame transactions: the envelope has 9 fields with the fees nested in one list, each frame declares limits = [execution, state], the intrinsic cost is 12,000 plus 6,000 per frame that moves value, SIGDATACOPY is its own opcode at 0xB5, EIP-8250's ids moved to TXPARAM 0x0D–0x10, and EIP-8272's count sits at TXPARAM 0x11 with RECENTROOTREFLOAD at 0xB6. Every type 0x06 transaction signed for the previous chain is invalid here. The previous chain ended at block 313,106: wipe your database and resync from the new bundle. An earlier relaunch the same day was withdrawn after 1,691 blocks; nothing from it carries over. Spec diffs: 8141, 8250, 8272.
2026-08-11 Network launched as chain 8141: EIP-8141, EIP-8250, EIP-8272 and EIP-7805 with EIP-8369, activating together at one fork on top of Glamsterdam, at the four core EIPs' 4093c21847 revision and EIP-8369's 6f818e27dd. Validator entry permissioned through a gated deposit contract; syncing, peering and transacting open to anyone. Faucet, explorer and public RPC online.

Newest first. Every relaunch, and every change a node operator or transaction builder has to act on, gets an entry here with the date it took effect. The exact rule set and pins are in the network spec.