Skip to main content

ZK Query Language

The Atomic Query Signature V2 Circuit and Atomic Query MTP V2 Circuit circuits have been designed as generic circuits to do the ZK verification based on users' claims.

The Query Language sits on top of these circuits to provide a simple way for developers to design customized authentication requirements for someone's credentials. As long as the user holds a credential of a specific type, the Verifier can design a query based on 6 operators, for example:

  • Must be a verified human to vote for a DAO specific proposal - equals (operator 1).
  • Must have been born before 2000-01-01 to access a specific website - less-than (operator 2).
  • Must have a monthly salary greater than $1000 to get a loan - greater-than (operator 3).
  • Must be an admin or a hacker of a DAO to enter a platform - ìn (operator 4).
  • Must not be a resident of a country in the list of blacklisted countries to operate on an exchange - not-in (operator 5).
  • Must not be a resident of a specific country - not-equal (operator 6).

The query is designed by the Verifier and presented to the user via a QR Code (or deep-linking). Starting from the proof generated by the user as a response to the query, the Verifier is easily able to check if the query is satisfied or not.

The Query Language follows the same rules whether the verification is implemented on-chain or off-chain, while the syntax to define these is a bit different. For each of the queries presented above, both the on-chain and off-chain way of designing will now be defined.

note

The entire scripts to set a query are available here: off-chain verification, on-chain verification

Equals - Operator 1

Credential Schema

The ProofOfHumanity Schema encodes whether a user has been verified as a human or not. Here's the JSON-LD Context of the Schema Type.

info

You can create customized schemas, check out this tutorial!

Query

When presented with this query, the user must prove that he/she is a Person.

  const proofRequest: protocol.ZKPRequest = {
id: 1,
circuitId: 'credentialAtomicQuerySigV2',
query: {
allowedIssuers: ['*'],
type: 'ProofOfHumanity',
context: 'https://raw.githubusercontent.com/0xPolygonID/tutorial-examples/main/credential-schema/schemas-examples/proof-of-humanity/proof-of-humanity.jsonld',
credentialSubject: {
isHuman: {
$eq: 1,
},
},
},
};

Corresponding QR Code


{
"id": "7f38a193-0918-4a48-9fac-36adfdb8b542",
"typ": "application/iden3comm-plain-json",
"type": "https://iden3-communication.io/proofs/1.0/contract-invoke-request",
"thid": "7f38a193-0918-4a48-9fac-36adfdb8b542",
"body": {
"reason": "airdrop participation",
"transaction_data": {
"contract address" : "<add your contract address here>", // replace with your contract address
"method_id": "b68967e2",
"chain_id": 80001,
"network": "polygon-mumbai"
},
"scope": [
{
"id": 1,
"circuitId": "credentialAtomicQuerySigV2OnChain",
"query": {
"allowedIssuers": [
"*"
],
"context": "https://raw.githubusercontent.com/0xPolygonID/tutorial-examples/main/credential-schema/schemas-examples/proof-of-humanity/proof-of-humanity.jsonld",
"credentialSubject": {
"isHuman": {
"$eq": 1
}
},
"type": "ProofOfHumanity"
}
}
]
}
}

Less-than - Operator 2

Credential Schema

The KYCAgeCredential Schema encodes the date of birth of the credential subject. Here's the JSON-LD Context of the Schema Type.

Query

When presented with this query, the user must prove that he/she has been born before 2001/01/01.

  const proofRequest: protocol.ZKPRequest = {
id: 1,
circuitId: 'credentialAtomicQuerySigV2',
query: {
allowedIssuers: ['*'],
type: 'KYCAgeCredential',
context: 'https://raw.githubusercontent.com/iden3/claim-schema-vocab/main/schemas/json-ld/kyc-v4.jsonld',
credentialSubject: {
birthday: {
$lt: 20010101,
},
},
},
};

Corresponding QR Code

{
"id": "7f38a193-0918-4a48-9fac-36adfdb8b542",
"typ": "application/iden3comm-plain-json",
"type": "https://iden3-communication.io/proofs/1.0/contract-invoke-request",
"thid": "7f38a193-0918-4a48-9fac-36adfdb8b542",
"body": {
"reason": "airdrop participation",
"transaction_data": {
"contract address" : "<add your contract address here>",
"method_id": "b68967e2",
"chain_id": 80001,
"network": "polygon-mumbai"
},
"scope": [
{
"id": 1,
"circuitId": "credentialAtomicQuerySigV2OnChain",
"query": {
"allowedIssuers": [
"*"
],
"context": "https://raw.githubusercontent.com/iden3/claim-schema-vocab/main/schemas/json-ld/kyc-v4.jsonld",
"credentialSubject": {
"birthday": {
"$lt": 20010101
}
},
"type": "KYCAgeCredential"
}
}
]
}
}

