Eco ID System

Eco IDs are non-transferable NFTs that conform to the ERC-721 standard. Each NFT contains an arbitrary claim that is attested to by at least one verifier, along with a list of the verifiers who have attested to the claim. The claim can contain any piece of data an individual or collective might want to be associated with a public Ethereum address.

To mint an Eco ID for a given claim, an end user must first find one verifier willing to verify the claim. Once a verifier has attested to the claim, the end user can mint a single non-transferable NFT with the claim in the “data” property of the NFT and the initial verifier in the “verifier” property of the NFT.

Once the NFT is minted, additional verifiers are able to attest to the claim, and their addresses are appended to the NFT’s readable metadata structure. The system allows for an unlimited number of verifiers.

The NFT system provides two types of attestations: revocable and non-revocable. A revocable attestation allows the verifier to revoke their attestation at any time, which may be appropriate for attestations that are ephemeral in nature, like a subscription to a service. A non-revocable attestation may not be revoked by either the holder of the NFT or the verifier and is appropriate for claims that require immutability.

The system introduces novel economic incentives for verifiers to participate in the system by allowing both the initial verifier and additional verifiers to charge a fee for the attestation. Verifiers and end users must agree on a price for the attestation beforehand, which must be paid in ECO.

The Eco ID NFT is a primitive that will enable a fully decentralized and permissionless identity infrastructure and system. Interested parties can choose which verifiers they trust and which data to listen to. Over time, the Eco ID NFT system will allow for the accumulation of many claims and verifications, and those will lead to increasingly-complex and custom reputation and governance systems. For more detailed implementation details, see the GitHub Repository (when it is public).

Eco ID NFT Technical Details

Public Variables

All NFTs share a couple of core constant public variables, located below.

EcoID.sol
string public constant NFT_EXTERNAL_URL = "https://eco.org/eco-id";
string public constant NFT_IMAGE_URL = "https://ipfs.io/ipfs/QmWZFvb88KDos7BYyf52btxPuEEifZN7i5CA2YfC3azS8J";
uint256 public constant META_LIMIT = 50;
uint256 public constant SUB_NAME_LENGTH = 10;

Most of these variables are self-explanatory, other than META_LIMIT and SUB_NAME_LENGTH. META_LIMIT imposes a limit on the number of verifiers read from the contract at a time (loop over all pages when the number of verifiers is larger than 50). The SUB_NAME_LENGTH sets the length of the NFT name to a max of ten characters.

Data Structure

To help conceptualize the data located in the NFT, there is a JSON located below with a structure similar to the way the data is structured in the NFT:

{
  description: 'EcoNFT',
  external_url: 'https://eco.org/',
  image: 'https://ipfs.io/ipfs/QmZxvWzRT4Kq3FGEjvMeBaad7qvrSc79MqPggk5At5qxP6',
  name: 'Eco Fragment [data:discord..., verifiers:0xf39fd...]',
  attributes: [
    { trait_type: 'Data', value: 'discord:21306324' },
    {
      trait_type: 'Verifier',
      value: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266',
      revocable: 'false'
    },
    {
      trait_type: 'Verifier',
      value: '0x3c44cdddb6a900fa2b585dd299e03d12fa4293bc',
      revocable: 'true'
    }
  ]
}

Verified claim data is structured in the VerifiedClaim struct, which contains a VerifierRecord within the struct. The VerifiedClaim struct contains a claim string, a tokenID to track the NFT IDs, VerifierRecord struct which contains the verifier address and indicates whether the attestation is removable, and the verifierMap, which tracks if an attestation has a given verifier. This is all then stored in \_verifiedClaims using a mapping.

EcoID.sol
/**
 * Structure for storing a verified claim
 */
struct VerifiedClaim {
    string claim;
    uint256 tokenID;
    VerifierRecord[] verifiers;
    mapping(address => bool) verifierMap;
}

/**
 * Structure for the verifier record
 */
struct VerifierRecord {
    address verifier;
    bool revocable;
}

/**
 * Mapping the user address with all claims they have
 */
mapping(address => mapping(string => VerifiedClaim)) public _verifiedClaims;

Important Functions

This section contains a high-level overview of important functions in the NFT. For more detailed implementation details, see the GitHub Repository.

Checking Claim Verification

The isClaimVerified allows a reader to quickly check if a claim is verified for a given address.

EcoID.sol
function isClaimVerified(
    address recipient,
    string calldata claim,
    address verifier
) external view returns (bool)

Registering a Claim

The register function allows an address and verifier to submit signatures together to register a claim. In this sense, both addresses seeking verification and verifiers must coordinate offline to exchange signatures so that one of them can call the verification.

EcoID.sol
function register(
    string calldata claim,
    uint256 feeAmount,
    bool revocable,
    address recipient,
    address verifier,
    uint256 deadline,
    bytes calldata approveSig,
    bytes calldata verifySig
) external _validClaim(claim)

Minting an NFT

The mintNFT function allows anyone to mint an NFT that is soulbound to an end user who has a verified claim and does not have the NFT minted.

EcoID.sol
function mintNFT(address recipient, string memory claim)
    external
    returns (uint256 tokenID)

Retrieving Verifier List and Pagination

Verifier claims for a given Eco ID are stored in paginated JSON objects. To call the first 50 verifiers, one can call the tokenURI function.

EcoID.sol
function tokenURI(uint256 tokenID)
    public
    view
    override
    returns (string memory)

If an Eco ID has more than 50 verifiers, the tokenURICursor allows for paginated calls, which allow a reader to loop over the index of pages to retrieve the verifiers.

EcoID.sol
function tokenURICursor(
    uint256 tokenID,
    uint256 cursor,
    uint256 limit
) public view virtual returns (string memory meta)

Nonce Mechanism

The Eco ID system uses a nonce for each unique verifier for a claim. To get the current nonce for a claim, use the nonces function.

EcoID.sol
nonces(string memory claim) public view returns (uint256)

Last updated