Documentation

Submitting Attestations

Attestations are the core of EnergyAS — on-chain energy readings that are permanent, verifiable, and auditable by anyone.

Prepare Your Data

Each attestation contains interval readings in watt-hours (Wh). For example, 24 hourly readings from a solar farm:

JSON
{
  "project_id": 1,
  "reading_count": 24,
  "reading_interval": 60,
  "readings": [0, 0, 0, 0, 0, 15000, 45000, 120000,
               280000, 410000, 520000, 580000, 590000,
               560000, 480000, 350000, 200000, 80000,
               20000, 0, 0, 0, 0, 0],
  "from_timestamp": "1700000000",
  "method": "iot",
  "energy_type": 1,
  "metadata_uri": "ipfs://QmReportHash"
}

Submit via Script

Terminal
npx hardhat run scripts/attest.ts --network <network>

The script can load from a JSON file or prompt interactively. It encodes the data, submits to EAS, and the resolver validates and records the attestation.

Submit via Code

JavaScript
import { AbiCoder, ZeroAddress, ZeroHash } from 'ethers';

const data = AbiCoder.defaultAbiCoder().encode(
  ["uint64", "uint32", "uint32", "uint256[]", "uint64",
   "string", "uint8", "string"],
  [projectId, readingCount, intervalMinutes, readings,
   fromTimestamp, "iot", energyType, metadataURI]
);

const tx = await eas.attest({
  schema: schemaUID,
  data: {
    recipient: ZeroAddress,
    expirationTime: 0,
    revocable: true,
    refUID: ZeroHash,
    data,
    value: 0n
  }
});

const receipt = await tx.wait();

Batch Attestations

Use EAS multiAttest() to submit multiple readings in a single transaction:

JavaScript
const items = reports.map(report => ({
  schema: schemaUID,
  data: [{
    recipient: ZeroAddress,
    expirationTime: 0,
    revocable: true,
    refUID: ZeroHash,
    data: encodeReport(report),
    value: 0n
  }]
}));

await eas.multiAttest(items);

Corrections

To correct a reading, first revoke the original attestation, then re-submit:

JavaScript
// 1. Revoke the incorrect attestation
await eas.revoke({
  schema: schemaUID,
  data: { uid: originalAttestationUID, value: 0n }
});

// 2. Re-submit with corrected data
await eas.attest({ ... });
Note

Revocation clears the period lock, allowing the same time window to be re-attested. Revocations always work, even when the resolver is paused.