Skip to content

Receptor Smart Contract Example

The below is an example of a smart contract that implement's an example business's eligibility criteria through Proof by Query.

  • Criteria: the user is born before 01/01/2002
  • Credential: a DrivingLicenceCredential with an attribute birthDate.

The schema is published at https://redbellynetwork.github.io/did-schema/driversLicence/credential/v1.jsonld

Request

The eligibility criteria in the example are surfaced to the user in the form of a request.

const CR = {
  id: 7,
  circuitId: "credentialAtomicQueryMTPV2OnChain",
  query: {
    allowedIssuers: ["*"],
    type: "DriversLicenceCredential",
    context: "https://redbellynetwork.github.io/did-schema/driversLicence/credential/v1.jsonld",
    credentialSubject: {
      birthDate: {
        $lt: 20020101,
      },
    },
  },
};

How eligibility criteria can be used

The ZKPVerifier Contract has two hooks: _beforeProofSubmit and _afterProofSubmit. These hooks refer to functions or events that are triggered just before and after the submission of a zero-knowledge proof (ZKP) in the ZKPVerifier contract. They provide the flexibility to customise the behaviour of the contract to suit specific requirements.

  • _beforeProofSubmit: This hook is called just before the submission of the ZKP proof. It allows you to perform any custom logic, checks, or modifications to the contract state before the proof is submitted. This can be useful for tasks such as validating additional conditions, updating variables, or verifying the authenticity of supporting data.

  • _afterProofSubmit: This hook is triggered right after the submission of the ZKP proof. It allows you to perform any actions, updates, or events in response to the successful submission of the proof. This could include updating records, emitting events, or triggering further processes based on the outcome of the proof submission.

Example contract code

The example contract below triggers an event to indicate either successful or unsuccessful verification.

BusinessSmartContract.sol
pragma solidity ^0.8.16;

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@iden3/contracts/verifiers/ZKPVerifier.sol";

/**
 * @title BusinessSmartContract
 * @dev A smart contract that extends ERC20 and implements a Zero-Knowledge Proof (ZKP) verification mechanism.
 *      Users can submit proofs, and the contract emits an event based on the success or failure of the verification.
 */
contract BusinessSmartContract is ERC20, ZKPVerifier {
    mapping(address => bool) public verifiedUsers;

    /**
     * @dev Emitted when a proof is verified.
     * @param value The requestId associated with the proof.
     * @param user The address of the user who submitted the proof.
     * @param message The verification result message ("Verification succeeded!" or "Verification failed!").
     */
    event ProofVerification(uint64 value, address user, string message);

    /**
     * @dev Constructor to initialise the ERC20 token with the name "RBNT" and symbol "RBNT".
     */
    constructor() ERC20("RBNT", "RBNT") {}

    /**
     * @dev Internal function called before submitting a proof for validation.
     * @param requestId The unique identifier for the proof.
     * @param inputs The array of inputs for the proof.
     * @param validator The circuit validator for the proof.
     */
    function _beforeProofSubmit(
        uint64 /* requestId */,
        uint256[] memory inputs,
        ICircuitValidator validator
    ) internal view override {}

    /**
     * @dev Internal function called after submitting a proof for validation.
     * @param requestId The unique identifier for the proof.
     * @param inputs The array of inputs for the proof.
     * @param validator The circuit validator for the proof.
     */
    function _afterProofSubmit(
        uint64 requestId,
        uint256[] memory inputs,
        ICircuitValidator validator
    ) internal override {
        if (proofs[msg.sender][requestId]) { 
            emit ProofVerification(
                requestId,
                msg.sender,
                "Verification succeeded!"
            );
        } else {
            emit ProofVerification(
                requestId,
                msg.sender,
                "Verification failed!"
            );
        }
    }
}