diff --git a/.gitignore b/.gitignore index 3ba4537bc..53dc72094 100644 --- a/.gitignore +++ b/.gitignore @@ -73,9 +73,6 @@ dist artifacts cache typechain-types -packages/contracts/deployed-contracts/undefined.json -packages/contracts/deployed-contracts/hardhat.json -packages/contracts/deployed-contracts/localhost.json # Stores VSCode versions used for testing VSCode extensions .vscode-test diff --git a/.prettierignore b/.prettierignore index 35f372c40..6fb9c59a7 100644 --- a/.prettierignore +++ b/.prettierignore @@ -12,9 +12,6 @@ coverage.json artifacts cache typechain-types -packages/contracts/deployed-contracts/undefined.json -packages/contracts/deployed-contracts/hardhat.json -packages/contracts/deployed-contracts/localhost.json # production dist diff --git a/packages/contracts/deployed-contracts.json b/packages/contracts/deployed-contracts.json new file mode 100644 index 000000000..d86c27970 --- /dev/null +++ b/packages/contracts/deployed-contracts.json @@ -0,0 +1,20 @@ +[ + { + "network": "sepolia", + "contracts": [ + { + "name": "SemaphoreVerifier", + "address": "0x1E979ECf8C23d45577904974642592f80C464522" + }, + { + "name": "PoseidonT3", + "address": "0x43AE9518d9FE43898cD705a06C22A73B015bCf12" + }, + { + "name": "Semaphore", + "address": "0x5B8e7cC7bAC61A4b952d472b67056B2f260ba6dc" + } + ] + } +] + diff --git a/packages/contracts/deployed-contracts/arbitrum.json b/packages/contracts/deployed-contracts/arbitrum.json deleted file mode 100644 index d06f939b1..000000000 --- a/packages/contracts/deployed-contracts/arbitrum.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "Pairing": "0xE3a4C2FE9f025405cA6F60f6E960B4558604A74C", - "SemaphoreVerifier": "0xCAbeED6cB96a287000aBd834b0B79c05e6Ea4d07", - "Poseidon": "0xe0c8d1e53D9Bfc9071F6564755FCFf6cC0dB61d0", - "IncrementalBinaryTree": "0xcDF8efE6334c68aF283C83f2F14648da51fcfFb0", - "Semaphore": "0xc60E0Ee1a2770d5F619858C641f14FC4a6401520" -} diff --git a/packages/contracts/deployed-contracts/goerli.json b/packages/contracts/deployed-contracts/goerli.json deleted file mode 100644 index c7d7bb9cd..000000000 --- a/packages/contracts/deployed-contracts/goerli.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "Pairing": "0xEe44c1e83A768E80A3588B409f1A010f9D1dd7e8", - "SemaphoreVerifier": "0xb908Bcb798e5353fB90155C692BddE3b4937217C", - "Poseidon": "0xe136aBACf78E05988154ed85F4Ea911105302595", - "IncrementalBinaryTree": "0x4621EE309EAc747425F0FEd51931dDC241A27F49", - "Semaphore": "0x3889927F0B5Eb1a02C6E2C20b39a1Bd4EAd76131" -} diff --git a/packages/contracts/deployed-contracts/mumbai.json b/packages/contracts/deployed-contracts/mumbai.json deleted file mode 100644 index c7d7bb9cd..000000000 --- a/packages/contracts/deployed-contracts/mumbai.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "Pairing": "0xEe44c1e83A768E80A3588B409f1A010f9D1dd7e8", - "SemaphoreVerifier": "0xb908Bcb798e5353fB90155C692BddE3b4937217C", - "Poseidon": "0xe136aBACf78E05988154ed85F4Ea911105302595", - "IncrementalBinaryTree": "0x4621EE309EAc747425F0FEd51931dDC241A27F49", - "Semaphore": "0x3889927F0B5Eb1a02C6E2C20b39a1Bd4EAd76131" -} diff --git a/packages/contracts/deployed-contracts/sepolia.json b/packages/contracts/deployed-contracts/sepolia.json deleted file mode 100644 index c651d4259..000000000 --- a/packages/contracts/deployed-contracts/sepolia.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "Verifier": "0x1E979ECf8C23d45577904974642592f80C464522", - "Poseidon": "0x43AE9518d9FE43898cD705a06C22A73B015bCf12", - "Semaphore": "0x5B8e7cC7bAC61A4b952d472b67056B2f260ba6dc" -} diff --git a/packages/contracts/scripts/create-mock-groups.ts b/packages/contracts/scripts/create-mock-groups.ts index 486102a35..e2ea3fa56 100644 --- a/packages/contracts/scripts/create-mock-groups.ts +++ b/packages/contracts/scripts/create-mock-groups.ts @@ -2,56 +2,58 @@ import { Group } from "@semaphore-protocol/group" import { Identity } from "@semaphore-protocol/identity" import { generateProof } from "@semaphore-protocol/proof" import { ethers, hardhatArguments } from "hardhat" -import { getDeployedContracts } from "./utils" +import { getDeployedContractAddress } from "./utils" async function main() { - const deployedContracts = getDeployedContracts(hardhatArguments.network) + if (!hardhatArguments.network) { + throw Error("Please, define a supported network") + } - if (deployedContracts) { - const semaphoreContract = await ethers.getContractAt("Semaphore", deployedContracts.Semaphore) + const semaphoreAddress = getDeployedContractAddress(hardhatArguments.network, "Semaphore") - const [admin] = await ethers.getSigners() - const adminAddress = await admin.getAddress() + const semaphoreContract = await ethers.getContractAt("Semaphore", semaphoreAddress) - const identity = new Identity(0) - const members = Array.from({ length: 3 }, (_, i) => new Identity(i)).map(({ commitment }) => commitment) - const group = new Group(members) + const [admin] = await ethers.getSigners() + const adminAddress = await admin.getAddress() - const groupId = 42 + const identity = new Identity(0) + const members = Array.from({ length: 3 }, (_, i) => new Identity(i)).map(({ commitment }) => commitment) + const group = new Group(members) - console.info(`Creating group '${groupId}' with ${members.length} members...`) + const groupId = 42 - // Create a group and add 3 members. - await semaphoreContract["createGroup(uint256,address)"](groupId, adminAddress) - await semaphoreContract.addMembers(groupId, members) + console.info(`Creating group '${groupId}' with ${members.length} members...`) - console.info(`Removing third member from group '${groupId}'...`) + // Create a group and add 3 members. + await semaphoreContract["createGroup(uint256,address)"](groupId, adminAddress) + await semaphoreContract.addMembers(groupId, members) - // Remove the third member. - { - group.removeMember(2) - const { siblings } = group.generateMerkleProof(2) + console.info(`Removing third member from group '${groupId}'...`) - await semaphoreContract.removeMember(groupId, members[2], siblings) - } + // Remove the third member. + { + group.removeMember(2) + const { siblings } = group.generateMerkleProof(2) - console.info(`Updating second member from group '${groupId}'...`) + await semaphoreContract.removeMember(groupId, members[2], siblings) + } - // Update the second member. - { - group.updateMember(1, members[2]) - const { siblings } = group.generateMerkleProof(1) + console.info(`Updating second member from group '${groupId}'...`) - await semaphoreContract.updateMember(groupId, members[1], members[2], siblings) - } + // Update the second member. + { + group.updateMember(1, members[2]) + const { siblings } = group.generateMerkleProof(1) - console.info(`Validating a proof generated by the first member of group '${groupId}'...`) + await semaphoreContract.updateMember(groupId, members[1], members[2], siblings) + } - // Validate a proof. - const proof = await generateProof(identity, group, 42, 9, 10) + console.info(`Validating a proof generated by the first member of group '${groupId}'...`) - await semaphoreContract.validateProof(groupId, proof) - } + // Validate a proof. + const proof = await generateProof(identity, group, 42, 9, 10) + + await semaphoreContract.validateProof(groupId, proof) } main() diff --git a/packages/contracts/scripts/utils.ts b/packages/contracts/scripts/utils.ts index 285264a98..71d6d1fe2 100644 --- a/packages/contracts/scripts/utils.ts +++ b/packages/contracts/scripts/utils.ts @@ -1,15 +1,62 @@ -import { readFileSync } from "fs" +import { readFileSync, writeFileSync } from "fs" + +export type NetworkDeployedContracts = { + name: "Semaphore" | "SemaphoreVerifier" | "PoseidonT3" + address: string +}[] export type DeployedContracts = { - Poseidon: string - Semaphore: string - Verifier: string + network: string + contracts: NetworkDeployedContracts +}[] + +const supportedNetworks = ["sepolia", "arbitrum", "mumbai", "optimism-sepolia", "arbitrum-sepolia"] + +export function getDeployedContracts(): DeployedContracts { + return JSON.parse(readFileSync(`./deployed-contracts.json`, "utf8")) +} + +export function getDeployedContractsByNetwork(network: string): NetworkDeployedContracts { + const deployedContracts = getDeployedContracts() + const networkDeployedContracts = deployedContracts.find((n) => n.network === network) + + if (!networkDeployedContracts) { + throw Error(`Network '${network}' is not supported`) + } + + return networkDeployedContracts.contracts +} + +export function getDeployedContractAddress(network: string, contractName: string): string { + const contracts = getDeployedContractsByNetwork(network) + const semaphoreAddress = contracts.find((contract) => contract.name === contractName) + + if (!semaphoreAddress) { + throw Error(`Contract with name '${contractName}' does not exist`) + } + + return semaphoreAddress.address } -export function getDeployedContracts(network: string | undefined): DeployedContracts | null { - try { - return JSON.parse(readFileSync(`./deployed-contracts/${network}.json`, "utf8")) - } catch (error) { - return null +export function saveDeployedContracts(contracts: NetworkDeployedContracts, network?: string) { + if (network && supportedNetworks.includes(network)) { + const deployedContracts = getDeployedContracts() as DeployedContracts + + for (let i = 0; i < deployedContracts.length; i += 1) { + if (deployedContracts[i].network === network) { + deployedContracts[i].contracts = contracts + + writeFileSync(`./deployed-contracts.json`, JSON.stringify(deployedContracts, null, 4)) + + return + } + } + + deployedContracts.push({ + network, + contracts + }) + + writeFileSync(`./deployed-contracts.json`, JSON.stringify(deployedContracts, null, 4)) } } diff --git a/packages/contracts/scripts/verify-contracts.ts b/packages/contracts/scripts/verify-contracts.ts index 43c1e1af0..c04016eb8 100644 --- a/packages/contracts/scripts/verify-contracts.ts +++ b/packages/contracts/scripts/verify-contracts.ts @@ -1,5 +1,5 @@ import { hardhatArguments, run } from "hardhat" -import { getDeployedContracts } from "./utils" +import { getDeployedContractAddress } from "./utils" async function verify(address: string, constructorArguments?: any[]): Promise { try { @@ -13,13 +13,17 @@ async function verify(address: string, constructorArguments?: any[]): Promise("logs", "Print the logs", true, types.boolean) .setAction( async ( - { logs, verifier: verifierAddress, poseidon: poseidonAddress }, + { logs, verifier: semaphoreVerifierAddress, poseidon: poseidonT3Address }, { ethers, hardhatArguments, defender } ): Promise => { - if (!verifierAddress) { + if (!semaphoreVerifierAddress) { const VerifierFactory = await ethers.getContractFactory(`SemaphoreVerifier`) const verifier = await deployContract(defender, VerifierFactory, hardhatArguments.network) - verifierAddress = await verifier.getAddress() + semaphoreVerifierAddress = await verifier.getAddress() if (logs) { - console.info(`SemaphoreVerifier contract has been deployed to: ${verifierAddress}`) + console.info(`SemaphoreVerifier contract has been deployed to: ${semaphoreVerifierAddress}`) } } - if (!poseidonAddress) { + if (!poseidonT3Address) { const PoseidonT3Factory = await ethers.getContractFactory("PoseidonT3") const poseidonT3 = await deployContract(defender, PoseidonT3Factory, hardhatArguments.network) - poseidonAddress = await poseidonT3.getAddress() + poseidonT3Address = await poseidonT3.getAddress() if (logs) { - console.info(`Poseidon library has been deployed to: ${poseidonAddress}`) + console.info(`PoseidonT3 library has been deployed to: ${poseidonT3Address}`) } } const SemaphoreFactory = await ethers.getContractFactory("Semaphore", { libraries: { - PoseidonT3: poseidonAddress + PoseidonT3: poseidonT3Address } }) const semaphore = await deployContract(defender, SemaphoreFactory, hardhatArguments.network, [ - verifierAddress + semaphoreVerifierAddress ]) const semaphoreAddress = await semaphore.getAddress() @@ -51,23 +51,28 @@ task("deploy", "Deploy a Semaphore contract") console.info(`Semaphore contract has been deployed to: ${semaphoreAddress}`) } - writeFileSync( - `./deployed-contracts/${hardhatArguments.network}.json`, - JSON.stringify( + saveDeployedContracts( + [ { - Verifier: verifierAddress, - Poseidon: poseidonAddress, - Semaphore: semaphoreAddress + name: "SemaphoreVerifier", + address: semaphoreVerifierAddress }, - null, - 4 - ) + { + name: "PoseidonT3", + address: poseidonT3Address + }, + { + name: "Semaphore", + address: semaphoreAddress + } + ], + hardhatArguments.network ) return { semaphore, - verifierAddress, - poseidonAddress + verifierAddress: semaphoreVerifierAddress, + poseidonAddress: poseidonT3Address } } )