-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 23a7f49
Showing
7 changed files
with
1,785 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
main | ||
**/.DS_Store |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
# go-waku-light | ||
|
||
This repo contains a proof of concept of a `waku` light client, integrating [this](https://github.com/vacp2p/rln-contract/pull/31) modification in the RLN contract, which allows having the whole membership set + Merkle root on-chain. This makes light clients even lighter. | ||
|
||
For context, RLN is a decentralized rate-limiting protocol, that allows setting a limit on the number of messages sent by each entity, using zero-knowledge proofs. Said proofs prove that i) the member is whitelisted, without revealing its index, and ii) no more than 1 message is sent every epoch, which prevents double signaling. | ||
|
||
The main motivation is to showcase how [this](https://github.com/vacp2p/rln-contract/pull/31) modification can help light clients become lighter. It makes proof generation and verification easier: | ||
* Proof verification: Only requires the Merkle root, which is now available on-chain and can be fetched with a simple call. Before, one had to sync the whole Merkle tree with emitted events, and keep a local copy of it. | ||
* Proof generation: Requires the whole Merkle tree, which can be synced faster since this modification stores all the leaves in the contract. This approach is faster than syncing events, with the con of spending more gas on membership registration. | ||
|
||
Notes: | ||
* The new [contract](https://github.com/vacp2p/rln-contract/pull/31) uses a [BinaryIMT](https://github.com/privacy-scaling-explorations/zk-kit/blob/main/packages/imt.sol/contracts/BinaryIMT.sol). | ||
* It is deployed in Polygon Layer 2 zkEVM, [see](https://testnet-zkevm.polygonscan.com/address/0x16aBFfCAB50E8D1ff5c22b118Be5c56F801Dce54). | ||
|
||
This repo provides the following functionalities: | ||
* Register an RLN membership in the contract in Layer 2 (Polygon zkEVM) | ||
* Listen to new membership addition | ||
* Get on-chain Merkle root | ||
* Locally sync the membership Merkle tree (no need to sync events as before) | ||
* Generate RLN proofs for a message | ||
* Verify RLN proofs against the contract Merkle root. | ||
|
||
## Usage | ||
|
||
Build: | ||
``` | ||
go build | ||
``` | ||
|
||
Listen for new memberships and Merkle root changes. You can leave this running in another terminal. | ||
``` | ||
./main listen | ||
``` | ||
|
||
Register a new membership. You must provide a valid Polygon zkEVM account, see [faucet](https://faucet.polygon.technology/). Your membership information will be stored in a `.json` file. | ||
``` | ||
./main register --priv-key=REPLACE_YOUR_PRIV_KEY | ||
``` | ||
|
||
Fetches and logs the latest Merkle root of the tree, using the contract as a source. | ||
``` | ||
./main onchain-root | ||
``` | ||
|
||
Syncs the Merkle tree from the contract. The `chunk-size` indicates how many memberships are fetched at once. If too big, the RPC provider may error. | ||
``` | ||
./main sync-tree --chunk-size=500 | ||
``` | ||
|
||
Generates a proof using a given membership. The proof is stored in a `.json` file. | ||
``` | ||
./main generate-proof --membership-file=membership_xxx.json | ||
``` | ||
|
||
Verifies a given proof against the smart contract Merkle root. | ||
``` | ||
./main verify-proof --proof-file=proof_xxx.json | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
[{"inputs":[{"internalType":"uint256","name":"membershipDeposit","type":"uint256"},{"internalType":"uint256","name":"depth","type":"uint256"},{"internalType":"address","name":"_verifier","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"DuplicateIdCommitment","type":"error"},{"inputs":[],"name":"FullTree","type":"error"},{"inputs":[],"name":"InsufficientContractBalance","type":"error"},{"inputs":[{"internalType":"uint256","name":"required","type":"uint256"},{"internalType":"uint256","name":"provided","type":"uint256"}],"name":"InsufficientDeposit","type":"error"},{"inputs":[],"name":"InsufficientWithdrawalBalance","type":"error"},{"inputs":[{"internalType":"uint256","name":"idCommitment","type":"uint256"}],"name":"InvalidIdCommitment","type":"error"},{"inputs":[{"internalType":"uint256","name":"startIndex","type":"uint256"},{"internalType":"uint256","name":"endIndex","type":"uint256"}],"name":"InvalidPaginationQuery","type":"error"},{"inputs":[],"name":"InvalidProof","type":"error"},{"inputs":[{"internalType":"address","name":"to","type":"address"}],"name":"InvalidReceiverAddress","type":"error"},{"inputs":[{"internalType":"uint256","name":"idCommitment","type":"uint256"}],"name":"MemberHasNoStake","type":"error"},{"inputs":[{"internalType":"uint256","name":"idCommitment","type":"uint256"}],"name":"MemberNotRegistered","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"idCommitment","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"index","type":"uint256"}],"name":"MemberRegistered","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"idCommitment","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"index","type":"uint256"}],"name":"MemberWithdrawn","type":"event"},{"inputs":[],"name":"DEPTH","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MEMBERSHIP_DEPOSIT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"Q","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SET_SIZE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"deployedBlockNumber","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"startIndex","type":"uint256"},{"internalType":"uint256","name":"endIndex","type":"uint256"}],"name":"getCommitments","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"idCommitmentIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"imtData","outputs":[{"internalType":"uint256","name":"depth","type":"uint256"},{"internalType":"uint256","name":"root","type":"uint256"},{"internalType":"uint256","name":"numberOfLeaves","type":"uint256"},{"internalType":"bool","name":"useDefaultZeroes","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"indexToCommitment","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"idCommitment","type":"uint256"}],"name":"isValidCommitment","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"memberExists","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"members","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"idCommitment","type":"uint256"}],"name":"register","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"root","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"idCommitment","type":"uint256"},{"internalType":"address payable","name":"receiver","type":"address"},{"internalType":"uint256[8]","name":"proof","type":"uint256[8]"}],"name":"slash","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"stakedAmounts","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"verifier","outputs":[{"internalType":"contract IVerifier","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"withdrawalBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}] |
Oops, something went wrong.