EIPs/EIPS/eip-5851.md
Dhruv Malik 250420822f
Add EIP-5851: On-Chain Verifiable Credentials (#5851)
* WIP: defining ERC standard for ZK based KYC verifier.

* modified:   EIPS/eip-draft-ZKID-standard.md

* WIp: description of the functions

* WIP: metadata description

* removing metadata to local docs, adding examples

* WIp: adapting the certifier contract and interface

* WIP: code refactor and adding examples

* spaces and author name

* WIP: removing eipv errors

* contd

* minor issues

* removing identation issues

* resolving another round of markdown and EIPV issues

* last one hopefully !!!

* Update spaces in-lining

Co-authored-by: Pandapip1 <45835846+Pandapip1@users.noreply.github.com>

* link and image format

Co-authored-by: Pandapip1 <45835846+Pandapip1@users.noreply.github.com>

* defining definition of ZK term

Co-authored-by: Pandapip1 <45835846+Pandapip1@users.noreply.github.com>

* Refactoring the description

Co-authored-by: Pandapip1 <45835846+Pandapip1@users.noreply.github.com>

* removing redundant description of motivation points

Co-authored-by: Pandapip1 <45835846+Pandapip1@users.noreply.github.com>

* refactor description

Co-authored-by: Pandapip1 <45835846+Pandapip1@users.noreply.github.com>

* Update description points

Co-authored-by: Pandapip1 <45835846+Pandapip1@users.noreply.github.com>

* explain the efficiency aspect

* title description

Co-authored-by: Pandapip1 <45835846+Pandapip1@users.noreply.github.com>

* addingdefinitions to be described

* reference changes

* did all the spec changes , along with renaming asset folder

* minor refactor

* minor corrections of formula

* broken links

* linting issues

* adding new diagram

* wip: define latest workflow diagram

* leaf -> proof in setting information

* feat: reviewed with all the intial corrections and diagram description

* corrections pointed out by @Pandapip1

* never mind

* removing lint issues

* refactoring the diagram along with description of spec

* WIP: rectifying the code contracts.

* Update EIPS/eip-5851.md

Co-authored-by: Pandapip1 <45835846+Pandapip1@users.noreply.github.com>

* Update EIPS/eip-5851.md

Co-authored-by: Pandapip1 <45835846+Pandapip1@users.noreply.github.com>

* Update EIPS/eip-5851.md

Co-authored-by: Pandapip1 <45835846+Pandapip1@users.noreply.github.com>

* Update EIPS/eip-5851.md

Co-authored-by: Pandapip1 <45835846+Pandapip1@users.noreply.github.com>

* Update EIPS/eip-5851.md

Co-authored-by: Pandapip1 <45835846+Pandapip1@users.noreply.github.com>

* WIP: commit changes by the reviewer

* Update EIPS/eip-5851.md

Co-authored-by: Pandapip1 <45835846+Pandapip1@users.noreply.github.com>

* WIp: other description errors.

* fix lint

* fixing explanation

* adding Verifiable description changes

* contd

* WIP: rewriting the standard (currently not completed).

* changing the metadata details

* WIp: defining the example of VC.

* modified:   EIPS/eip-5851.md

* Update eip-5851.md

* Update eip-5851.md

* refactoring the description along with adding the new diagram.

 - WIP: @yuliu-debond to define the workflow regarding how the third party will  integrate the standard.

* update EIP examples and their description

* update

* Update eip-5851.md

* Update eip-5851.md

* Update eip-5851.md

* Update eip-5851.md

* Update IERC5851.sol

* Update IERC5851.sol

* Update eip-5851.md

* Update eip-5851.md

* Update eip-5851.md

* Update eip-5851.md

* Update eip-5851.md

* Update eip-5851.md

* Update IERC5851.sol

* Update verification_modifier.sol

* Update IERC5851.sol

* Update eip-5851.md

* Update IERC5851.sol

* Update SBT_certification.sol

* Create EIP-5851Verifier

* Rename EIP-5851Verifier to EIP-5851Verifier.sol

* Rename SBT_certification.sol to ERC5851Issuer.sol

* Rename EIP-5851Verifier.sol to ERC5851Verifier.sol

* Delete verification_modifier.sol

* Update test.sol

* Update ERC5851Verifier.sol

* Update ERC5851Issuer.sol

* Update ERC5851Issuer.sol

* Update IERC5851.sol

* Update ERC5851Issuer.sol

* Create ERC5851Verifier.sol

* Update test.sol

* Update eip-5851.md

* Update eip-5851.md

* Update eip-5851.md

* Update eip-5851.md

* Delete architecture-diagram-5851.png

* modified:   EIPS/eip-5851.md
- Rectifying linting issues like spacing between the headings and spellings

* adding suggestions from 5851.

	modified:   EIPS/eip-5851.md
	modified:   assets/eip-3475/ERC3475.sol
	modified:   assets/eip-5851/contracts/interfaces/IERC5851.sol

- l#3: minor refactoring
- shifting the definitions to the specification section.
- rewriting the description of claim structures.
- black-ticks for marking code.
- l#61: refactoring the description of metadata in the nature of exposure to given
- changing name of metadata type to kind for standardised names.
- refactoting the JSON description along with sentences description about the example requirement structure.
- l#95: refactoring the definition.
- defining the logic operations supported by the claim structure along with their ASCII code representation.
- defining the abstract more comprehensively.
- l#137: completing the description about the function logic.

* Update definition ZKP

* Update eip-5851.md

* update json example format eip-5851.md

* Update eip-5851.md

* minr lint

* Updated titile

* Update eip-5851.md

* resolving minor functions

* improve clarity of 'value information'

* Update eip-5851.md

* add a blank line before/after fenced code blocks

* Delete eip-5851.md

* Delete ERC5851Issuer.sol

* Delete ERC3475.sol

* Create eip-5851.md

* Create ERC5851Issuer.sol

* Create ERC3475.sol

* Update ERC3475.sol

Co-authored-by: Pandapip1 <45835846+Pandapip1@users.noreply.github.com>
Co-authored-by: Shebin John <admin@remedcu.com>
Co-authored-by: yuliu-debond <79855548+yuliu-debond@users.noreply.github.com>
Co-authored-by: jooeys <zhongjunyi.dev@gmail.com>
2023-01-14 17:51:16 -08:00

14 KiB

eip title description author discussions-to status type category created requires
5851 On-Chain Verifiable Credentials Interface for contracts that manage verifiable claims and identifiers as Soulbound tokens. Yu Liu (@yuliu-debond), Junyi Zhong (@Jooeys) https://ethereum-magicians.org/t/eip-5815-kyc-certification-issuer-and-verifier-standard/11513 Draft Standards Track ERC 2022-10-18 721, 1155, 1167, 1967, 3475

Abstract

This proposal introduces a method of certifying that a particular address meets a claim, and a method of verifying those certifications using on-chain metadata. Claims are assertions or statements made about a subject having certain properties that may be met conditions (for example: age >= 18), and are certified by issuers using a Soundbound Token (SBT).

Motivation

On-chain issuance of verifiable attestations are essential for use-case like:

  • Avoiding Sybil attacks with one person one vote
  • Participation in certain events with credentials
  • Compliance to government financial regulations etc.

We are proposing a standard claims structure for Decentralized Identity (DID) issuers and verifier entities to create smart contracts in order to provide on-chain commitment of the off-chain verification process, and once the given address is associated with the given attestation of the identity verification off-chain, the issuers can then onboard other verifiers (i.e. governance, financial institution, non-profit organization, web3 related cooperation) to define the condition of the ownership of the user in order to reduce the technical barriers and overhead of current implementations.

The motivation behind this proposal is to create a standard for verifier and issuer smart contracts to communicate with each other in a more efficient way. This will reduce the cost of KYC processes, and provide the possibility for on-chain KYC checks. By creating a standard for communication between verifiers and issuers, it will create an ecosystem in which users can be sure their data is secure and private. This will ultimately lead to more efficient KYC processes and help create a more trustful environment for users. It will also help to ensure that all verifier and issuer smart contracts are up-to-date with the most recent KYC regulations.

Specification

The keywords "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119 and RFC 8174.

Definitions

  • Zero-Knowledge Proof (ZKP): a cryptographic device that can convince a verifier that an assertion is correct without revealing all of the inputs to the assertion.

  • Soulbound Token (SBT): A non-fungible and non-transferrable token that is used for defining the identity of the users.

  • SBT Certificate: An SBT that represents the ownership of ID signatures corresponding to the claims defined in function standardClaim().

  • Verifiable Credential (VC): A collection of claims made by an issuer. These are temper evident credentials that allow the holders to prove that they posses certain characteristics (for example, passport verification, constraints like value of tokens in your wallet, etc) as demanded by the verifier entity.

  • Claim: An assertion that the DID Holder must fulfill to be verified.

  • Holder: The entity that stores the claim, such as a digital identity provider or a DID registry. The holder is responsible for validating the claim and providing verifiable evidence of the claim.

  • Claimer: The party making a claim, such as in an identity verification process.

  • Issuer: The entity that creates a verifiable credential from claims about one or more subjects to a holder. Example issuers include governments, corporations, non-profit organizations, trade associations, and individuals.

  • Verifier: An entity that validates data provided by an issuer of verifiable credentials, determining its accuracy, origin, currency and trustworthiness.

Metadata Standard

Claims MUST be exposed in the following structures:

1. Metadata information

Each claim requirement MUST be exposed using the following structure:

    /** Metadata
    * 
    * @param title defines the name of the claim field
    * @param _type is the type of the data (bool,string,address,bytes,..)
    * @param description additional information about claim details.
     */
    struct Metadata {
        string title;
        string _type;
        string description;
    }

2. Values Information

This following structure will be used to define the actual claim information, based on the description of the Metadata structure, the structure is the same as Values structure of EIP-3475.

   struct Values{
       string stringValue;
       uint uintValue;
       address addressValue;
       bool boolValue;
  }

3. Claim structure

Claims (eg. age >= 18, jurisdiction in allowlist, etc.) are represented by one or many instances of the Claim structure below:

    /** Claims
    * 
    * Claims structure consist of the conditions and value that holder claims to associate and verifier has to validate them.
    * @notice the below given parameters are for reference purposes only, developers can optimize the fields that are needed to be represented on-chain by using schemes like TLV, encoding into base64 etc.
    * @dev structure that defines the parameters for specific claims of the SBT certificate
    * @notice this structure is used for the verification process, it contains the metadata, logic and expectation
    * @notice logic can represent either the enum format for defining the different operations, or they can be logic operators (stored in form of ASCII figure based on unicode standard). like  e.g: 
("⊄" = U+2284, "⊂" = U+2282,  "<" = U+003C , "<=" = U + 2265,"==" = U + 003D, "!="U + 2260, ">=" = U + 2265,">" =  U + 2262).
    */
    struct Claim {
        Metadata metadata;
        string logic;
        Values expectation;
   
    }

description of some logic functions that can be used are as follows:

Symbol Description
does not belong to the set of values (or range) defined by the corresponding Values
condition that the parameter belongs to one of values defined by the Values
< condition that the parameter is greater than value defined by the Values
== condition that the parameter is strictly equal to the value defined by the Values structure

Claim Example

{
   "title":"age",
   "type":"unit",
   "description":"age of the person based on the birth date on the legal document",
   "logic":">=",
   "value":"18"
}

Defines the condition encoded for the index 1 (i.e the holder must be equal or more than 18 years old).

Interface specification

Verifier


    /// @notice getter function to validate if the address `claimer` is the holder of the claim defined by the tokenId `SBTID`
    /// @dev it MUST be defining the conditional operator (logic explained below) to allow the application to convert it into code logic 
    /// @dev logic given here MUST be the conditiaonl operator, MUST be one of ("⊄", "⊂", "<", "<=", "==", "!=", ">=", ">")
    /// @param claimer is the EOA address that wants to validate the SBT issued to it by the issuer. 
    /// @param SBTID is the Id of the SBT that user is the claimer.
    /// @return true if the assertion is valid, else false
    /**
    example ifVerified(0xfoo, 1) => true will mean that 0xfoo is the holder of the SBT identity token defined by tokenId of the given collection. 
    */
    function ifVerified(address claimer, uint256 SBTID) external view returns (bool);

Issuer

  
    /// @notice getter function to fetch the on-chain identification logic for the given identity holder.
    /// @dev it MUST not be defined for address(0). 
    /// @param SBTID is the Id of the SBT that the user is the claimer.
    /// @return the struct array of all the descriptions of condition metadata that is defined by the administrator for the given KYC provider.
    /**
    ex: standardClaim(1) --> {
    { "title":"age",
        "type": "uint",
        "description": "age of the person based on the birth date on the legal document",
        },
       "logic": ">=",
    "value":"18"  
    }
    Defines the condition encoded for the identity index 1, defining the identity condition that holder must be equal or more than 18 years old.
    **/

    function standardClaim(uint256 SBTID) external view returns (Claim[] memory);

    /// @notice function for setting the claim requirement logic (defined by Claims metadata) details for the given identity token defined by SBTID.
    /// @dev it should only be called by the admin address.
    /// @param SBTID is the Id of the SBT-based identity certificate for which the admin wants to define the Claims.
    /// @param `claims` is the struct array of all the descriptions of condition metadata that is defined by the administrator. check metadata section for more information.
    /**
    example: changeStandardClaim(1, { "title":"age",
            "type": "uint",
            "description": "age of the person based on the birth date on the legal document",
            },
        "logic": ">=",
        "value":"18"  
    }); 
    will correspond to the functionality that admin needs to adjust the standard claim for the identification SBT with tokenId = 1, based on the conditions described in the Claims array struct details.
    **/

    function changeStandardClaim(uint256 SBTID, Claim[] memory _claims) external returns (bool);

    /// @notice function which uses the ZKProof protocol to validate the identity based on the given 
    /// @dev it should only be called by the admin address.
    /// @param SBTID is the Id of the SBT-based identity certificate for which admin wants to define the Claims.
    /// @param claimer is the address that needs to be proven as the owner of the SBT defined by the tokenID.
    /**
    example: certify(0xA....., 10) means that admin assigns the DID badge with id 10 to the address defined by the `0xA....` wallet.
    */
    function certify(address claimer, uint256 SBTID) external returns (bool);

    /// @notice function which uses the ZKProof protocol to validate the identity based on the given 
    /// @dev it should only be called by the admin address.
    /// @param SBTID is the Id of the SBT-based identity certificate for which the admin wants to define the Claims.
    /// @param claimer is the address that needs to be proven as the owner of the SBT defined by the tokenID.
    /* eg: revoke(0xfoo,1): means that KYC admin revokes the SBT certificate number 1 for the address '0xfoo'. */
    function revoke(address certifying, uint256 SBTID) external returns (bool);

Events

    /** 
    * standardChanged
    * @notice standardChanged MUST be triggered when claims are changed by the admin. 
    * @dev standardChanged MUST also be triggered for the creation of a new SBTID.
    e.g : emit StandardChanged(1, Claims(Metadata('age', 'uint', 'age of the person based on the birth date on the legal document' ), ">=", "18");
    is emitted when the Claim condition is changed which allows the certificate holder to call the functions with the modifier, claims that the holder must be equal or more than 18 years old.
    */
    event StandardChanged(uint256 SBTID, Claim[] _claims);
    
    /** 
    * certified
    * @notice certified MUST be triggered when the SBT certificate is given to the certifying address. 
    * eg: Certified(0xfoo,2); means that wallet holder address `0xfoo` is certified to hold a certificate issued with id 2, and thus can satisfy all the conditions defined by the required interface.
    */
    event Certified(address claimer, uint256 SBTID);
    
    /** 
    * revoked
    * @notice revoked MUST be triggered when the SBT certificate is revoked. 
    * eg: Revoked( 0xfoo,1); means that entity user 0xfoo has been revoked to all the function access defined by the SBT ID 1.
    */
    event Revoked(address claimer, uint256 SBTID);
}

