Skip to content

Commit 884fad2

Browse files
committed
feat: circuit script and smart contract run scripts
1 parent 09dcd23 commit 884fad2

6 files changed

Lines changed: 191 additions & 3 deletions

File tree

Makefile

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,15 @@
1-
.PHONY: network deploy-local deploy-sepolia test
1+
.PHONY: clean network deploy-local deploy-sepolia test slither-check
22
include .env
33

4+
clean:
5+
forge clean
6+
rm -rf circuits/build circuits/proof.json circuits/public.json circuits/verification_key.json src/Verifier.sol
7+
8+
9+
# Setup zk-SNARK circuit
10+
circuit:
11+
./circuits/circuit_setup.sh
12+
413
# Start a local Ethereum
514
network:
615
anvil
@@ -15,9 +24,26 @@ deploy-sepolia:
1524
--rpc-url ${SEPOLIA_RPC_URL} \
1625
--private-key 0x${PRIVATE_KEY} \
1726
--verify \
18-
--etherscan-api-key ${ETHERSCAN_API_KEY}
27+
--etherscan-api-key ${ETHERSCAN_API_KEY} \
1928
--broadcast \
2029

30+
add-creator-local:
31+
forge script script/AddCreator.s.sol:AddCreator --rpc-url http://127.0.0.1:8545 --private-key ${PRIVATE_KEY_LOCAL} --broadcast
32+
33+
add-task-local:
34+
forge script script/AddTask.s.sol:AddTask --rpc-url http://127.0.0.1:8545 --private-key ${PRIVATE_KEY_CREATOR} --broadcast
35+
36+
deactivate-task-local:
37+
forge script script/DeactivateTask.s.sol:DeactivateTask --rpc-url http://127.0.0.1:8545 --private-key ${PRIVATE_KEY_LOCAL} --broadcast
38+
39+
solve-task-local:
40+
forge script script/SolveTask.s.sol:SolveTask --rpc-url http://127.0.0.1:8545 --private-key ${PRIVATE_KEY_SOLVER} --broadcast
41+
2142
# Run smart contract tests
2243
test:
23-
forge test
44+
forge test
45+
forge coverage
46+
47+
# Run Slither static analysis
48+
slither-check:
49+
slither .

circuits/circuit_setup.sh

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
#!/bin/bash
2+
set -euo pipefail # Strict error handling
3+
4+
# Ensures the script runs in the circuit directory
5+
cd "$(dirname "$0")"
6+
7+
BUILD_DIR="build"
8+
INPUTS_DIR="inputs"
9+
10+
mkdir -p "$BUILD_DIR" "$INPUTS_DIR"
11+
12+
echo "### Step 1: Compile circuit to R1CS + WASM + SYM"
13+
circom TaskProof.circom --r1cs --wasm --sym -o "$BUILD_DIR"
14+
# Rename to .cjs for Node.js compatibility
15+
mv build/TaskProof_js/generate_witness.js build/TaskProof_js/generate_witness.cjs
16+
mv build/TaskProof_js/witness_calculator.js build/TaskProof_js/witness_calculator.cjs
17+
sed -i 's/\.\/witness_calculator\.js/.\/witness_calculator.cjs/' build/TaskProof_js/generate_witness.cjs
18+
19+
echo "### Step 2: Trusted setup (powers of tau)"
20+
snarkjs powersoftau new bn128 12 "$BUILD_DIR/pot12_0000.ptau" -v
21+
snarkjs powersoftau contribute "$BUILD_DIR/pot12_0000.ptau" "$BUILD_DIR/pot12_0001.ptau" --name="First contribution" -v
22+
snarkjs powersoftau beacon "$BUILD_DIR/pot12_0001.ptau" "$BUILD_DIR/pot12_beacon.ptau" 0102030405060708 10 -n="final-beacon"
23+
snarkjs powersoftau prepare phase2 "$BUILD_DIR/pot12_beacon.ptau" "$BUILD_DIR/pot12_final.ptau" -v
24+
25+
echo "### Step 2b: Setup Groth16 Phase 2"
26+
snarkjs groth16 setup "$BUILD_DIR/TaskProof.r1cs" "$BUILD_DIR/pot12_final.ptau" "$BUILD_DIR/TaskProof_0000.zkey"
27+
snarkjs zkey contribute "$BUILD_DIR/TaskProof_0000.zkey" "$BUILD_DIR/TaskProof_0001.zkey" --name="Alice" -e="$(openssl rand -base64 32)" -v
28+
snarkjs zkey contribute "$BUILD_DIR/TaskProof_0001.zkey" "$BUILD_DIR/TaskProof_0002.zkey" --name="Bob" -e="$(openssl rand -base64 32)" -v
29+
snarkjs zkey beacon "$BUILD_DIR/TaskProof_0002.zkey" "$BUILD_DIR/TaskProof_final.zkey" 0102030405060708 12 -n="final-beacon-phase2"
30+
31+
echo "### Step 3: Export verification key + Solidity verifier"
32+
snarkjs zkey export verificationkey "$BUILD_DIR/TaskProof_final.zkey" verification_key.json
33+
snarkjs zkey export solidityverifier "$BUILD_DIR/TaskProof_final.zkey" ../src/Verifier.sol
34+
35+
echo "### Step 4: Generate witness"
36+
if [[ ! -f "$INPUTS_DIR/input.json" ]]; then
37+
cat > "$INPUTS_DIR/input.json" <<EOF
38+
{
39+
"solution": "42",
40+
"taskId": "7",
41+
"taskSalt": "123456",
42+
"recipient": "987654321",
43+
"commit": "11500528584593830379883139624647731070623497308416655972613955003754148633922"
44+
}
45+
EOF
46+
echo "Created default inputs at $INPUTS_DIR/input.json"
47+
fi
48+
49+
node "$BUILD_DIR/TaskProof_js/generate_witness.cjs" \
50+
"$BUILD_DIR/TaskProof_js/TaskProof.wasm" \
51+
"$INPUTS_DIR/input.json" \
52+
"$BUILD_DIR/witness.wtns"
53+
54+
echo "### Step 4b: Generate proof and public signals"
55+
snarkjs groth16 prove "$BUILD_DIR/TaskProof_final.zkey" "$BUILD_DIR/witness.wtns" proof.json public.json
56+
57+
echo "### Step 4c: Verify proof"
58+
snarkjs groth16 verify verification_key.json public.json proof.json
59+
60+
echo "Done!"

