Skip to content

Commit

Permalink
feat(cli-template-contracts-foundry): complete cli-template-contracts…
Browse files Browse the repository at this point in the history
  • Loading branch information
jimmychu0807 committed Nov 29, 2024
1 parent ec91d3e commit 0556acc
Show file tree
Hide file tree
Showing 7 changed files with 101 additions and 86 deletions.
3 changes: 1 addition & 2 deletions packages/cli-template-contracts-foundry/.env.example
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
SEPOLIA_RPC_URL=
SEPOLIA_API_URL=
PRIVATE_KEY=
ETHERSCAN_API_KEY=
PRIVATE_KEY=
44 changes: 9 additions & 35 deletions packages/cli-template-contracts-foundry/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,70 +11,44 @@ This project requires [**Foundry**](https://getfoundry.sh/), and thus a [**Rust
### Install dependencies

```bash
make install
yarn
```

## Usage

### Compile contracts

```bash
make build
yarn compile
```

### Test
### Test contracts

```bash
make test
yarn test
```

You can also generate a test coverage report:

```bash
make coverage
yarn test:coverage
```

Or a test gas report:

```bash  
make gas-report
```

### Deploy contracts

1. Copy the `.env.example` file as `.env`.

```bash
cp .env.example .env
```

2. Add your environment variables.

> [!NOTE]
> You should at least set a valid Ethereum URL (e.g. Infura) and a private key with some ethers.
3. And deploy your contract.

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

4. You can also deploy your contract in Sepolia test chain.
### Start a local anvil node

```bash
make deploy-sepolia
yarn dev
```

```bash
make deploy-sepolia-verify
```

> [!NOTE]
> Check the Semaphore contract addresses [here](https://docs.semaphore.pse.dev/deployed-contracts).
### Code quality and formatting

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

```bash
yarn lint
Expand Down
6 changes: 6 additions & 0 deletions packages/cli-template-contracts-foundry/foundry.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,10 @@ script = "script"
libs = ["node_modules"]
allow_paths = ["*", "../.."]

[rpc_endpoints]
# 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
5 changes: 3 additions & 2 deletions packages/cli-template-contracts-foundry/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,12 @@
"poseidon-solidity": "0.0.5",
"prettier": "^3.2.5",
"prettier-plugin-solidity": "^1.3.1",
"solhint": "^4.1.1"
"solhint": "^4.1.1",
"wait-on": "^8.0.1"
},
"scripts": {
"dev": "anvil --no-mining & (wait-on tcp:8545 && LOG=true forge script script/DeployFeedback.s.sol --chain 31337 --broadcast)",
"compile": "forge build",
"deploy": "",
"clean": "forge clean",
"test": "forge test -vvv",
"test:report-gas": "forge test --gas-report",
Expand Down
42 changes: 25 additions & 17 deletions packages/cli-template-contracts-foundry/script/DeployFeedback.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -8,30 +8,38 @@ import {ISemaphoreVerifier} from "@semaphore/contracts/interfaces/ISemaphoreVeri
import {console, Script} from "forge-std/Script.sol";

contract DeployFeedback is Script {
function run() external returns (address, address) {
address semaphoreVerifierAddress;
address semaphoreAddress;
function run() external returns (address feedbackAddr, address semaphoreAddr) {
address semaphoreVerifierAddr;

vm.startBroadcast();
// Default to use the first test user private key of anvil node
uint256 deployerPrivateKey = vm.envOr(
"PRIVATE_KEY",
uint256(0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80)
);
bool log = vm.envOr("LOG", false);

if (semaphoreAddress == address(0)) {
// Deploy SemaphoreVerifier
SemaphoreVerifier semaphoreVerifier = new SemaphoreVerifier();
semaphoreVerifierAddress = address(semaphoreVerifier);
vm.startBroadcast(deployerPrivateKey);

// Deploy Semaphore
Semaphore semaphore = new Semaphore(ISemaphoreVerifier(semaphoreVerifierAddress));
semaphoreAddress = address(semaphore);
}
// Deploy SemaphoreVerifier
SemaphoreVerifier semaphoreVerifierContract = new SemaphoreVerifier();
semaphoreVerifierAddr = address(semaphoreVerifierContract);

// Deploy Semaphore
Semaphore semaphoreContract = new Semaphore(ISemaphoreVerifier(semaphoreVerifierAddr));
semaphoreAddr = address(semaphoreContract);

// Deploy Feedback
Feedback feedback = new Feedback(semaphoreAddress);
Feedback feedbackContract = new Feedback(semaphoreAddr);
feedbackAddr = address(feedbackContract);

vm.stopBroadcast();

// solhint-disable-next-line no-console
console.log("Feedback contract has been deployed to:", address(feedback));

return (address(feedback), semaphoreAddress);
if (log) {
/* solhint-disable no-console */
console.log("SemaphoreVerifier contract has been deployed to:", semaphoreVerifierAddr);
console.log("Semaphore contract has been deployed to:", semaphoreAddr);
console.log("Feedback contract has been deployed to:", feedbackAddr);
/* solhint-enable no-console */
}
}
}
45 changes: 16 additions & 29 deletions packages/cli-template-contracts-foundry/test/Feedback.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ 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";
import {console} from "forge-std/Script.sol";

contract FeedbackTest is Test {
event MemberAdded(uint256 indexed groupId, uint256 index, uint256 identityCommitment, uint256 merkleTreeRoot);
Expand All @@ -25,12 +24,12 @@ contract FeedbackTest is Test {
groupId = feedbackContract.groupId();
}

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

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

Expand All @@ -41,46 +40,34 @@ contract FeedbackTest is Test {
feedbackContract.joinGroup(identityCommitment);
}

function test_sendFeedback() public {
function testSendFeedback() public {
uint256[] memory commitments = new uint256[](2);
commitments[0] = uint256(
18_699_903_263_915_756_199_535_533_399_390_350_858_126_023_699_350_081_471_896_734_858_638_858_200_219
);
commitments[1] = uint256(
4_446_973_358_529_698_253_939_037_684_201_229_393_105_675_634_248_270_727_935_122_282_482_202_195_132
);
commitments[0] = uint256(11005642493773047649202648265396872197147567800455247120861783398111750817516);
commitments[1] = uint256(14473821761500463903284857947161896352613497175238126022206384102438097355186);

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

uint256 merkleTreeDepth = 2;
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 = 19686122779422310562166284157356225273555811832250923548604308577995736533741;
uint256 nullifier = 14622092170088252518938850323258916742048811914834592843410744760450844885096;
uint256[8] memory points = [
12048312860461559338883155239253399933546666729690013703471566999549175452467,
21840091385609522690103928000869734241136862303146585471149748945500784854265,
10054166788431277732934266072748176286083365382773741957806739135617485223542,
9116054769380232069869558420495933708797671282085269461846220481242548419978,
6948551756635965397908570768367265912884504926499199123083878377204200654789,
2245690128809758381379719477871572712156305432595569015554741897717367802975,
5611601698470220983640634359607737788561497874240905720723835997666161640377,
10003362076211645361201917446734540672642362716488164733173444779942043660944
2004484873491928515306456072357737929124240734208600886081152392890959117520,
21291026142870585364296731900941597996672838511394659364623185352043543529323,
4657264777014371046112557309523098953851041383509685591373847255581509612788,
6904165961903336246592681066375875983213983935764940579845010085396463328555,
1952750241178995674697344628236393389729638396609772141225880353616301956443,
106937615136633409337870509099767689510837462832227699340906789167349502398,
13080722838047436988558418790480431472161933638137155324683844808531903905810,
2547578906197450986657523555784319153413167960139250957065929818900731634820
];

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

feedbackContract.sendFeedback(merkleTreeDepth, merkleTreeRoot, nullifier, feedback, points);
}
Expand Down
42 changes: 41 additions & 1 deletion yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -7337,6 +7337,7 @@ __metadata:
prettier: "npm:^3.2.5"
prettier-plugin-solidity: "npm:^1.3.1"
solhint: "npm:^4.1.1"
wait-on: "npm:^8.0.1"
languageName: unknown
linkType: soft

Expand Down Expand Up @@ -10486,6 +10487,17 @@ __metadata:
languageName: node
linkType: hard

"axios@npm:^1.7.7":
version: 1.7.8
resolution: "axios@npm:1.7.8"
dependencies:
follow-redirects: "npm:^1.15.6"
form-data: "npm:^4.0.0"
proxy-from-env: "npm:^1.1.0"
checksum: 10/7ddcde188041ac55090186254b4025eb2af842be3cf615ce45393fd7f543c1eab0ad2fdd2017a5f6190695e3ecea73ee5e9c37f204854aec2698f9579046efdf
languageName: node
linkType: hard

"axobject-query@npm:^3.2.1":
version: 3.2.1
resolution: "axobject-query@npm:3.2.1"
Expand Down Expand Up @@ -19004,6 +19016,19 @@ __metadata:
languageName: node
linkType: hard

"joi@npm:^17.13.3":
version: 17.13.3
resolution: "joi@npm:17.13.3"
dependencies:
"@hapi/hoek": "npm:^9.3.0"
"@hapi/topo": "npm:^5.1.0"
"@sideway/address": "npm:^4.1.5"
"@sideway/formula": "npm:^3.0.1"
"@sideway/pinpoint": "npm:^2.0.0"
checksum: 10/4c150db0c820c3a52f4a55c82c1fc5e144a5b5f4da9ffebc7339a15469d1a447ebb427ced446efcb9709ab56bd71a06c4c67c9381bc1b9f9ae63fc7c89209bdf
languageName: node
linkType: hard

"joi@npm:^17.9.2":
version: 17.13.1
resolution: "joi@npm:17.13.1"
Expand Down Expand Up @@ -21087,7 +21112,7 @@ __metadata:
languageName: node
linkType: hard

"minimist@npm:^1.0.0, minimist@npm:^1.2.0, minimist@npm:^1.2.5, minimist@npm:^1.2.6":
"minimist@npm:^1.0.0, minimist@npm:^1.2.0, minimist@npm:^1.2.5, minimist@npm:^1.2.6, minimist@npm:^1.2.8":
version: 1.2.8
resolution: "minimist@npm:1.2.8"
checksum: 10/908491b6cc15a6c440ba5b22780a0ba89b9810e1aea684e253e43c4e3b8d56ec1dcdd7ea96dde119c29df59c936cde16062159eae4225c691e19c70b432b6e6f
Expand Down Expand Up @@ -28966,6 +28991,21 @@ __metadata:
languageName: node
linkType: hard

"wait-on@npm:^8.0.1":
version: 8.0.1
resolution: "wait-on@npm:8.0.1"
dependencies:
axios: "npm:^1.7.7"
joi: "npm:^17.13.3"
lodash: "npm:^4.17.21"
minimist: "npm:^1.2.8"
rxjs: "npm:^7.8.1"
bin:
wait-on: bin/wait-on
checksum: 10/41f933031b994718dfb50af35bb843f7f7017d601ef22927e92c211736fadd21808fdbf7ae367e998bcaf995cb9c05cf6160552dc655db9082aeecc346bc926d
languageName: node
linkType: hard

"walk-up-path@npm:^3.0.1":
version: 3.0.1
resolution: "walk-up-path@npm:3.0.1"
Expand Down

0 comments on commit 0556acc

Please sign in to comment.