Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add CLI Foundry Template (cont.) #905

Merged
merged 101 commits into from
Dec 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
101 commits
Select commit Hold shift + click to select a range
9a10b39
Semaphore identity example code bug fix
weipooppys93030 Aug 12, 2024
68df0d9
Receive suggestion for consistency
weipooppys93030 Aug 12, 2024
845e49c
chore: forge init
timou0911 Sep 5, 2024
7db237f
forge install: forge-std
timou0911 Sep 5, 2024
3924f5f
Foundry CLI First Draft
timou0911 Sep 5, 2024
c507097
Merge branch 'new_branch' of https://github.com/csiejimmyliu/semaphor…
csiejimmyliu Sep 5, 2024
8e73c32
modules
csiejimmyliu Sep 5, 2024
db8db8e
forge install: semaphore
csiejimmyliu Sep 5, 2024
1455706
forge install: zk-kit.solidity
csiejimmyliu Sep 5, 2024
88b7b46
forge install: poseidon-solidity
csiejimmyliu Sep 5, 2024
29228d9
forge install: openzeppelin-contracts
csiejimmyliu Sep 5, 2024
a062c6a
modules
csiejimmyliu Sep 5, 2024
0ec856e
forge install: semaphore
csiejimmyliu Sep 5, 2024
de881bb
forge install: zk-kit.solidity
csiejimmyliu Sep 5, 2024
967fade
forge install: poseidon-solidity
csiejimmyliu Sep 5, 2024
4754073
forge install: openzeppelin-contracts
csiejimmyliu Sep 5, 2024
caf1e7a
modules
csiejimmyliu Sep 5, 2024
3193f7d
forge install: semaphore
csiejimmyliu Sep 5, 2024
4ac8c36
forge install: zk-kit.solidity
csiejimmyliu Sep 5, 2024
7fba0cf
forge install: poseidon-solidity
csiejimmyliu Sep 5, 2024
a4e5fe9
forge install: openzeppelin-contracts
csiejimmyliu Sep 5, 2024
92dae03
modules
csiejimmyliu Sep 5, 2024
1f1214c
forge install: semaphore
csiejimmyliu Sep 5, 2024
4a26225
forge install: zk-kit.solidity
csiejimmyliu Sep 5, 2024
1eba2a9
forge install: poseidon-solidity
csiejimmyliu Sep 5, 2024
d553272
forge install: openzeppelin-contracts
csiejimmyliu Sep 5, 2024
8197522
modules
csiejimmyliu Sep 5, 2024
18446f8
forge install: semaphore
csiejimmyliu Sep 5, 2024
eb9b2c2
forge install: zk-kit.solidity
csiejimmyliu Sep 5, 2024
ba33b5d
forge install: poseidon-solidity
csiejimmyliu Sep 5, 2024
d1b755e
forge install: openzeppelin-contracts
csiejimmyliu Sep 5, 2024
bdfe270
modules
csiejimmyliu Sep 5, 2024
c13fef9
forge install: semaphore
csiejimmyliu Sep 5, 2024
fa7cf9a
forge install: zk-kit.solidity
csiejimmyliu Sep 5, 2024
a72abc9
forge install: poseidon-solidity
csiejimmyliu Sep 5, 2024
997264f
forge install: openzeppelin-contracts
csiejimmyliu Sep 5, 2024
7601e50
forge install: forge-std
csiejimmyliu Sep 5, 2024
2473ad8
modules
csiejimmyliu Sep 5, 2024
df86f35
forge install: semaphore
csiejimmyliu Sep 5, 2024
d6b8b48
forge install: zk-kit.solidity
csiejimmyliu Sep 5, 2024
b22b15d
forge install: poseidon-solidity
csiejimmyliu Sep 5, 2024
e179470
forge install: openzeppelin-contracts
csiejimmyliu Sep 5, 2024
ceed128
modules
csiejimmyliu Sep 5, 2024
0f05f4f
forge install: semaphore
csiejimmyliu Sep 5, 2024
6266bb5
forge install: zk-kit.solidity
csiejimmyliu Sep 5, 2024
6d9843c
forge install: poseidon-solidity
csiejimmyliu Sep 5, 2024
2f874b6
forge install: openzeppelin-contracts
csiejimmyliu Sep 5, 2024
bb40b95
forge install: forge-std
csiejimmyliu Sep 5, 2024
d4e83b5
modules
csiejimmyliu Sep 5, 2024
ab8d1f6
forge install: semaphore
csiejimmyliu Sep 5, 2024
1a561fb
forge install: zk-kit.solidity
csiejimmyliu Sep 5, 2024
5de7d1b
forge install: poseidon-solidity
csiejimmyliu Sep 5, 2024
589b080
forge install: openzeppelin-contracts
csiejimmyliu Sep 5, 2024
8006eda
forge install: forge-std
csiejimmyliu Sep 5, 2024
cf5fedc
modules
csiejimmyliu Sep 5, 2024
a12b1b1
forge install: semaphore
csiejimmyliu Sep 5, 2024
0c88ced
forge install: zk-kit.solidity
csiejimmyliu Sep 5, 2024
ba78da7
forge install: poseidon-solidity
csiejimmyliu Sep 5, 2024
081bce4
forge install: openzeppelin-contracts
csiejimmyliu Sep 5, 2024
877ad59
modules
csiejimmyliu Sep 5, 2024
8e790ce
forge install: semaphore
csiejimmyliu Sep 5, 2024
c28befb
forge install: zk-kit.solidity
csiejimmyliu Sep 5, 2024
5465816
forge install: poseidon-solidity
csiejimmyliu Sep 5, 2024
5bc6eac
forge install: openzeppelin-contracts
csiejimmyliu Sep 5, 2024
b83d5c2
forge install: forge-std
csiejimmyliu Sep 5, 2024
5a53df7
modules
csiejimmyliu Sep 5, 2024
f13c7e5
forge install: semaphore
csiejimmyliu Sep 5, 2024
e064f4e
forge install: zk-kit.solidity
csiejimmyliu Sep 5, 2024
d338f27
forge install: poseidon-solidity
csiejimmyliu Sep 5, 2024
826b659
forge install: openzeppelin-contracts
csiejimmyliu Sep 5, 2024
5bc93e7
forge install: forge-std
csiejimmyliu Sep 5, 2024
76afd09
change test name
csiejimmyliu Sep 5, 2024
56ae53b
modify declaration of semaphore and verifier
csiejimmyliu Sep 5, 2024
673b801
Modify Test Function Name
timou0911 Sep 7, 2024
46b3c14
Add Test Chain Target
timou0911 Sep 7, 2024
721f26c
forge std install
csiejimmyliu Sep 7, 2024
4832baa
refactor(cli-template-contracts-foundry): change default Anvil addres…
timou0911 Sep 9, 2024
22ea215
chore(cli-template-contracts-foundry): add comments
timou0911 Sep 9, 2024
52eea1b
refactor(cli-template-contracts-foundry): add Semaphore & SemaphoreVe…
timou0911 Sep 9, 2024
f02da82
chore(cli-template-contracts-foundry): add forge coverage for Makefile
timou0911 Sep 9, 2024
5373034
chore(cli-template-contracts-foundry): add env.example
timou0911 Sep 9, 2024
072b11f
docs(cli-template-contracts-foundry): add command instructions
timou0911 Sep 9, 2024
adcec41
refactor: merge main into 'jc/854' branch
jimmychu0807 Nov 27, 2024
2f5a180
Merge branch 'main' into jc/854
jimmychu0807 Nov 27, 2024
5ac64e0
updated
jimmychu0807 Nov 27, 2024
7c5f70d
forge build works
jimmychu0807 Nov 27, 2024
07beb4b
Fixed for linting
jimmychu0807 Nov 28, 2024
2bbf313
chore(cli-template-contracts-foundry): make the lint, prettier, and l…
jimmychu0807 Nov 28, 2024
c80cdd7
chore(cli-template-contracts-foundry): replace Makefile(removed) with…
jimmychu0807 Nov 28, 2024
620cd67
chore(cli-template-contracts-foundry): passing the ci test
jimmychu0807 Nov 28, 2024
ec91d3e
updated test
jimmychu0807 Nov 28, 2024
0556acc
feat(cli-template-contracts-foundry): complete cli-template-contracts…
jimmychu0807 Nov 29, 2024
3e617f9
Merge branch 'main' into jc/854
jimmychu0807 Nov 29, 2024
4793d7b
Update dependencies
jimmychu0807 Nov 29, 2024
d96a611
Add explanation on `yarn dev`
jimmychu0807 Dec 2, 2024
8075e11
fix(cli-template-contracts-foundry): fix `yarn dev` command and add d…
jimmychu0807 Dec 3, 2024
d764c2d
Merge branch 'main' into jc/854
jimmychu0807 Dec 3, 2024
4b2f241
Added yarnrc
jimmychu0807 Dec 16, 2024
e4ac013
Merge branch 'main' into jc/854
jimmychu0807 Dec 16, 2024
d8646cd
updated version
jimmychu0807 Dec 16, 2024
6020340
Added Foundry in template option
jimmychu0807 Dec 17, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions packages/cli-template-contracts-foundry/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
SEPOLIA_RPC_URL=
PRIVATE_KEY=
ETHERSCAN_API_KEY=
43 changes: 43 additions & 0 deletions packages/cli-template-contracts-foundry/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
node_modules
.env