script/AddCreator.s.sol

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// SPDX-License-Identifier: GPL-3.0-or-later
2+
pragma solidity ^0.8.24;
3+
4+
import "forge-std/Script.sol";
5+
import "../src/TaskAccess.sol";
6+
7+
contract AddCreator is Script {
8+
function run() external {
9+
// Load admin key (must be DEFAULT_ADMIN_ROLE in TaskAccess)
10+
uint256 adminKey = vm.envUint("PRIVATE_KEY_LOCAL");
11+
address admin = vm.addr(adminKey);
12+
13+
// Load deployed TaskAccess contract address
14+
address accessAddr = vm.envAddress("TASK_ACCESS_ADDR");
15+
TaskAccess access = TaskAccess(accessAddr);
16+
17+
// Address to grant TASK_CREATOR_ROLE
18+
address newCreator = vm.envAddress("CREATOR_ADDR");
19+
20+
vm.startBroadcast(admin);
21+
access.addTaskCreator(newCreator);
22+
vm.stopBroadcast();
23+
}
24+
}

script/AddTask.s.sol

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// SPDX-License-Identifier: GPL-3.0-or-later
2+
pragma solidity ^0.8.24;
3+
4+
import "forge-std/Script.sol";
5+
import "../src/TaskManager.sol";
6+
7+
contract AddTask is Script {
8+
function run() external {
9+
uint256 creatorKey = vm.envUint("PRIVATE_KEY_CREATOR"); // must be TaskCreator
10+
address creator = vm.addr(creatorKey);
11+
12+
// Load TaskManager address
13+
address managerAddr = vm.envAddress("TASK_MANAGER_ADDR");
14+
TaskManager manager = TaskManager(managerAddr);
15+
16+
// Example values (replace with real commit/salt)
17+
string memory taskURI = "ipfs://Qm...";
18+
uint256 commit = 11500528584593830379883139624647731070623497308416655972613955003754148633922;
19+
uint256 salt = 123456;
20+
21+
vm.startBroadcast(creator);
22+
manager.addTask(taskURI, commit, salt);
23+
vm.stopBroadcast();
24+
}
25+
}

script/DeactivateTask.s.sol

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// SPDX-License-Identifier: GPL-3.0-or-later
2+
pragma solidity ^0.8.24;
3+
4+
import "forge-std/Script.sol";
5+
import "../src/TaskManager.sol";
6+
7+
contract DeactivateTask is Script {
8+
function run() external {
9+
uint256 adminKey = vm.envUint("PRIVATE_KEY_LOCAL"); // must be TaskAdmin
10+
address admin = vm.addr(adminKey);
11+
12+
address managerAddr = vm.envAddress("TASK_MANAGER_ADDR");
13+
TaskManager manager = TaskManager(managerAddr);
14+
15+
uint256 taskId = vm.envUint("TASK_ID_TO_DEACTIVATE");
16+
17+
vm.startBroadcast(admin);
18+
manager.deactivateTask(taskId);
19+
vm.stopBroadcast();
20+
}
21+
}

script/SolveTask.s.sol

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// SPDX-License-Identifier: GPL-3.0-or-later
2+
pragma solidity ^0.8.24;
3+
4+
import "forge-std/Script.sol";
5+
import "../src/TaskManager.sol";
6+
7+
contract SolveTask is Script {
8+
function run() external {
9+
uint256 solverKey = vm.envUint("PRIVATE_KEY_SOLVER"); // solver’s wallet
10+
address solver = vm.addr(solverKey);
11+
12+
address managerAddr = vm.envAddress("TASK_MANAGER_ADDR");
13+
TaskManager manager = TaskManager(managerAddr);
14+
15+
// Example proof values (replace with actual Groth16 proof)
16+
uint[2] memory a = [uint(0), uint(0)];
17+
uint[2][2] memory b = [[uint(0), uint(0)], [uint(0), uint(0)]];
18+
uint[2] memory c = [uint(0), uint(0)];
19+
20+
// Public signals = [commit, taskId, salt, recipient]
21+
uint[4] memory publicSignals = [
22+
11500528584593830379883139624647731070623497308416655972613955003754148633922, // commit
23+
7, // taskId
24+
123456, // salt
25+
uint256(uint160(solver)) // recipient must be solver
26+
];
27+
28+
vm.startBroadcast(solver);
29+
manager.solveTask(7, solver, a, b, c, publicSignals);
30+
vm.stopBroadcast();
31+
}
32+
}

0 commit comments

Comments
 (0)