Documentation

Registry & Resolver

The two-contract design is the backbone of EnergyAS. Understanding how the Registry and Resolver interact is essential for working with the protocol.

EnergyRegistry

The registry is the permanent state contract. It stores all watchers, projects, attesters, energy accumulators, and period locks. It is never replaced or migrated.

Responsibilities

FunctionDescription
Watcher managementRegistration, ownership transfer
Project managementRegistration, deregistration, transfer between watchers
Attester managementPer-project and watcher-wide whitelisting
Period lockingPrevent duplicate attestations for the same time window
Linear chain enforcementEnsure attestations form a continuous timeline per project
Energy accumulatorsRunning totals per project and per watcher
Resolver authorizationControl which resolvers can write to the registry
Energy type registryOn-chain registry of valid energy source types
Replacement trackingTrack correction chains between attestations

EnergyAttestationResolver

The resolver is a stateless validation layer. It implements EAS's resolver interface and is called automatically by EAS on every attestation and revocation attempt.

Responsibilities

FunctionDescription
Data decodingDecode the ABI-encoded attestation data (7 fields)
Structural validationCheck readingCount, interval, readings array length, method
Permission checksVerify attester is whitelisted for the project or watcher
Derived computationCalculate toTimestamp and total energyWh from readings
Replacement validationVerify replacement attestations match the original's project and period
Registry delegationCall recordAttestation() or recordReplacement() on registry
Revocation blockingReject direct revocations to preserve audit trail

How They Interact

The resolver reads from the registry (to check project status, attester authorization, etc.) and writes to it (to record attestations and replacements). The registry only accepts writes from authorized resolvers.

Registry.authorizeResolver(resolverAddress)
  → Resolver can now call registry.recordAttestation()
  → Resolver can now call registry.recordReplacement()

Registry.deauthorizeResolver(resolverAddress)
  → Resolver can no longer write to registry
Note

Multiple resolvers can be authorized simultaneously. This enables zero-downtime migrations where old and new resolvers run side by side during a transition period.