Tutorials
Create a Cred

Constructing an Cred Issuer Contract

Using Creds Protocol contracts we can easily create our own Creds Issuer Contract and add the Zero Knowledge flavour.

⚠️

This tutorial is under review and would be modified in future !!

In this tutorial, we will be creating a Cred, and learn how to customize the contract.


Consider your favourite Web2 application, which wants to token gate a certain segment on it's platform.

In this scenario, the application would have to verify if the user has that particular token or not, while verification of this process the user would have to reveal its wallet address to the application which is not good for user privacy.

The application thus decides to make use of Creds Protocol to allow the users to generate the Creds which the user can show as a proof and the application can then verify the same.

Let's code 🛸

 
// SPDX-License-Identifier: MIT
 
pragma solidity ^0.8.4;
 
import "@creds-protocol/contracts/interfaces/IVerifier.sol";
import "@creds-protocol/contracts/CredsProtocol.sol";
 
contract CredsIssuer is CredsProtocol {
 
    uint256 public credID;
 
    constructor(
        uint8 _treeDepth,
        IVerifier _verifier,
        bytes32 credName
    ) CredsProtocol(_treeDepth, _verifier) {
        credID = hashEventName(credName);
        createCred(credID, treeDepth, 0, msg.sender);
    }
}

Let us now add the functionality i.e claimCred() function to allow the user to claim the cred, this is where the developer needs to set the condition as to who is eligible to claim the cred.

In our scenario, we need to check the ownership of NFT, so let us import the required libraries and define the NFT contract address in the constructor and then finally set the eligibility condition inside the claimCred() function.

 
// SPDX-License-Identifier: MIT
 
pragma solidity ^0.8.4;
 
import "@creds-protocol/contracts/interfaces/IVerifier.sol";
import "@creds-protocol/contracts/CredsProtocol.sol";
import "@openzeppelin/contracts/token/ERC721/IERC721.sol";
 
contract CredsIssuer is CredsProtocol {
 
    uint256 public credID;
    IERC721 public tokenAddress;
 
    constructor(
        uint8 _treeDepth,
        IVerifier _verifier,
        bytes32 credName,
        address _tokenAddress
    ) CredsProtocol(_treeDepth, _verifier) {
        credID = hashEventName(credName);
        createCred(credID, treeDepth, 0, msg.sender);
        tokenAddress = IERC721(_tokenAddress); 
    }
 
    function claimCred(uint256 identityCommitment) public {
        // You can customize eligibility condition here
        require(tokenAddress.balanceOf(msg.sender) >= 1, "Eligibility condition failed");
        addIdentity(credID, identityCommitment);
    }
 
}

using verifier

 
// SPDX-License-Identifier: MIT
 
pragma solidity ^0.8.4;
 
import "@creds-protocol/contracts/interfaces/IVerifier.sol";
import "@creds-protocol/contracts/CredsProtocol.sol";
 
contract CredsIssuer is CredsProtocol {
 
    uint256 public credID;
 
    constructor(
        uint8 _treeDepth,
        IVerifier _verifier,
        bytes32 credName
    ) CredsProtocol(_treeDepth, _verifier) {
        credID = hashEventName(credName);
        createCred(credID, treeDepth, 0, msg.sender);
    }
 
    function claimCred(uint256 identityCommitment) public {
        // Add the condition for claiming the Cred here
        addIdentity(credID, identityCommitment);
    }
 
    function verifyCred(
        bytes32 signal,
        uint256 nullifierHash,
        uint256[8] calldata proof
    ) public view {
        uint256 root = creds[credID].root;
 
        _verifyProof(signal, root, nullifierHash, credID, proof, verifier);
    }
 
    function hashEventName(bytes32 eventId) private pure returns (uint256) {
        return uint256(keccak256(abi.encodePacked(eventId))) >> 8;
    }
}