From 94de78d1d481e9ab6320a12d963edaa3ceec7140 Mon Sep 17 00:00:00 2001 From: nicoshark Date: Wed, 19 Feb 2025 13:51:20 +0900 Subject: [PATCH] Feat/verifier update scripts (#157) --- circuits/scripts/build/build_dsc_circuits.sh | 4 +- .../scripts/build/build_register_circuits.sh | 6 +- contracts/scripts/mint.ts | 69 ------------ contracts/scripts/setVerifiers.ts | 86 +++++++------- contracts/scripts/testTokenUri.ts | 106 ------------------ sdk/backend-api/bun.lockb | Bin 232670 -> 232670 bytes .../src/contracts/application/hubContract.ts | 32 ++++++ .../infrastructure/contracts.controller.ts | 66 ++++++++++- 8 files changed, 144 insertions(+), 225 deletions(-) delete mode 100644 contracts/scripts/mint.ts delete mode 100644 contracts/scripts/testTokenUri.ts create mode 100644 sdk/backend-api/src/contracts/application/hubContract.ts diff --git a/circuits/scripts/build/build_dsc_circuits.sh b/circuits/scripts/build/build_dsc_circuits.sh index 95ef64156..da321307b 100755 --- a/circuits/scripts/build/build_dsc_circuits.sh +++ b/circuits/scripts/build/build_dsc_circuits.sh @@ -24,9 +24,9 @@ CIRCUITS=( "dsc_sha512_ecdsa_secp521r1:21:false" # RSA circuits - "dsc_sha1_rsa_65537_4096:21:false" + "dsc_sha1_rsa_65537_4096:21:true" "dsc_sha256_rsa_65537_4096:21:true" - "dsc_sha512_rsa_65537_4096:21:false" + "dsc_sha512_rsa_65537_4096:21:true" # RSA-PSS circuits "dsc_sha256_rsapss_3_32_3072:22:false" diff --git a/circuits/scripts/build/build_register_circuits.sh b/circuits/scripts/build/build_register_circuits.sh index 1fd3eecf6..c15d8161a 100755 --- a/circuits/scripts/build/build_register_circuits.sh +++ b/circuits/scripts/build/build_register_circuits.sh @@ -11,14 +11,14 @@ OUTPUT_DIR="build/${CIRCUIT_TYPE}" CIRCUITS=( "register_sha1_sha1_sha1_ecdsa_brainpoolP224r1:21:false" "register_sha1_sha1_sha1_ecdsa_secp256r1:21:false" - "register_sha1_sha1_sha1_rsa_65537_2048:20:false" - "register_sha1_sha256_sha256_rsa_65537_4096:20:false" + "register_sha1_sha1_sha1_rsa_65537_2048:20:true" + "register_sha1_sha256_sha256_rsa_65537_4096:20:true" "register_sha256_sha224_sha224_ecdsa_brainpoolP224r1:21:false" "register_sha256_sha256_sha256_ecdsa_brainpoolP224r1:21:false" "register_sha256_sha256_sha256_ecdsa_brainpoolP256r1:21:false" "register_sha256_sha256_sha256_ecdsa_secp256r1:21:false" "register_sha256_sha256_sha256_ecdsa_secp384r1:22:false" - "register_sha256_sha256_sha256_rsa_65537_3072:20:false" + "register_sha256_sha256_sha256_rsa_65537_3072:20:true" "register_sha256_sha256_sha256_rsa_65537_4096:20:true" "register_sha256_sha256_sha256_rsapss_3_32_4096:21:false" "register_sha256_sha256_sha256_rsapss_65537_4096:21:false" diff --git a/contracts/scripts/mint.ts b/contracts/scripts/mint.ts deleted file mode 100644 index 991b642e2..000000000 --- a/contracts/scripts/mint.ts +++ /dev/null @@ -1,69 +0,0 @@ -import { assert } from "chai"; -import { ethers } from "hardhat"; -import { mockPassportData_sha256WithRSAEncryption_65537 } from "../../common/src/utils/mockPassportData"; -import { groth16 } from 'snarkjs' -import { revealBitmapFromMapping } from "../../common/src/utils/revealBitmap"; -import { generateCircuitInputs } from "../../common/src/utils/generateInputs"; -import fs from 'fs'; - -async function main() { - const proofOfPassportAddress = "0xF3F619aB057E3978204Be68549f9D4a503EAa535" - const proofOfPassport = await ethers.getContractAt("OpenPassport", proofOfPassportAddress); - - const passportData = mockPassportData_sha256WithRSAEncryption_65537; - - const attributeToReveal = { - issuing_state: true, - name: true, - passport_number: true, - nationality: true, - date_of_birth: true, - gender: true, - expiry_date: true, - older_than: true, - } - - const reveal_bitmap = revealBitmapFromMapping(attributeToReveal) - - const address = "0xE6E4b6a802F2e0aeE5676f6010e0AF5C9CDd0a50"; - - const inputs = generateCircuitInputs( - passportData, - reveal_bitmap, - address, - 18, - ); - - console.log('generating proof...'); - const { proof, publicSignals } = await groth16.fullProve( - inputs, - "../circuits/build/proof_of_passport_js/proof_of_passport.wasm", - "../circuits/build/proof_of_passport_final.zkey" - ) - - console.log('proof done'); - - const vKey = JSON.parse(fs.readFileSync("../circuits/build/proof_of_passport_vkey.json") as unknown as string); - - const verified = await groth16.verify( - vKey, - publicSignals, - proof - ) - - assert(verified == true, 'Should verifiable') - - const cd = await groth16.exportSolidityCallData(proof, publicSignals); - const callData = JSON.parse(`[${cd}]`); - console.log('callData', callData); - - const tx = await proofOfPassport.mint(...callData); - - const receipt = await tx.wait(); - console.log('receipt', receipt?.hash); - const tokenURI = await proofOfPassport.tokenURI(0); - console.log('tokenURI', tokenURI); -} - - -main() \ No newline at end of file diff --git a/contracts/scripts/setVerifiers.ts b/contracts/scripts/setVerifiers.ts index 600098b3b..5715973ae 100644 --- a/contracts/scripts/setVerifiers.ts +++ b/contracts/scripts/setVerifiers.ts @@ -1,27 +1,14 @@ -import { ethers } from "hardhat"; +import { ethers } from "ethers"; import * as dotenv from "dotenv"; import * as fs from "fs"; import * as path from "path"; +import { RegisterVerifierId, DscVerifierId } from "../../common/src/constants/constants"; dotenv.config(); -const deployedAddresses = JSON.parse(fs.readFileSync(path.join(__dirname, "../ignition/deployments/chain-11155111/deployed_addresses.json"), "utf-8")); +const deployedAddresses = JSON.parse(fs.readFileSync(path.join(__dirname, "../ignition/deployments/chain-42220/deployed_addresses.json"), "utf-8")); const contractAbiPath = path.join(__dirname, "../ignition/deployments/chain-11155111/artifacts"); -const ProveVerifierList = [ - "Verifier_prove_rsa_65537_sha1", - "Verifier_prove_rsa_65537_sha256", - "Verifier_prove_rsapss_65537_sha256", - "Verifier_prove_ecdsa_secp256r1_sha256", - "Verifier_prove_ecdsa_secp256r1_sha1", -] - -const DscVerifierList = [ - "Verifier_dsc_rsa_65537_sha1_4096", - "Verifier_dsc_rsa_65537_sha256_4096", - "Verifier_dsc_rsapss_65537_sha256_4096" -] - function getContractAddressByPartialName(partialName: string): string | unknown { for (const [key, value] of Object.entries(deployedAddresses)) { if (key.includes(partialName)) { @@ -31,40 +18,51 @@ function getContractAddressByPartialName(partialName: string): string | unknown return undefined; } -function computeVerifierId(input: string): string { - return ethers.keccak256(ethers.toUtf8Bytes(input)); -} - async function main() { - const verifierIds: { - proveVerifierIds: { [key: string]: string }, - dscVerifierIds: { [key: string]: string } - } = { - proveVerifierIds: {}, - dscVerifierIds: {} + const provider = new ethers.JsonRpcProvider(process.env.CELO_RPC_URL as string); + const wallet = new ethers.Wallet(process.env.CELO_KEY as string, provider); + const identityVerificationHubAbiFile = fs.readFileSync(path.join(__dirname, "../ignition/deployments/chain-42220/artifacts/DeployHub#IdentityVerificationHubImplV1.json"), "utf-8"); + const identityVerificationHubAbi = JSON.parse(identityVerificationHubAbiFile).abi; + const identityVerificationHub = new ethers.Contract(deployedAddresses["DeployHub#IdentityVerificationHub"], identityVerificationHubAbi, wallet); + + const registerVerifierKeys = Object.keys(RegisterVerifierId).filter(key => isNaN(Number(key))); + for (const key of registerVerifierKeys) { + const verifierName = `Verifier_${key}`; + const verifierAddress = getContractAddressByPartialName(verifierName); + if (!verifierAddress) { + console.log(`Skipping ${verifierName} because no deployed address was found.`); + continue; + } + console.log(`Updating for ${verifierName}`); + const verifierId = RegisterVerifierId[key as keyof typeof RegisterVerifierId]; + + const tx = await identityVerificationHub.updateRegisterCircuitVerifier( + verifierId, + verifierAddress + ); + const receipt = await tx.wait(); + console.log(`${verifierName} is updated wit this tx: ${receipt.hash}`) } - const provider = new ethers.JsonRpcProvider(process.env.SEPOLIA_RPC_URL as string); - const wallet = new ethers.Wallet(process.env.PKEY as string, provider); - const GenericVerifierAbiFile = fs.readFileSync(path.join(__dirname, "../ignition/deployments/chain-11155111/artifacts/Deploy_Open_Passport_Verifier#GenericVerifier.json"), "utf-8"); - const GenericVerifierAbi = JSON.parse(GenericVerifierAbiFile).abi; - const genericVerifier = new ethers.Contract(getContractAddressByPartialName("GenericVerifier") as string, GenericVerifierAbi, wallet); + const dscKeys = Object.keys(DscVerifierId).filter(key => isNaN(Number(key))); + for (const key of dscKeys) { + const verifierName = `Verifier_${key}`; + const verifierAddress = getContractAddressByPartialName(verifierName); + if (!verifierAddress) { + console.log(`Skipping ${verifierName} because no deployed address was found.`); + continue; + } + const verifierId = DscVerifierId[key as keyof typeof DscVerifierId]; - for (let i = 0; i < ProveVerifierList.length; i++) { - // const proveVerifierAddress = getContractAddressByPartialName(ProveVerifierList[i]) as string; - const proveVerifierId = computeVerifierId(ProveVerifierList[i]); - verifierIds.proveVerifierIds[ProveVerifierList[i]] = proveVerifierId; - // await genericVerifier.updateVerifier(0, proveVerifierId, proveVerifierAddress); + const tx = await identityVerificationHub.updateDscVerifier( + verifierId, + verifierAddress + ); + const receipt = await tx.wait(); + console.log(`${verifierName} is updated wit this tx: ${receipt.hash}`); } - for (let i = 0; i < DscVerifierList.length; i++) { - // const dscVerifierAddress = getContractAddressByPartialName(DscVerifierList[i]) as string; - const dscVerifierId = computeVerifierId(DscVerifierList[i]); - verifierIds.dscVerifierIds[DscVerifierList[i]] = dscVerifierId; - // await genericVerifier.updateVerifier(1, dscVerifierId, dscVerifierAddress); - } - const outputPath = path.join(__dirname, "verifierIds.json"); - fs.writeFileSync(outputPath, JSON.stringify(verifierIds, null, 2), "utf-8"); + } main().catch((error) => { diff --git a/contracts/scripts/testTokenUri.ts b/contracts/scripts/testTokenUri.ts deleted file mode 100644 index e9dfaf45f..000000000 --- a/contracts/scripts/testTokenUri.ts +++ /dev/null @@ -1,106 +0,0 @@ -import { assert } from "chai"; -import { ethers } from "hardhat"; -import { mockPassportData_sha256WithRSAEncryption_65537 } from "../../common/src/utils/mockPassportData"; -import { groth16 } from 'snarkjs' -import { revealBitmapFromMapping } from "../../common/src/utils/revealBitmap"; -import { generateCircuitInputs } from "../../common/src/utils/generateInputs"; -import { countryCodes } from "../../common/src/constants/constants"; -import { formatRoot } from "../../common/src/utils/utils"; -import fs from 'fs'; - -// Useful script to test formatting of tokenURI -async function main() { - const passportData = mockPassportData_sha256WithRSAEncryption_65537; - - const attributeToReveal = { - issuing_state: true, - name: true, - passport_number: true, - nationality: true, - date_of_birth: true, - gender: true, - expiry_date: true, - older_than: true, - } - - const reveal_bitmap = revealBitmapFromMapping(attributeToReveal) - - console.log('reveal_bitmap', reveal_bitmap); - - const address = "0xE6E4b6a802F2e0aeE5676f6010e0AF5C9CDd0a50"; - - const inputs = generateCircuitInputs( - passportData, - reveal_bitmap, - address, - 18, - ); - - const Verifier = await ethers.getContractFactory("Groth16Verifier"); - const verifier = await Verifier.deploy(); - await verifier.waitForDeployment(); - - console.log(`Verifier deployed to ${verifier.target}`); - - const Formatter = await ethers.getContractFactory("Formatter"); - const formatter = await Formatter.deploy(); - await formatter.waitForDeployment(); - console.log(`Formatter deployed to ${formatter.target}`); - - const tx = await formatter.addCountryCodes(Object.entries(countryCodes)); - await tx.wait(); - console.log(`Country codes added`); - - const Registry = await ethers.getContractFactory("Registry"); - const registry = await Registry.deploy(formatRoot(inputs.root[0])); - await registry.waitForDeployment(); - console.log(`Registry deployed to ${registry.target}`); - - const OpenPassport = await ethers.getContractFactory("OpenPassport"); - const proofOfPassport = await OpenPassport.deploy(verifier.target, formatter.target, registry.target); - await proofOfPassport.waitForDeployment(); - - console.log(`OpenPassport NFT deployed to ${proofOfPassport.target}`); - - console.log('generating proof...'); - const { proof, publicSignals } = await groth16.fullProve( - inputs, - "../circuits/build/proof_of_passport_js/proof_of_passport.wasm", - "../circuits/build/proof_of_passport_final.zkey" - ) - - console.log('proof done'); - - const vKey = JSON.parse(fs.readFileSync("../circuits/build/proof_of_passport_vkey.json") as unknown as string); - - const verified = await groth16.verify( - vKey, - publicSignals, - proof - ) - - assert(verified == true, 'Should verifiable') - - const cd = await groth16.exportSolidityCallData(proof, publicSignals); - const callData = JSON.parse(`[${cd}]`); - console.log('callData', callData); - - const mintTx = await proofOfPassport.mint(...callData); - - const receipt = await mintTx.wait(); - console.log('receipt', receipt?.hash); - const tokenURI = await proofOfPassport.tokenURI(0); - console.log('tokenURI', tokenURI); - - const decodedTokenURI = Buffer.from(tokenURI.split(',')[1], 'base64').toString(); - const parsedTokenURI = JSON.parse(decodedTokenURI) - - console.log('parsedTokenURI', parsedTokenURI); - process.exit(0); -} - - -main().catch((error) => { - console.error(error); - process.exitCode = 1; -}); diff --git a/sdk/backend-api/bun.lockb b/sdk/backend-api/bun.lockb index 2d8799f4cef5b5f880aa69e1d2400400c932094c..4aab9887d489733b300d8c9db8c9ecf023fe310b 100755 GIT binary patch delta 31 mcmcaNlkeV4zJ?aYElmF9?2K^+dIox??P29i+r!G4J46AutO{KK delta 31 jcmcaNlkeV4zJ?aYElmF9>`V+`&>mLKv^}hxxkD5HrK$-J diff --git a/sdk/backend-api/src/contracts/application/hubContract.ts b/sdk/backend-api/src/contracts/application/hubContract.ts new file mode 100644 index 000000000..d15234307 --- /dev/null +++ b/sdk/backend-api/src/contracts/application/hubContract.ts @@ -0,0 +1,32 @@ +import { getContractInstance } from "./getContracts"; +import { waitForTransactionReceipt } from "viem/actions"; + +export class HubContract { + + protected hub: any; + protected client: any; + + constructor( + chain: any, + privateKey: `0x${string}`, + rpcUrl: string + ) { + const { contract, publicClient } = getContractInstance("hub", chain, privateKey, rpcUrl); + this.hub = contract; + this.client = publicClient; + } + + public async sigTypeToRegisterCircuitVerifiers( + id: number + ) { + const address = await this.hub.read.sigTypeToRegisterCircuitVerifiers([id]); + return address; + } + + public async sigTypeToDscCircuitVerifiers( + id: number + ) { + const address = await this.hub.read.sigTypeToDscCircuitVerifiers([id]); + return address + } +} \ No newline at end of file diff --git a/sdk/backend-api/src/contracts/infrastructure/contracts.controller.ts b/sdk/backend-api/src/contracts/infrastructure/contracts.controller.ts index ac18b0d1a..174e7473d 100644 --- a/sdk/backend-api/src/contracts/infrastructure/contracts.controller.ts +++ b/sdk/backend-api/src/contracts/infrastructure/contracts.controller.ts @@ -1,6 +1,7 @@ import Elysia, { t } from 'elysia'; import { ProofVerifier } from '../../contracts/application/proofVerifier'; import { RegistryContract } from '../../contracts/application/registryContract'; +import { HubContract } from '../application/hubContract'; import { getChain } from '../../contracts/application/chains'; import { getDscCommitmentEvents } from '../application/getEvents'; import { MerkleTreeService } from '../application/tree-reader/leanImtService'; @@ -47,7 +48,8 @@ export const ContractsController = new Elysia() description: 'Retrieve the identity commitment root in registry contract', }, }, - ).post( + ) + .post( 'update-csca-root', async ({ body, set }) => { try { @@ -317,6 +319,68 @@ export const ContractsController = new Elysia() }, }, ) + .get( + 'sig-to-register', + async ({ query }) => { + const id = Number(query.id); + const hubContract = new HubContract( + getChain(process.env.NETWORK as string), + process.env.PRIVATE_KEY as `0x${string}`, + process.env.RPC_URL as string + ); + const address = await hubContract.sigTypeToRegisterCircuitVerifiers(id); + return { status: 'success', data: address }; + }, + { + query: t.Object({ id: t.String() }), + response: { + 200: t.Object({ + status: t.String(), + data: t.String(), + }), + 500: t.Object({ + status: t.String(), + message: t.String(), + }), + }, + detail: { + tags: ['Hub'], + summary: 'Get Register Circuit Verifier Address via Query', + description: 'Retrieve the Register Circuit Verifier address by passing id as a query parameter.', + }, + } + ) + .get( + 'sig-to-dsc', + async ({ query }) => { + const id = Number(query.id); + const hubContract = new HubContract( + getChain(process.env.NETWORK as string), + process.env.PRIVATE_KEY as `0x${string}`, + process.env.RPC_URL as string + ); + const address = await hubContract.sigTypeToDscCircuitVerifiers(id); + return { status: 'success', data: address }; + }, + { + query: t.Object({ id: t.String() }), + response: { + 200: t.Object({ + status: t.String(), + data: t.String(), + }), + 500: t.Object({ + status: t.String(), + message: t.String(), + }), + }, + detail: { + tags: ['Hub'], + summary: 'Get DSC Circuit Verifier Address via Query', + description: 'Retrieve the DSC Circuit Verifier address by passing id as a query parameter.', + }, + } + ) .post( 'verify-vc-and-disclose-proof', async (request) => {