Greater-than - Operator 3

Credential Schema

The EmployeeData Schema encodes the monthly salary of the credential subject. Here's the JSON-LD Context of the Schema Type.

Query

When presented with this query, the user must prove that his/her monthly salary is greater than $1000.

  const proofRequest: protocol.ZKPRequest = {
id: 1,
circuitId: 'credentialAtomicQuerySigV2',
query: {
allowedIssuers: ['*'],
type: 'EmployeeData',
context: 'https://raw.githubusercontent.com/0xPolygonID/tutorial-examples/main/credential-schema/schemas-examples/employee-data/employee-data.jsonld',
credentialSubject: {
monthlySalary: {
$gt: 1000,
},
},
},
};

Corresponding QR Code

{
"id": "7f38a193-0918-4a48-9fac-36adfdb8b542",
"typ": "application/iden3comm-plain-json",
"type": "https://iden3-communication.io/proofs/1.0/contract-invoke-request",
"thid": "7f38a193-0918-4a48-9fac-36adfdb8b542",
"body": {
"reason": "airdrop participation",
"transaction_data": {
"contract address" : "<add your contract address here>",
"method_id": "b68967e2",
"chain_id": 80001,
"network": "polygon-mumbai"
},
"scope": [
{
"id": 1,
"circuitId": "credentialAtomicQuerySigV2OnChain",
"query": {
"allowedIssuers": [
"*"
],
"context": "https://raw.githubusercontent.com/0xPolygonID/tutorial-examples/main/credential-schema/schemas-examples/employee-data/employee-data.jsonld",
"credentialSubject": {
"monthlySalary": {
"$gt": 1000
}
},
"type": "EmployeeData"
}
}
]
}
}

In - Operator 4

Credential Schema

The ProofOfDaoRole Schema encodes the role of someone inside a DAO. Each role is identified by a code as described in the Schema Vocab.

Here's the JSON-LD Context of the Schema Type.

Query

When presented with this query, the user must prove that he/she is either an Admin or a Hacker of a DAO (which corresponds to values 4 and 5).

  const proofRequest: protocol.ZKPRequest = {
id: 1,
circuitId: 'credentialAtomicQuerySigV2',
query: {
allowedIssuers: ['*'],
type: 'ProofOfDaoRole',
context: 'https://raw.githubusercontent.com/0xPolygonID/tutorial-examples/main/credential-schema/schemas-examples/proof-of-dao-role/proof-of-dao-role.jsonld',
credentialSubject: {
role: {
$in: [4, 5],
},
},
},
};

Corresponding QR Code

{
"id": "7f38a193-0918-4a48-9fac-36adfdb8b542",
"typ": "application/iden3comm-plain-json",
"type": "https://iden3-communication.io/proofs/1.0/contract-invoke-request",
"thid": "7f38a193-0918-4a48-9fac-36adfdb8b542",
"body": {
"reason": "airdrop participation",
"transaction_data": {
"contract address" : "<add your contract address here>",
"method_id": "b68967e2",
"chain_id": 80001,
"network": "polygon-mumbai"
},
"scope": [
{
"id": 1,
"circuitId": "credentialAtomicQuerySigV2OnChain",
"query": {
"allowedIssuers": [
"*"
],
"context": "https://raw.githubusercontent.com/0xPolygonID/tutorial-examples/main/credential-schema/schemas-examples/proof-of-dao-role/proof-of-dao-role.jsonld",
"credentialSubject": {
"role": {
"$in": [4, 5]
}
},
"type": "ProofOfDaoRole"
}
}
]
}
}

Not-in - Operator 5

Credential Schema

The KYCCountryOfResidenceCredential Schema encodes the countryCode of residence of the credential subject according to the ISO Standard. Here's the JSON-LD Context of the Schema Type.

Query

