6.7 KiB
ECP-0092: Ethereum rails and private settlement for every.channel
Status: Draft
Problem / context
every.channel already has useful anti-junk and manifest integrity primitives, but they stop at
repo-local formats: custom Merkle trees, JSON body hashes, and Ed25519 signatures. That is enough
for local validation, not for the broader direction now requested:
- stream identity, broadcast de-duplication, manifests, and transport announcements should all have Ethereum-compatible representations,
- private-chain settlement should reuse existing Ethereum tooling instead of inventing a custom ledger,
- iroh should remain the transport substrate,
- storage on chain must stay compact, and
ecp-forgeshould become the high-bandwidth head node for sequencing, archival, and bootstrap.
This supersedes the specific ECP-0022 alternative that rejected “global consensus / blockchain for manifests” as overkill. The new direction is not a public general-purpose chain. It is a private, Ethereum-compatible settlement rail for every.channel commitments.
Decision
Adopt a dual-plane architecture:
irohremains the transport, discovery, and media movement layer.- Local protocol integrity remains first-class:
manifest_idstays BLAKE3 over the manifest body,- object membership proofs stay
merkle+blake3, - Ed25519 manifest signatures remain supported.
- Ethereum-compatible commitments become an additive settlement/mirroring layer for stream identity, transport announcements, and manifests.
- Ethereum-native signatures are added alongside local signatures:
- manifests may carry secp256k1 EIP-712 signatures over
ManifestBody, - no existing local signature path is removed as part of this proposal.
- manifests may carry secp256k1 EIP-712 signatures over
- On-chain state remains compact:
- manifests store only stream/epoch ids plus commitment hashes,
- control announcements store only stream ids plus announcement commitments,
- full media bytes, manifests, PSIP tables, and chunk inventories remain off-chain.
- The chain is private and purpose-built for every.channel use cases:
- no arbitrary application compute in the near term,
- no fraud-proof system in the near term,
- permissionless submission as far as operationally possible,
- pseudonymous participation preferred over account-heavy identity.
Details
Canonical Ethereum representations
Introduce Solidity-compatible struct mirrors for the protocol surfaces we actually ship:
BroadcastIdSourceIdStreamKeyStreamDescriptorStreamControlAnnouncementChunkIdManifestVariantManifestBodyManifestSignatureManifest
These are encoded via Solidity ABI rules and hashed with keccak256. They mirror the shipped
protocol types; they do not replace the local wire format or local hashing rules.
Manifest commitments
Publisher-generated manifests may carry a set of Ethereum commitments as first-class fields:
manifest-data-merkle-keccak256-v1- Keccak Merkle root over ordered chunk hashes, or over ordered variant roots for multi-variant manifests.
manifest-body-abi-keccak256-v1keccak256(abi.encode(EthManifestBody))
manifest-envelope-abi-keccak256-v1keccak256(abi.encode(EthManifest))
manifest_id and merkle_root remain the local BLAKE3-backed protocol fields. Ethereum
commitments are explicit, separately named, and never inferred from those local field names alone.
Signature rails
Manifest signatures become dual-rail:
- local signatures continue to sign the local BLAKE3
manifest_idwith Ed25519, - Ethereum-native signatures sign the typed
EthManifestBodywith secp256k1 EIP-712, - both signature families may appear on the same manifest.
The Ethereum signature target is ManifestBody, not the full manifest envelope, so signatures do
not become self-referential when more signatures are appended.
Stream and control commitments
Stream descriptors and control announcements may also carry Ethereum-compatible commitments:
stream-id-keccak256-v1stream-descriptor-abi-keccak256-v1control-announcement-abi-keccak256-v1
This ties broadcast-scoped discovery identity to the same settlement vocabulary used by manifests without forcing transport-time consumers to abandon the local vocabulary they already use.
Solidity rail contract
Add a minimal contract that stores only the latest compact pointers:
- latest manifest pointer per
stream_id + epoch_id - latest transport announcement pointer per
stream_id - event emissions for historical indexing
The contract must stay event-heavy and storage-light. Full manifests stay in iroh / relay / archive storage.
ecp-forge role
ecp-forge becomes the maximal head node for this network:
- private-chain bootstrap and packaging,
- archival indexer for settlement events,
- high-bandwidth manifest and control announcer,
- optional sequencer / execution-client host for the private network.
This role is operational, not constitutional. Other nodes must still be able to validate, mirror, and submit commitments without going through a closed control plane.
Alternatives considered
- Keep custom BLAKE3-only manifests forever. Rejected because it strands every.channel outside the tooling and audit surface of the Ethereum ecosystem.
- Replace BLAKE3 and Ed25519 immediately. Rejected because it weakens the local protocol’s existing integrity path before the private rail is operational and discards useful cryptographic properties for no near-term operational win.
- Build a custom blockchain. Rejected because existing Rust + Solidity stacks are already good enough and reduce implementation risk.
- Use public Ethereum mainnet / arbitrary public L2s directly. Rejected for now because cost, privacy, and operational control do not fit the current network shape.
Rollout / teardown plan
- Add
ec-ethwith canonical Solidity-compatible representations and Keccak commitments. - Preserve the local BLAKE3/Ed25519 rail as the default transport integrity path.
- Add optional secp256k1 EIP-712 manifest-body signatures alongside Ed25519 signatures.
- Add the minimal Solidity rail contract for compact settlement pointers.
- Teach publishers/indexers to mirror manifests and announcements onto the private chain.
- Stand up the private Ethereum-compatible network on
ecp-forgeand companion nodes.
Teardown:
- back out the Ethereum rail changes explicitly in code; the preserved local rail remains as the fallback integrity path.
Open questions
- Which execution stack should back the private network first: a slim Reth-based node, or a more minimal Rust EVM deployment?
- When the private rail becomes live, do we require both signature families for publisher policy, or is one valid rail-specific signature enough for a given transport or settlement action?