Skip to content

Data Models

ERD showing the relationship between schemas and attestations ERD showing the relationship between schemas and attestations
ERD showing the relationship between schemas and attestations

Schema

struct Schema {
    address registrant;
    bool revocable;
    DataLocation dataLocation;
    uint64 maxValidFor;
    ISPHook hook;
    uint64 timestamp;
    string data;
}
  • registrant: The address that registered this schema.
  • revocable: Whether Attestations that adopt this Schema can be revoked.
  • dataLocation: Where Schema.data is stored. See DataLocation.
  • maxValidFor: The maximum number of seconds that an Attestation can remain valid. 0 means Attestations can be valid forever. This is enforced through Attestation.validUntil.
  • hook: The ISPHook that is called at the end of every function. 0 means no hook is set. See ISPHook.
  • timestamp: When the schema was registered. This is automatically populated by _register(...).
  • data: The raw schema that Attestation.data should follow. Since there is no way to enforce this, it is a string for easy readability.

Notes

  • Use the ISPHook to take payments.
  • Reverting from within the ISPHook reverts the entire transaction, so the hook can add checks to validate attestation creation (for example, a whitelist). Pass additional information to the hook in the extraData argument of attest().

Attestation

struct Attestation {
    uint64 schemaId;
    uint64 linkedAttestationId;
    uint64 attestTimestamp;
    uint64 revokeTimestamp;
    address attester;
    uint64 validUntil;
    DataLocation dataLocation;
    bool revoked;
    bytes[] recipients;
    bytes data;
}
  • schemaId: The Schema that this Attestation is based on. It must exist.
  • linkedAttestationId: Useful if the current Attestation references a previous Attestation. It can either be 0 or an existing attestation ID.
  • attestTimestamp: When the attestation was made. This is automatically populated by _attest(...).
  • revokeTimestamp: When the attestation was revoked. This is automatically populated by _revoke(...).
  • attester: The attester.
  • validUntil: The expiration timestamp of the Attestation. Must respect Schema.maxValidFor. 0 indicates no expiration date.
  • dataLocation: Where Attestation.data is stored. See DataLocation.
  • revoked: Whether the Attestation has been revoked. It is possible to make a revoked Attestation.
  • recipients: The intended ABI-encoded recipients of this Attestation. This is of type bytes to support non-EVM recipients.
  • data: The raw data of the Attestation based on Schema.data. This is not enforced. We recommend using abi.encode.

Notes

  • By default, attester is the caller of attest(). If the call includes a delegate signature, attester is instead the address in the Attestation object passed to the function.
  • recipients is an array of addresses, so one attestation can have many recipients. If no recipient is provided when an attestation is created, the attester is used.
  • By default, data is not validated when an attestation is created. You can validate it in an ISPHook on the schema. Use abi.encode and abi.decode to handle the data, or functions like viem's encodeAbiParameters and decodeAbiParameters in the frontend.

OffchainAttestation

struct OffchainAttestation {
    address attester;
    uint64 timestamp;
}
  • attester: The attester. At this time, the attester must be the caller of attestOffchain().
  • timestamp: The block.timestamp of the function call.

Notes

  • OffchainAttestation is for true off-chain attestations: data is stored on other servers and only a record of the attestation is stored on-chain. This differs from the "Offchain Attestations" made with Sign Protocol's schema and attestation builders, which use schemas and attestations with data stored on Arweave, handled the same way as on-chain data.

DataLocation

enum DataLocation {
    ONCHAIN,
    ARWEAVE,
    IPFS,
    CUSTOM
}

This enum indicates where Schema.data and Attestation.data are stored.

Notes

  • A DataLocation that is not ONCHAIN means the associated attestation is a Hybrid Attestation. The SDK handles this for you, but if you call the Sign Protocol smart contracts directly, pass the correct data values (encoded CIDs) when creating a hybrid attestation.