Using verification registry proxies to improve web3 credential verification workflows

Last week, the Centre Consortium announced its new Verite project:

Verite provides an open architecture for facilitating the verification of credentials among decentralized apps. It is designed with particular use-cases in mind such as verifying that a user has completed KYC or an accreditation check, but it can be used for a wide range of credentials. Verite is designed to be private by design, minimizing the amount of personally identifiable information that needs to be shared outside of the credential setup process with an issuer such as an exchange.

The Verite documentation provides a helpful overview of patterns for issuing and verifying credentials, and implementing credential verification in a smart contract.

Smart Contract Patterns for Credential Verification

The section of the Verite documentation on smart contract patterns describes two primary patterns. The first is a Verifier Submission Pattern. To quote the documentation:

In the verifier submission pattern, a verifier executes the off-chain verification of a credential and then registers verification success with a registry smart contract. A relying decentralized application or other client never accesses the credential or the Verification Result.

After verification and registration, wallets, dapps, apps, and smart contracts can determine whether a given address has an active verification by executing a view (no cost) function on the registry contract containing the registration.

Illustration of Verifier Submission Workflow
Illustration of Verifier Submission Workflow

A variation of this pattern is also described in which a service that is completing ID verification and KYC directly submits a verification record to a registry, where it can be accessed by smart contracts. This combines the steps of setting up credentials with verifying those credentials and storing that verification record on-chain:

Verification within IDV/KYC process
Verification within IDV/KYC process

Regardless of how the verification records are made available on-chain, there are a couple of notable problems with verification registries as presented in the Verite docs. With the limited data structures available in Solidity, one contract must be used for each type of credential check and there may be dozens if not hundreds of on-chain verification registries. Smart contracts utilizing these records need to know in advance which smart contract address to use for the verification. Even if a smart contract is able to have its code updated or is designed to allow an admin to specify new registries to use, this creates a potentially significant maintenance burden for the smart contract developer.

The other problem with verification registries is that there is likely to not be a single registry used by all smart contracts . This is a good thing from the perspective of not allowing dependencies of smart contracts to become overly centralized, but users are likely to need to have credentials on different registries and as a result set up credentials with multiple issuers and have them verified separately. At best this is poor UX that does not minimize the sharing of personally identifiable information, and at worst it could be a vector for bad actors to maliciously collect PII under the guise of being a legitimate KYC or accreditation checking process.

The Verite documentation does describe an alternative to verification registries in the form of the Subject Submission Pattern:

In the subject submission pattern, a dapp still utilizes an off-chain verifier for verification, but the verifier does not directly register the result with a smart contract. Instead, the verifier returns the Verification Result and its signature to the subject, and the subject passes the Verification Result and verifier’s signature to a smart contract's custom function, which can validate the result in addition to other logic in the same transaction.

This pattern does not require the use of an on-chain verification registry, but it requires custom functions for additional parameters for verification data provided by the user, and as a result the pattern breaks compatibility with ERC-20 and other common standards that almost all token contracts and wallets use.

Proposing Verification Registry Proxies

This post briefly describes a proposal for how to simultaneously accomplish the following outcomes:

  • Smart contract compatibility with ERC-20, ERC-721, and other common standards.
  • Smart contract developers implementing credential verification without needing to maintain their own updated mappings of various verification registries to support.
  • Dapp users being able to have choice over which issuer they would like to use for setting up credentials and not needing to set up credentials with multiple issuers.
  • Supporting the principles of the Verite project including minimizing the number of times PII must be shared, and the over-reliance on a single credential issuer.

The Verification Registry Proxy Pattern is a modified version of the Verifier Submission Pattern in which the smart contract makes a call to a verification registry proxy contract setup for a particular type of credential, such as credentials verifying whether the address is associated with a user who has completed KYC or an investor accreditation check. These proxy contracts allow for users to specify with which registry out of a number of supported registries they have verified. This specification could also be provided by the verifier uploading the verification record to the chosen registry so the user does not need to perform a separate transaction to specify this information. The registries supported by the proxy are determined by the contract administrator, which could be an organization such as a DAO or an individual.

Illustration of modified smart contract workflow with registry proxy
Illustration of modified smart contract workflow with registry proxy

Just like with the Subject Submission Pattern, users are able to use their choice of verifier, and presumably issuer as well. But no additional parameters are needed in transactions to transfer tokens are perform other common actions, as this choice has been previously specified to the registry proxy.

The proxy pattern also enables a variety of other possibilities. For example, a contract developer may need to check that a user has completed KYC, but is willing to accept the completion of an investor accreditation check as being equivalent to having completed KYC. In a variation that would be more practically easy to implement for contract developers, they would be willing to delegate this type of nuanced decision making to the DAO managing the registry proxy they are using. The proxy pattern enables contract developers to accomplish outcomes such as being in regulatory compliance in a straightforward way that does not require specialized expertise.

The smart contract utilizing a registry proxy can use code identical to that of how it would normally verify credentials with a verification registry:

    function _validCounterparty(address registryAddress) private view returns (bool) {
        return kycRegistry.isVerified(registryAddress);

Instead of kycRegistry mapping to a verification registry address, it would simply map to a registry proxy address instead.

A follow up to this post will include example solidity code demonstrating how a verification registry proxy could be implemented, and additional considerations and potential improvements that could be made to the pattern.

Subscribe to TapTrust
Receive the latest updates directly to your inbox.
This entry has been permanently stored onchain and signed by its creator.