Rationale

TBD

Backwards Compatibility

  • This EIP is backward compliant for the contracts that keep intact the metadata structure of previous issued SBT's with their ID and claim requirement details.
    • For e.g if the DeFI provider (using the modifiers to validate the ownership of required SBT by owner) wants the admin to change the logic of verification or remove certain claim structure, the previous holders of the certificates will be affected by these changes.

Test Cases

Test cases for the minimal reference implementation can be found here for using transaction verification regarding whether the users hold the tokens or not. Use Remix IDE to compile and test the contracts.

Reference Implementation

The interface is divided into two separate implementations:

  • EIP-5851 Verifier is a simple modifier that needs to be imported by functions that are to be only called by holders of the SBT certificates. Then the modifier will call the issuer contract to verifiy if the claimer has the SBT certifcate in question.

  • EIP-5851 Issuer is an example of an identity certificate that can be assigned by a KYC controller contract. This is a full implementation of the standard interface.

Security Considerations

  1. Implementation of functional interfaces for creating KYC on SBT (i.e changeStandardClaim(), certify() and revoke()) are dependent on the admin role. Thus the developer must insure security of admin role and rotation of this role to the entity entrusted by the KYC attestation service provider and DeFI protocols that are using this attestation service.

Copyright and related rights waived via CC0.