# solidity-coverage files
/coverage
/coverage.json

# Output of 'npm pack'
*.tgz

# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
lerna-debug.log*
.pnpm-debug.log*

# Optional npm cache directory
.npm
.DS_Store

# yarn v3
.pnp.*
.pnp.js
.yarn/*
!.yarn/patches
!.yarn/plugins
!.yarn/releases
!.yarn/sdks
!.yarn/versions

# Diagnostic reports (https://nodejs.org/api/report.html)
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json

# Foundry artifact
cache/
out/

# artifact for deploying on local Anvil node
**/31337

6 changes: 6 additions & 0 deletions packages/cli-template-contracts-foundry/.prettierrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"semi": false,
"arrowParens": "always",
"trailingComma": "none",
"plugins": ["prettier-plugin-solidity"]
}
6 changes: 6 additions & 0 deletions packages/cli-template-contracts-foundry/.solhint.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"extends": "solhint:recommended",
"rules": {
"func-visibility": ["error", { "ignoreConstructors": true }]
}
}

Large diffs are not rendered by default.

7 changes: 7 additions & 0 deletions packages/cli-template-contracts-foundry/.yarnrc.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
compressionLevel: mixed

enableGlobalCache: false

nodeLinker: node-modules

yarnPath: .yarn/releases/yarn-4.1.0.cjs
113 changes: 113 additions & 0 deletions packages/cli-template-contracts-foundry/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
# Semaphore Foundry Template

