Fundamentals

This article will help you understand the basic building blocks of Sign Protocol.

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

  • Utilize the ISPHook to take payments.

  • Reverting from within the ISPHook will revert the entire transaction, so the hook can provide additional checks and logic to validate attestation creation (for example, checking a whitelist). Use the Attestation.extraData field to pass in additional information that can be used from within the hook.

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: If 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.schema. There is no enforcement here, however. Recommended to use abi.encode.

Notes

  • attester will be the caller of attest() by default. If a delegate signature is supplied with the call, attester will be the address found in the Attestation object supplied to the function instead of the caller of attest().

  • recipients is an array of addresses. A single attestation can support many recipients. If no recipient is provided when an attestation is created, the attester is used.

  • data does not have any enforcement for what is supplied when an attestation is created by default. This validation can be performed in an ISPHook on the schema. You can use abi.encode and abi.decode to perform the data handling, or use other functions like viem's encodeAbiParameters and decodeAbiParameters to work with the data in the frontend.

ISPHook

interface ISPHook {
    function didReceiveAttestation(
        address attester,
        uint64 schemaId,
        uint64 attestationId,
        bytes calldata extraData
    )
        external
        payable;

    function didReceiveAttestation(
        address attester,
        uint64 schemaId,
        uint64 attestationId,
        IERC20 resolverFeeERC20Token,
        uint256 resolverFeeERC20Amount,
        bytes calldata extraData
    )
        external;

    function didReceiveRevocation(
        address attester,
        uint64 schemaId,
        uint64 attestationId,
        bytes calldata extraData
    )
        external
        payable;

    function didReceiveRevocation(
        address attester,
        uint64 schemaId,
        uint64 attestationId,
        IERC20 resolverFeeERC20Token,
        uint256 resolverFeeERC20Amount,
        bytes calldata extraData
    )
        external;
}

A hook is registered for a specific schema. We will refer to this schema in the following definitions.

  • didReceiveAttestation - Called when an attestation is created for the schema. The second definition of this function is to take payments.

  • didReceiveRevocation - Called when an attestation is revoked for the schema. The second definition of this function is to take payments.

Other Types

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 meant for true off-chain attestations where data is stored in other servers and a simple trace or record of the attestation is stored on-chain. This is distinct from the "Offchain Attestations" you can make from Sign Protocol's schema and attestation builders as these use schemas and attestations with data stored on Arweave, similar to how data is handled on-chain.

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 that an associated attestation will be a Hybrid Attestation. The SDK handles this case for you, but if you are directly interacting with any of the Sign Protocol smart contracts, ensure that you are passing in the correct data values (encoded CIDs) when creating a hybrid attestation.

Last updated

Logo

Copyright Sign 2021-2024