Skip to content

Commit

Permalink
Merge pull request #129 from 0xPolygonID/feature/changelog-beta-0-1
Browse files Browse the repository at this point in the history
beta.1 upgrade
  • Loading branch information
vmidyllic authored Mar 27, 2024
2 parents ab1bbdd + 9f0c5eb commit 349be5c
Show file tree
Hide file tree
Showing 7 changed files with 645 additions and 113 deletions.
38 changes: 31 additions & 7 deletions docs/smart-contracts.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,17 @@ Check a contract codebase and algorithms of work <ins>[docs](https://docs.iden3.

## Validator addresses


Current addresses on Polygon Mumbai testnet. (V2.0.0 V2 validators)

| | Sig | MTP |
|:-----------------:|:-----------------------------------------------------------:|:------------------------------------------------------------:|
| **Verifier** | 0x81ef49013627F363570a1C60B0D2215E23651B01 | 0xe5DB0489979C5671D9785cF1cBA9D9028041c9Bf |
| **Validators** | 0x59f2a6D94D0d02F3a2F527a8B6175dc511935624 | 0xb9b51F7E8C83C90FE48e0aBd815ef0418685CcF6 |
| **ERC20 example** | 0x3a4d4E47bFfF6bD0EF3cd46580D9e36F3367da03 (request id = 1) | 0x3a4d4E47bFfF6bD0EF3cd46580D9e36F3367da03 (request id = 2) |



Current addresses on Polygon Mumbai testnet. (V1.0.1)

| | Sig | MTP |
Expand All @@ -33,6 +44,18 @@ Current addresses on Polygon Mumbai testnet. (V1.0.1)
| **Validators** | 0x1E4a22540E293C0e5E8c33DAfd6f523889cFd878 | 0x0682fbaA2E4C478aD5d24d992069dba409766121 |
| **ERC20 example** | 0xD75638D319B1aE2a9491DC61f87a800AD362D168 (request id = 1) | 0xD75638D319B1aE2a9491DC61f87a800AD362D168 (request id = 2) |



Current addresses on Polygon Main

(V2.0.0 V2 validators)

| | Sig | MTP |
|:-----------------:|:-----------------------------------------------------------------:|:-----------------------------------------------------------------:|
| **Verifier** | 0xa0495df44ABBDbfCD1da30638869A3307BF21532 | 0x068b3dDE10b55643b55aA4820c7a977dEEEc3c07 |
| **Validators** | 0xEF8540a5e0F4f53B436e7C3A273dCAe1C05d764D | 0x03Ee09635E9946165dd9538e9414f0ACE57e42e1 |
| **ERC20 example** | 0xB9Ac8e785f854f9B76bBF6d495213d58226DE813 (request id = 1 (sig)) | 0xB9Ac8e785f854f9B76bBF6d495213d58226DE813 (request id = 2 (mtp) |

Current addresses on Polygon Main (V1.0.1)

| | Sig | MTP |
Expand Down Expand Up @@ -81,14 +104,15 @@ Features of v3 validator:
- ethereum controlled identities support
- selective disclosure support

Current addresses for V3 beta circuit on Polygon Mumbai testnet. (1.0.0-beta.0 V3 validator)
Current addresses for V3 beta circuit on Polygon Mumbai testnet. (2.0.0-beta.1 V3 validator)

| | V3 validator 2.0.0-beta.1 |
|:--------------------:|:-----------------------------------------------------------------------------------------------------------:|
| **Verifier** | 0xDE27fc243Bf4eDAaB72E1008c9828C480582f672 |
| **Validators** | 0x3412AB64acFf5d94Da4914F176A43aCbDdC7Fc4a |
| **ERC20 SD example** | 0x36eB0E70a456c310D8d8d15ae01F6D5A7C15309A (request id = 3) |
| **ERC20 ** | 0x36eB0E70a456c310D8d8d15ae01F6D5A7C15309A (request id = 100 - 1100 merklized / 10000 - 65000 nonmerklized |

| | V3 validator 1.0.0-beta.0 |
| :------------------: | :------------------------------------------------------------------------------------------------------------------------------: |
| **Verifier** | 0x3dE74ffCf9Fc0AA6c9fD73b511342a0E653B4129 |
| **Validators** | 0xCBde9B14fcF5d56B709234528C44798B4ea64761 |
| **ERC20 SD example** | 0xD0Fd3E9fDF448e5B86Cc0f73E5Ee7D2F284884c0 (request id = 3) |
| **ERC20 ** | 0xD0Fd3E9fDF448e5B86Cc0f73E5Ee7D2F284884c0 (request id = 100 - 650 merklized (step 50) / 10000 - 65000 nonmerklized (step 5000)) |

:::note
More about <ins>[v3 circuit](./verifier/v3-circuit)</ins>.
Expand Down
135 changes: 97 additions & 38 deletions docs/verifier/on-chain-verification/overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,24 +73,38 @@ The ERC20Verifier is an ERC20 standard contract with a few other features. The e
The ERC20Verifier contract must define at least a single `TRANSFER_REQUEST_ID`. This is the Identifier of the request that the contract is making to the user.

```solidity
pragma solidity ^0.8.16;
pragma solidity 0.8.20;
import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import {ERC20Upgradeable} from '@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol';
import {PrimitiveTypeUtils} from "@iden3/contracts/lib/PrimitiveTypeUtils.sol";
import {ICircuitValidator} from "@iden3/contracts/interfaces/ICircuitValidator.sol";
import {ZKPVerifier} from "@iden3/contracts/verifiers/ZKPVerifier.sol";
contract ERC20Verifier is ERC20, ZKPVerifier {
contract ERC20Verifier is ERC20Upgradeable, ZKPVerifier {
uint64 public constant TRANSFER_REQUEST_ID = 1;
// define the amount of token to be airdropped per user
uint256 public TOKEN_AMOUNT_FOR_AIRDROP_PER_ID = 5 * 10**uint(decimals());
mapping(uint256 => address) public idToAddress;
mapping(address => uint256) public addressToId;
uint256 public TOKEN_AMOUNT_FOR_AIRDROP_PER_ID;
constructor(
string memory name_,
string memory symbol_
) ERC20(name_, symbol_) {}
modifier beforeTransfer(address to) {
MainStorage storage s = _getMainStorage();
require(
s.proofs[to][TRANSFER_REQUEST_ID] == true,
"only identities who provided proof are allowed to receive tokens"
);
_;
}
function initialize(
string memory name,
string memory symbol
) public initializer {
super.__ERC20_init(name, symbol);
super.__ZKPVerifier_init(_msgSender());
TOKEN_AMOUNT_FOR_AIRDROP_PER_ID = 5 * 10 ** uint256(decimals());
}
}
```

Expand All @@ -103,27 +117,39 @@ In this specific case, it must be checked that the sender of the proof matches t
The airdrop logic must be added inside `_afterProofSubmit`. The contract must execute the airdrop once the proof is correctly verified.

```solidity {4, 5, 13, 14, 15, 16, 17, 28, 29, 30, 31, 32}
contract ERC20Verifier is ERC20, ZKPVerifier {
contract ERC20Verifier is ERC20Upgradeable, ZKPVerifier {
uint64 public constant TRANSFER_REQUEST_ID = 1;
mapping(uint256 => address) public idToAddress;
mapping(address => uint256) public addressToId;
uint256 public TOKEN_AMOUNT_FOR_AIRDROP_PER_ID =
5 * 10 ** uint256(decimals());
uint256 public TOKEN_AMOUNT_FOR_AIRDROP_PER_ID;
modifier beforeTransfer(address to) {
MainStorage storage s = _getMainStorage();
require(
s.proofs[to][TRANSFER_REQUEST_ID] == true,
"only identities who provided proof are allowed to receive tokens"
);
_;
}
constructor(
string memory name_,
string memory symbol_
) ERC20(name_, symbol_) {}
function initialize(
string memory name,
string memory symbol
) public initializer {
super.__ERC20_init(name, symbol);
super.__ZKPVerifier_init(_msgSender());
TOKEN_AMOUNT_FOR_AIRDROP_PER_ID = 5 * 10 ** uint256(decimals());
}
function _beforeProofSubmit(
uint64 /* requestId */,
uint256[] memory inputs,
ICircuitValidator validator
) internal view override {
// check that challenge input is address of sender
address addr = PrimitiveTypeUtils.int256ToAddress(
address addr = PrimitiveTypeUtils.uint256LEToAddress(
inputs[validator.inputIndexOf("challenge")]
);
// this is linking between msg.sender and
Expand Down Expand Up @@ -156,50 +182,80 @@ contract ERC20Verifier is ERC20, ZKPVerifier {
}
```

Finally, we can add a further element of security inside the Smart Contract: prevent any type of token transfer (even after the airdrop) unless users passed the proof verification. This last condition is added by overriding the ERC20 `_beforeTokenTransfer` function and checking that the receiver address `to` of the transfer is included inside the
Finally, we can add a further element of security inside the Smart Contract: prevent any type of token transfer (even after the airdrop) unless users passed the proof verification. This last condition is added by overriding the ERC20 `_update` function and checking that the receiver address `to` of the transfer is included inside the
<a href="https://github.com/iden3/contracts/blob/master/contracts/verifiers/ZKPVerifier.sol#L28" target="_blank">`proofs`</a> mapping.

```solidity {29, 30, 31, 32, 33}
contract ERC20Verifier is ERC20, ZKPVerifier {
contract ERC20Verifier is ERC20Upgradeable, ZKPVerifier {
uint64 public constant TRANSFER_REQUEST_ID = 1;
mapping(uint256 => address) public idToAddress;
mapping(address => uint256) public addressToId;
uint256 public TOKEN_AMOUNT_FOR_AIRDROP_PER_ID =
5 * 10 ** uint256(decimals());
uint256 public TOKEN_AMOUNT_FOR_AIRDROP_PER_ID;
modifier beforeTransfer(address to) {
MainStorage storage s = _getMainStorage();
require(
s.proofs[to][TRANSFER_REQUEST_ID] == true,
"only identities who provided proof are allowed to receive tokens"
);
_;
}
constructor(
string memory name_,
string memory symbol_
) ERC20(name_, symbol_) {}
function initialize(
string memory name,
string memory symbol
) public initializer {
super.__ERC20_init(name, symbol);
super.__ZKPVerifier_init(_msgSender());
TOKEN_AMOUNT_FOR_AIRDROP_PER_ID = 5 * 10 ** uint256(decimals());
}
function _beforeProofSubmit(
uint64 /* requestId */,
uint256[] memory inputs,
ICircuitValidator validator
) internal view override {
...
// check that challenge input is address of sender
address addr = PrimitiveTypeUtils.uint256LEToAddress(
inputs[validator.inputIndexOf("challenge")]
);
// this is linking between msg.sender and
require(
_msgSender() == addr,
"address in proof is not a sender address"
);
}
function _afterProofSubmit(
uint64 requestId,
uint256[] memory inputs,
ICircuitValidator validator
) internal override {
...
require(
requestId == TRANSFER_REQUEST_ID && addressToId[_msgSender()] == 0,
"proof can not be submitted more than once"
);
// get user id
uint256 id = inputs[1];
// additional check didn't get airdrop tokens before
if (idToAddress[id] == address(0) && addressToId[_msgSender()] == 0) {
super._mint(_msgSender(), TOKEN_AMOUNT_FOR_AIRDROP_PER_ID);
addressToId[_msgSender()] = id;
idToAddress[id] = _msgSender();
}
}
function _beforeTokenTransfer(
address /* from */,
function _update(
address from /* from */,
address to,
uint256 /* amount */
) internal view override {
require(
proofs[to][TRANSFER_REQUEST_ID] == true,
"only identities who provided proof are allowed to receive tokens"
);
uint256 amount /* amount */
) internal override beforeTransfer(to) {
super._update(from, to, amount);
}
}
```

Expand All @@ -222,7 +278,10 @@ async function main() {
const verifierSymbol = "zkERC20";

const ERC20Verifier = await ethers.getContractFactory(verifierContract);
const erc20Verifier = await ERC20Verifier.deploy(verifierName, verifierSymbol);
const erc20Verifier = await upgrades.deployProxy(
ERC20Verifier,
[verifierName, verifierSymbol]
);

await erc20Verifier.deployed();
console.log(verifierName, " contract address:", erc20Verifier.address);
Expand Down Expand Up @@ -389,7 +448,7 @@ function coreSchemaFromStr(schemaIntString) {
return SchemaHash.newSchemaHashFromInt(schemaInt);
}

function calculateQueryHash(values, schema, slotIndex, operator, claimPathKey, claimPathNotExists) {
function calculateQueryHashV2(values, schema, slotIndex, operator, claimPathKey, claimPathNotExists) {
const expValue = prepareCircuitArrayValues(values, 64);
const valueHash = poseidon.spongeHashX(expValue, 6);
const schemaHash = coreSchemaFromStr(schema);
Expand Down Expand Up @@ -429,7 +488,7 @@ async function main() {
claimPathNotExists: 0,
};

query.queryHash = calculateQueryHash(
query.queryHash = calculateQueryHashV2(
query.value,
query.schema,
query.slotIndex,
Expand Down
19 changes: 13 additions & 6 deletions docs/verifier/query-builder.md
Original file line number Diff line number Diff line change
Expand Up @@ -128,24 +128,31 @@ Providing a nullifier session ID ensures the query's integrity and uniqueness, c

### Query Type

The protocol allows selection between two query types:
The protocol allows selection between three query types:

1. **Condition:** This type allows the prover to demonstrate that a specific condition is met without revealing the underlying data. It maintains data privacy by cryptographically verifying the condition. An example is proving legal age for entry into a venue without disclosing the actual age.

2. **Selective disclosure:** Use this when you need the prover to reveal specific data stored in their credential. This option discloses the actual value of an attribute to the verifier. For instance, instead of just requesting proof proving legal age, it would disclose the prover's actual age to the verifier.

Choose "Condition" for privacy-preserving verification, or "Selective disclosure" for cases where revealing specific information is necessary.
3. **Credential issued:** Use this when you need the prove that credential with a specific type has been issued, but not to reveal any information.

Choose "Condition" for privacy-preserving verification, "Selective disclosure" for cases where revealing specific information is necessary, "Credential issued" when you need to ensure the fact of credential issuance.

### Operator

In conditional queries, the "Operator" input defines the logical operation to be applied. The supported operators are:

- **Equal:** Checks if the value is equal to the specified value.
- **Not Equal:** Verifies if the value is not equal to the specified value.
- **Less Than:** Assesses that the value is less than the given value.
- **Greater Than:** Evaluates if the value is greater than the specified value.
- **Is equal to:** Checks if the value is equal to the specified value.
- **Is not equal to:** Verifies if the value is not equal to the specified value.
- **Matches one of the values:** Determines if the value is within a given set of values.
- **Matches none of the values:** Checks if the value is not within a specified set.
- **Is less than:** Assesses that the value is less than the given value.
- **Is greater than:** Evaluates if the value is greater than the specified value.
- **Is less than or equal to:** Assesses that the value is less than the given value or equal to it.
- **Is greater than or equal to:** Assesses that the value is greater than the given value or equal to it.
- **Falls within the range:** Checks if the value is in the specified range, including corner values.
- **Falls outside the range:** Checks if the value is not in the specified range, including corner values.
- **Exists:** Checks if the specific field is included or not in the Verifiable Credential (for optional attributes).

Choose the appropriate operator based on the condition you want to validate.

Expand Down
29 changes: 23 additions & 6 deletions docs/verifier/v3-circuit.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,27 @@ We want to introduce new circuits - СredentialAtomicQueryV3 and CredentialAtomi
:::warning

Circuits are in the beta version. Trusted setup will be performed in the next release.
Current Circuit id is `СredentialAtomicQueryV3-beta.0`
Newest version is СredentialAtomicQueryV3-beta.1

<details><summary>Changelog from beta.0 to beta.1</summary>


1. ValueArrSize input is introduced, which fixes behaviour for IN / NIN operations.
2. Exists / Noop / Less Than Or Equal / Greater Than or Equal / Not between / Between operators support.
3. Query hash calculation algorithm changes.
4. Constraints and security optimizations.

</details>


:::

More about new supported operators [here](./verification-library/zk-query-language.md#exists---operator-11).

Link to latest sdk circuit wrappers: [js](https://github.com/0xPolygonID/js-sdk/pull/181) / [go](https://github.com/iden3/go-circuits/releases/tag/v2.1.0)



In general it's an improved version of V2 circuits with several important key features:

1. SIG and MTP checks are united in single circuit. Now you can use only one circuit without sig/mtp suffixes. Proof will be taken from user wallet and authorization response will contain information about verifiable credential proof type which has been used. It is possible to request the needed proof from user by using `proofType` property in the authorization request message. Possible values are `Iden3SparseMerkleTreeProof` and `BJJSignature2021`. If `proofType` is not provided - available proof will be used. In case there are two proofs available - MTP will be used as more prior.
Expand All @@ -31,7 +48,7 @@ In general it's an improved version of V2 circuits with several important key fe
"scope": [
{
"id": 1,
"circuitId": "credentialAtomicQueryV3-beta.0",
"circuitId": "credentialAtomicQueryV3-beta.1",
"query": {
...
"proofType": "BJJSignature2021 | Iden3SparseMerkleTreeProof"
Expand All @@ -50,7 +67,7 @@ In general it's an improved version of V2 circuits with several important key fe
"scope": [
{
"id": 1,
"circuitId": "credentialAtomicQueryV3-beta.0",
"circuitId": "credentialAtomicQueryV3-beta.1",
"params": {
"nullifierSessionId" : "123443290439234342342423423423423"
},
Expand Down Expand Up @@ -84,7 +101,7 @@ Beta Validator is also deployed: [Repository](https://github.com/0xPolygonID/con
"scope": [
{
"id": 1,
"circuitId": "credentialAtomicQueryV3-beta.0",
"circuitId": "credentialAtomicQueryV3-beta.1",
"query": {
"groupId": 1
...
Expand Down Expand Up @@ -125,7 +142,7 @@ Example of complex request with v3 circuit proof request:
"scope": [
{
"id": 1,
"circuitId": "credentialAtomicQueryV3-beta.0",
"circuitId": "credentialAtomicQueryV3-beta.1",
"params": {
"nullifierSessionId": "123443290439234342342423423423423"
},
Expand All @@ -144,7 +161,7 @@ Example of complex request with v3 circuit proof request:
},
{
"id": 2,
"circuitId": "credentialAtomicQueryV3-beta.0",
"circuitId": "credentialAtomicQueryV3-beta.1",
"query": {
"allowedIssuers": ["*"],
"groupId": 1,
Expand Down
Loading

0 comments on commit 349be5c

Please sign in to comment.