Skip to main content

Proof of Humanity smart contracts reference

To make the Proof of Humanity verification result easily re-usable and to enable easy integration with existing DApps like quest platforms, each verified user gets a soulbound token(SBT).

This is facilitated by the smart contracts described below.

VerifiedSBT

The SBT awarded to users who complete the Proof of Humanity verification.

Deployments

ChainChainIDAddress
Polygon1370xaD7De01cb7eaAFf3a419A0a0a3133a964cD90373 (Polygonscan)
Goerli50xfaA7e7F14a2dCAD537d0141533bB58D62dD8022c (Etherscan)

Interface

contract VerifiedSBT is
IVerifiedSBT,
UUPSUpgradeable,
ERC721EnumerableUpgradeable,
OwnableUpgradeable
{
// ...

address public override verifier;
uint256 public override nextTokenId;
string public override tokensURI;

modifier onlyVerifier() {
require(msg.sender == verifier, "VerifiedSBT: only verifier can call this function");
_;
}

function mint(address recipientAddr_) external override onlyVerifier {
_mint(recipientAddr_, nextTokenId++);
}

// ...
}
  • verifier - address of the verifier's (SBTIdentityVerifier) contract;
  • nextTokenId - nonce that is incremented each time a new SBT is created;
  • tokensURI - token's picture URI;
  • onlyVerifier() - modifier that only allows calls by the verifier contract;
  • mint(address) - mints the SBT for the given address;

See VerifiedSBT.sol for the full implementation.

SBTIdentityVerifier

It's an implementation of a verifier contract that mints a Proof of Humanity SBT when a correct proof is provided.

Deployments

ChainChainIDAddress
Polygon1370x7DdAde70efADf832A600ba483FAD26fCA477FE2A (Polygonscan)
Goerli50x86906AbAAfA7F58Fb4D3125BD1971Fcf04F52CDd (Etherscan)

Interface

contract SBTIdentityVerifier is ISBTIdentityVerifier, BaseVerifier {
function _proveIdentity(ProveIdentityParams calldata proveIdentityParams_) internal {
_verify(SBT_IDENTITY_PROOF_QUERY_ID, proveIdentityParams_);

require(
addressToIdentityId[msg.sender] == 0,
"IdentityVerifier: Msg sender address has already been used to prove the another identity."
);

IQueryValidator queryValidator_ = IQueryValidator(
zkpQueriesStorage.getQueryValidator(SBT_IDENTITY_PROOF_QUERY_ID)
);

uint256 identityId_ = proveIdentityParams_.inputs[queryValidator_.getUserIdIndex()];

require(
!isIdentityProved(identityId_),
"IdentityVerifier: Identity has already been proven."
);

uint256 newTokenId_ = sbtToken.nextTokenId();
sbtToken.mint(msg.sender);

addressToIdentityId[msg.sender] = identityId_;
_identitiesProofInfo[identityId_] = SBTIdentityProofInfo(msg.sender, newTokenId_, true);

emit SBTIdentityProved(identityId_, msg.sender, address(sbtToken), newTokenId_);
}
}
  • _proveIdentity(...) checks the validity for a ZKP and mints an SBT;

See SBTIdentityVerifier.sol for the full implementation.