Skip to content

Commit

Permalink
Merge pull request #34 from 0xPolygonID/fix/upgrade-codebase-and-deps
Browse files Browse the repository at this point in the history
upgrade onchain demo
  • Loading branch information
vmidyllic authored Jun 5, 2024
2 parents 4e77561 + 6a8786b commit e865bc0
Show file tree
Hide file tree
Showing 12 changed files with 179 additions and 45,499 deletions.
4 changes: 2 additions & 2 deletions on-chain-verification/.env.sample
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Alchemy: https://alchemy.com/?r=zU2MTQwNTU5Mzc2M
# How to export private key from Metamask: https://metamask.zendesk.com/hc/en-us/articles/360015289632-How-to-export-an-account-s-private-key

ALCHEMY_MUMBAI_URL=https://polygon-mumbai.g.alchemy.com/v2/YourAlchemyApiKey
MUMBAI_PRIVATE_KEY=YourPrivateKey
ALCHEMY_AMOY_URL=https://polygon-mumbai.g.alchemy.com/v2/YourAlchemyApiKey
AMOY_PRIVATE_KEY=YourPrivateKey
10 changes: 5 additions & 5 deletions on-chain-verification/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,15 @@ This tutorial uses [Hardhat](https://hardhat.org/) as a development environment
`npx hardhat compile`

4. Deploy smart contracts
`npx hardhat run --network mumbai scripts/deploy.js`
- results in x tx hash: 0xecf178144CceC09417412D66E2ecC8a2841eE228
- example contract creation: https://mumbai.polygonscan.com/address/0xecf178144ccec09417412d66e2ecc8a2841ee228
`npx hardhat run --network amoy scripts/deploy.js`
- console should log output similar to `ERC20zkAirdrop contract address: 0x365D13748BEBcDaFEE12Fa18eA653f4E168A190c` with different address.
- example contract creation: https://amoy.polygonscan.com/tx/0x1102ccb5d1e322c0bdf32d590695f3a70f7e2128061ee4325413297ff88034e8

5. Update the `ERC20VerifierAddress` variable in scripts/set-request.js with your deployed contract address

6. Run set-request to send the zk request to the smart contract
`npx hardhat run --network mumbai scripts/set-request.js`
- Successful tx means the age query has been set up: https://mumbai.polygonscan.com/tx/0x2ddb2db7b3d35cf7cdf658209b257fd2a51c49df2249bf46ede8979eb8410ffb
`npx hardhat run --network amoy scripts/set-request.js`
- Successful tx means the age query has been set up: https://amoy.polygonscan.com/tx/0x98e83a2aad5d41dc44fa03e0524848aeeabc8963ab36599fc3a0c8824d7ef722


## Claim airdrop from a frontend
Expand Down
90 changes: 47 additions & 43 deletions on-chain-verification/contracts/ERC20Verifier.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,67 +4,58 @@ pragma solidity 0.8.20;
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";
import {EmbeddedZKPVerifier} from "@iden3/contracts/verifiers/EmbeddedZKPVerifier.sol";

contract ERC20Verifier is ERC20Upgradeable, ZKPVerifier {
contract ERC20Verifier is ERC20Upgradeable, EmbeddedZKPVerifier {
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;
/// @custom:storage-location erc7201:polygonid.storage.ERC20Verifier
struct ERC20VerifierStorage {
mapping(uint256 => address) idToAddress;
mapping(address => uint256) addressToId;
uint256 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"
isProofVerified(to, TRANSFER_REQUEST_ID),
'only identities who provided proof for transfer requests are allowed to receive tokens'
);
_;
}
// keccak256(abi.encode(uint256(keccak256("polygonid.storage.ERC20Verifier")) - 1)) & ~bytes32(uint256(0xff))
bytes32 private constant ERC20VerifierStorageLocation =
0x3b1c3bd751d9cd42a3739426a271cdc235017946663d56eeaf827d70f8b77000;

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 _getERC20VerifierStorage() private pure returns (ERC20VerifierStorage storage $) {
assembly {
$.slot := ERC20VerifierStorageLocation
}
}

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 initialize(string memory name, string memory symbol) public initializer {
ERC20VerifierStorage storage $ = _getERC20VerifierStorage();
super.__ERC20_init(name, symbol);
super.__EmbeddedZKPVerifier_init(_msgSender());
$.TOKEN_AMOUNT_FOR_AIRDROP_PER_ID = 5 * 10 ** uint256(decimals());
}

function _afterProofSubmit(
uint64 requestId,
uint256[] memory inputs,
ICircuitValidator validator
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();
ERC20VerifierStorage storage $ = _getERC20VerifierStorage();
if (
requestId == TRANSFER_REQUEST_ID
) {
// if proof is given for transfer request id and it's a first time we mint tokens to sender
uint256 id = inputs[1];
if ($.idToAddress[id] == address(0) && $.addressToId[_msgSender()] == 0) {
super._mint(_msgSender(), $.TOKEN_AMOUNT_FOR_AIRDROP_PER_ID);
$.addressToId[_msgSender()] = id;
$.idToAddress[id] = _msgSender();
}
}
}

Expand All @@ -76,4 +67,17 @@ contract ERC20Verifier is ERC20Upgradeable, ZKPVerifier {
super._update(from, to, amount);
}


function getIdByAddress(address addr) public view returns (uint256) {
return _getERC20VerifierStorage().addressToId[addr];
}

function getAddressById(uint256 id) public view returns (address) {
return _getERC20VerifierStorage().idToAddress[id];
}

function getTokenAmountForAirdropPerId() public view returns (uint256) {
return _getERC20VerifierStorage().TOKEN_AMOUNT_FOR_AIRDROP_PER_ID;
}

}
10 changes: 5 additions & 5 deletions on-chain-verification/hardhat.config.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
require('@nomiclabs/hardhat-waffle');
require('dotenv').config();
require('@openzeppelin/hardhat-upgrades');
require('@nomicfoundation/hardhat-toolbox');

module.exports = {
solidity: "0.8.20",
networks: {
mumbai: {
chainId: 80001,
url: `${process.env.ALCHEMY_MUMBAI_URL}`,
accounts: [`0x${process.env.MUMBAI_PRIVATE_KEY}`]
amoy: {
chainId: 80002,
url: `${process.env.ALCHEMY_AMOY_URL}`,
accounts: [`0x${process.env.AMOY_PRIVATE_KEY}`]
}
}
};
Loading

0 comments on commit e865bc0

Please sign in to comment.