When presented with this query, the user must prove that he/she is not a resident of the countries 840, 120, 340, 509 identified by the ISO Standard.

  const proofRequest: protocol.ZKPRequest = {
id: 1,
circuitId: 'credentialAtomicQuerySigV2',
query: {
allowedIssuers: ['*'],
type: 'KYCCountryOfResidenceCredential',
context: 'https://github.com/iden3/claim-schema-vocab/blob/main/schemas/json-ld/kyc-v4.jsonld',
credentialSubject: {
countryCode: {
$nin: [840, 120, 340, 509],
},
},
},
};

Corresponding QR Code

{
"id": "7f38a193-0918-4a48-9fac-36adfdb8b542",
"typ": "application/iden3comm-plain-json",
"type": "https://iden3-communication.io/proofs/1.0/contract-invoke-request",
"thid": "7f38a193-0918-4a48-9fac-36adfdb8b542",
"body": {
"reason": "airdrop participation",
"transaction_data": {
"contract address" : "<add your contract address here>",
"method_id": "b68967e2",
"chain_id": 80001,
"network": "polygon-mumbai"
},
"scope": [
{
"id": 1,
"circuitId": "credentialAtomicQuerySigV2OnChain",
"query": {
"allowedIssuers": [
"*"
],
"context": "https://raw.githubusercontent.com/iden3/claim-schema-vocab/main/schemas/json-ld/kyc-v4.jsonld",
"credentialSubject": {
"countryCode": {
"$nin": [840, 120, 340, 509]
}
},
"type": "KYCCountryOfResidenceCredential"
}
}
]
}
}

Not-equal - Operator 6

Credential Schema

The KYCCountryOfResidenceCredential Schema encodes the countryCode of residence of the credential subject according to the ISO Standard. Here's the JSON-LD Context of the Schema Type.

Query

When presented with this query, the user must prove that he/she is not a resident of the country 840 identified by the ISO Standard.

  const proofRequest: protocol.ZKPRequest = {
id: 1,
circuitId: 'credentialAtomicQuerySigV2',
query: {
allowedIssuers: ['*'],
type: 'KYCCountryOfResidenceCredential',
context: 'https://raw.githubusercontent.com/iden3/claim-schema-vocab/main/schemas/json-ld/kyc-v4.jsonld',
credentialSubject: {
countryCode: {
$ne: 840
},
},
},
};

Corresponding QR Code

{
"id": "7f38a193-0918-4a48-9fac-36adfdb8b542",
"typ": "application/iden3comm-plain-json",
"type": "https://iden3-communication.io/proofs/1.0/contract-invoke-request",
"thid": "7f38a193-0918-4a48-9fac-36adfdb8b542",
"body": {
"reason": "airdrop participation",
"transaction_data": {
"contract address" : "<add your contract address here>",
"method_id": "b68967e2",
"chain_id": 80001,
"network": "polygon-mumbai"
},
"scope": [
{
"id": 1,
"circuitId": "credentialAtomicQuerySigV2OnChain",
"query": {
"allowedIssuers": [
"*"
],
"context": "https://raw.githubusercontent.com/iden3/claim-schema-vocab/main/schemas/json-ld/kyc-v4.jsonld",
"credentialSubject": {
"countryCode": {
"$ne": 840
}
},
"type": "KYCCountryOfResidenceCredential"
}
}
]
}
}

Selective Disclosure

Selective Disclosure is a feature that enables requests for specific data from the ID Holder. Using a similar approach to the ZK language equal operation, the Verifier sends a verification request for a piece of the Holder's identity. As seen below, the way to make this request is by sending an empty object as a value.

Query

In the example below, the verifier requests the Holder's country code.

const proofRequest: protocol.ZKPRequest = {
id: 1,
circuitId: 'credentialAtomicQuerySigV2',
query: {
allowedIssuers: ['*'],
type: 'KYCCountryOfResidenceCredential',
context: 'https://raw.githubusercontent.com/iden3/claim-schema-vocab/main/schemas/json-ld/kyc-v4.jsonld',
credentialSubject: {
countryCode: {},
},
},
};
"Allowed Issuers"

When we use * in the "allowed issuers" segment (allowedIssuers: ['*']), we mean that we accept any entity that might have provided the credential. Even though this seems to be convenient for testing purposes, it may also be considered risky. Applying due diligence by actually choosing trusted specific issuers should be the best approach. Only in rare cases, a verifier would accept any issuer, so we advise not to use *.