Documentation

Attestation Schema

Every energy attestation follows a single schema registered on the EAS SchemaRegistry. The schema defines the data structure that all attestations must conform to.

Schema Definition

uint64 projectId, uint32 readingCount, uint32 readingIntervalMinutes, uint256[] readings, uint64 fromTimestamp, string method, string metadataURI

Field Reference

FieldTypeDescription
projectIduint64ID of the registered energy project
readingCountuint32Number of interval readings (must equal readings.length)
readingIntervalMinutesuint32Duration of each interval in minutes
readingsuint256[]Per-interval energy in Wh (array length must match readingCount)
fromTimestampuint64Start of the reporting period (Unix seconds)
methodstringCollection method: "manual", "iot", "estimated", etc.
metadataURIstringOptional URI to supporting evidence (IPFS or HTTPS)
Note

The energy type is stored per-project in the registry (set at registration time), not per-attestation. The resolver reads the project's energy type from the registry during validation.

Derived Values

The resolver computes two values from the attestation data. These are not stored in the attestation itself but are used by the registry:

Solidity
toTimestamp = fromTimestamp + readingCount * readingIntervalMinutes * 60
energyWh   = sum(readings)

ABI Encoding

Attestation data is ABI-encoded before submission to EAS:

JavaScript
import { AbiCoder } from 'ethers';

const data = AbiCoder.defaultAbiCoder().encode(
  [
    "uint64",    // projectId
    "uint32",    // readingCount
    "uint32",    // readingIntervalMinutes
    "uint256[]", // readings
    "uint64",    // fromTimestamp
    "string",    // method
    "string"     // metadataURI
  ],
  [
    1,                           // projectId
    3,                           // 3 readings
    60,                          // 60-minute intervals
    [100000, 150000, 200000],    // readings in Wh
    1700000000,                  // fromTimestamp
    "iot",                       // method
    ""                           // metadataURI (optional)
  ]
);

Energy Units

Note

All energy values are in watt-hours (Wh), not kWh or MWh. This avoids floating-point precision issues on-chain.

UnitWh ValueExample
1 Wh1Single LED bulb for one hour
1 kWh1,000Typical household hourly consumption
1 MWh1,000,000Small commercial facility daily
1 GWh1,000,000,000Utility-scale solar farm monthly

Period Locking

The registry enforces two uniqueness constraints per project:

ConstraintKeyPurpose
Period uniqueness(projectId, fromTimestamp, toTimestamp)Prevents the same time window from being attested twice
Start-time uniqueness(projectId, fromTimestamp)Prevents two attestations with the same start, even with different durations

Linear Chain Enforcement

Attestations for a project must form a linear chain — each new attestation's fromTimestamp must equal the previous attestation's toTimestamp. This prevents gaps or overlaps in the reporting timeline.

Note

If a project does not generate or consume energy during a given period, a zero-energy attestation must still be submitted (with all readings set to 0) to maintain the chain. Skipping a period would break the linear sequence and block all future attestations for that project.

Note

If the energy data for a period is temporarily unavailable (e.g. meter outage, delayed data export), submit a zero-energy attestation as a placeholder to keep the chain moving. Once the actual data is available, replace the zero attestation with the correct readings using the replacement mechanism.

Corrections via Replacement

To correct an attestation, submit a replacement attestation by setting the refUID field to the original attestation's UID. The resolver validates that the replacement covers the same project and time period, then the registry records the replacement and adjusts energy accumulators by the delta. Direct revocations are blocked.