This project demonstrates a basic Semaphore use case. It comes with a sample contract, a test for that contract and a sample script that deploys that contract.

## Prerequisites

This project requires [**Foundry**](https://getfoundry.sh/), and thus a [**Rust environment**](https://www.rust-lang.org/), installed in the machine.

## Install

### Install dependencies

```bash
yarn
```

## Usage

### Compile contracts

```bash
yarn compile
```

### Test contracts

```bash
yarn test
```

You can also generate a test coverage report:

```bash
yarn test:coverage
```

Or a test gas report:

```bash
yarn test:gas-report
```

You can also start a local [Anvil node](https://book.getfoundry.sh/anvil/) with Semaphore and Feedback contracts deployed on it with:

```bash
yarn dev
```

### Code quality and formatting

Run [solhint](https://github.com/protofire/solhint) to analyze the code and catch bugs:

```bash
yarn lint
```

Run [Prettier](https://prettier.io/) to check formatting rules:

```bash
yarn prettier
```

Or to automatically format the code:

```bash
yarn prettier:write
```

### Integrating with Semaphore Boilerplate

You can also integrate this project with [Semaphore Boilerplate](https://github.com/semaphore-protocol/boilerplate), using this project as the contract end and connecting with Boilerplate front end.

1. In `cli-template-contracts-foundry` package directory, run:

```sh
yarn install
yarn dev
```

After running `yarn dev`, notice the output of

```sh
# ...
# ...

== Return ==
feedbackAddr: address 0x6f1AFCA8BCA87bF02091AF6187a5002802f9FB31
semaphoreAddr: address 0xb730ce6CAE3FB706e83E4E00dFA31623966570eB
semaphoreVerifierAddr: address 0xE2c114f548bEf410eaCe04D0390b61cc963df295

# ...
# ...
```

2. Now, with another terminal, clone Semaphore Boilerplate down:

```sh
# Clone Semaphore boilerplate and build dependencies
git clone https://github.com/semaphore-protocol/boilerplate.git
cd boilerplate
yarn install

# Use the sample .env.example
cp .env.example .env
```

3. Open the file `apps/web-app/.env.development`. Modify the values of `NEXT_PUBLIC_FEEDBACK_CONTRACT_ADDRESS` and `NEXT_PUBLIC_SEMAPHORE_CONTRACT_ADDRESS` with **feedbackAddr** and **semaphoreAddr** values shown in step 1.

4. Run the Boilerplate front end:

```sh
yarn dev:web-app
```
vplasencia marked this conversation as resolved.
Show resolved Hide resolved
15 changes: 15 additions & 0 deletions packages/cli-template-contracts-foundry/foundry.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
[profile.default]
src = "src"
out = "out"
script = "script"
libs = ["node_modules"]
allow_paths = ["*", "../.."]

[rpc_endpoints]
anvil = "http://127.0.0.1:8545"
# sepolia = "${SEPOLIA_RPC_URL}"

[etherscan]
# sepolia = { key = "${ETHERSCAN_API_KEY}" }

# See more config options https://github.com/foundry-rs/foundry/blob/master/crates/config/README.md#all-options
41 changes: 41 additions & 0 deletions packages/cli-template-contracts-foundry/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
{
"name": "@semaphore-protocol/cli-template-contracts-foundry",
"version": "4.7.3",
"description": "Semaphore Foundry template.",
"license": "Unlicense",
"devDependencies": {
"@semaphore-protocol/contracts": "4.7.3",
"@zk-kit/lean-imt.sol": "2.0.0",
"forge-std": "github:foundry-rs/forge-std#v1.9.4",
"poseidon-solidity": "0.0.5",
"prettier": "^3.2.5",
"prettier-plugin-solidity": "^1.3.1",
"solhint": "^4.1.1",
"wait-on": "^8.0.1"
},
"scripts": {
"dev": "anvil & (wait-on tcp:8545 && forge script script/DeployFeedback.s.sol --rpc-url anvil --broadcast --sender 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266)",
"compile": "forge build",
"clean": "forge clean",
"test": "forge test -vvv",
"test:report-gas": "forge test --gas-report",
"test:coverage": "forge coverage",
"lint": "yarn solhint \"{script,src,test}/**/*.sol\"",
"prettier": "prettier -c \"**/*.{json,md,svg,yml,sol}\"",
"prettier:write": "prettier -w \"**/*.{json,md,svg,yml,sol}\"",
"check": "yarn test & yarn lint & yarn prettier"
},
"files": [
"src",
"test",
"script",
"package.json",
"foundry.toml",
"remappings.txt",
"README.md"
],
"publishConfig": {
"access": "public"
},
"packageManager": "[email protected]"
}
4 changes: 4 additions & 0 deletions packages/cli-template-contracts-foundry/remappings.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
@semaphore/contracts/=./node_modules/@semaphore-protocol/contracts/
@zk-kit/lean-imt.sol/=./node_modules/@zk-kit/lean-imt.sol/
forge-std/=./node_modules/forge-std/src/
poseidon-solidity/=./node_modules/poseidon-solidity/
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.23;

import {Feedback} from "../src/Feedback.sol";
import {Semaphore} from "@semaphore/contracts/Semaphore.sol";
import {SemaphoreVerifier} from "@semaphore/contracts/base/SemaphoreVerifier.sol";
import {ISemaphoreVerifier} from "@semaphore/contracts/interfaces/ISemaphoreVerifier.sol";
import {Script} from "forge-std/Script.sol";

// Passing SALT parameter to use CREATE2 for deterministic contract address
bytes32 constant SALT = bytes32(0);

contract DeployFeedback is Script {
function run() external returns (address feedbackAddr, address semaphoreAddr, address semaphoreVerifierAddr) {
// Default to use the first test user private key of anvil node
uint256 deployerPrivateKey = vm.envOr(
"PRIVATE_KEY",
uint256(0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80)
);

vm.startBroadcast(deployerPrivateKey);

// Deploy SemaphoreVerifier
SemaphoreVerifier semaphoreVerifierContract = new SemaphoreVerifier{salt: SALT}();
semaphoreVerifierAddr = address(semaphoreVerifierContract);

// Deploy Semaphore
Semaphore semaphoreContract = new Semaphore{salt: SALT}(ISemaphoreVerifier(semaphoreVerifierAddr));
semaphoreAddr = address(semaphoreContract);

// Deploy Feedback
Feedback feedbackContract = new Feedback{salt: SALT}(semaphoreAddr);
feedbackAddr = address(feedbackContract);

vm.stopBroadcast();
}
}
39 changes: 39 additions & 0 deletions packages/cli-template-contracts-foundry/src/Feedback.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.23;

import {ISemaphore} from "@semaphore/contracts/interfaces/ISemaphore.sol";

contract Feedback {
ISemaphore public semaphore;

uint256 public groupId;

constructor(address semaphoreAddress) {
semaphore = ISemaphore(semaphoreAddress);

groupId = semaphore.createGroup();
}

function joinGroup(uint256 identityCommitment) external {
semaphore.addMember(groupId, identityCommitment);
}

function sendFeedback(
uint256 merkleTreeDepth,
uint256 merkleTreeRoot,
uint256 nullifier,
uint256 feedback,
uint256[8] calldata points
) external {
ISemaphore.SemaphoreProof memory proof = ISemaphore.SemaphoreProof(
merkleTreeDepth,
merkleTreeRoot,
nullifier,
feedback,
groupId,
points
);

semaphore.validateProof(groupId, proof);
}
}
74 changes: 74 additions & 0 deletions packages/cli-template-contracts-foundry/test/Feedback.t.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.23;

import {Test} from "forge-std/Test.sol";
import {ISemaphore} from "@semaphore/contracts/interfaces/ISemaphore.sol";
import {ISemaphoreGroups} from "@semaphore/contracts/interfaces/ISemaphoreGroups.sol";
import {Feedback} from "../src/Feedback.sol";
import {DeployFeedback} from "../script/DeployFeedback.s.sol";

contract FeedbackTest is Test {
event MemberAdded(uint256 indexed groupId, uint256 index, uint256 identityCommitment, uint256 merkleTreeRoot);

Feedback internal feedbackContract;
ISemaphore internal semaphoreContract;
ISemaphoreGroups internal semaphoreGroups;
uint256 internal groupId;

function setUp() external {
DeployFeedback deployFeedback = new DeployFeedback();
(address feedbackAddress, address semaphoreAddress, ) = deployFeedback.run();
feedbackContract = Feedback(feedbackAddress);
semaphoreContract = ISemaphore(semaphoreAddress);
semaphoreGroups = ISemaphoreGroups(semaphoreAddress);
groupId = feedbackContract.groupId();
}

function testGroupCreatedInConstructor() public view {
uint256 groupCount = semaphoreContract.groupCounter();
assertEq(groupCount, 1);
}

function testJoinGroup() public {
// The commitment below is generated with private key of the first account in Anvil
uint256 identityCommitment = 15072455385723004728391568434269917452175057560864330595979104241296826134229;

// Test: expect an event emitted. Check for all event topics and data
vm.expectEmit(true, true, true, true);
emit MemberAdded(groupId, 0, identityCommitment, identityCommitment);

feedbackContract.joinGroup(identityCommitment);
}

function testSendFeedback() public {
uint256[] memory commitments = new uint256[](2);
commitments[0] = uint256(11005642493773047649202648265396872197147567800455247120861783398111750817516);
commitments[1] = uint256(14473821761500463903284857947161896352613497175238126022206384102438097355186);

for (uint256 i = 0; i < commitments.length; ++i) {
feedbackContract.joinGroup(commitments[i]);
}

uint256 merkleTreeDepth = 1;
uint256 merkleTreeRoot = semaphoreGroups.getMerkleTreeRoot(groupId);
uint256 feedback = uint256(bytes32("Hello World"));

// These values are computed by running through @semaphore-protocol/circuits
uint256 nullifier = 14622092170088252518938850323258916742048811914834592843410744760450844885096;
uint256[8] memory points = [
2004484873491928515306456072357737929124240734208600886081152392890959117520,
21291026142870585364296731900941597996672838511394659364623185352043543529323,
4657264777014371046112557309523098953851041383509685591373847255581509612788,
6904165961903336246592681066375875983213983935764940579845010085396463328555,
1952750241178995674697344628236393389729638396609772141225880353616301956443,
106937615136633409337870509099767689510837462832227699340906789167349502398,
13080722838047436988558418790480431472161933638137155324683844808531903905810,
2547578906197450986657523555784319153413167960139250957065929818900731634820
];

vm.expectEmit(true, true, true, true);
emit ISemaphore.ProofValidated(groupId, merkleTreeDepth, merkleTreeRoot, nullifier, feedback, groupId, points);

feedbackContract.sendFeedback(merkleTreeDepth, merkleTreeRoot, nullifier, feedback, points);
}
}
Loading
Loading