Try   HackMD

Introduction to RLN

A great introduction to RLN was written by Rasul here, discussing the capabilities of RLN. Here's a graph to understand the dependency tree of RLN, and it's downstream users -

rln dependency tree

Where RLN should be used

RLN should be used in the following scenarios -

  • You operate in a privacy-constrained environment, i.e you wouldn't want to reveal information about yourself (IP Address, KYC).
  • The application doesn't care about a specific user, rather, that a message has been sent from someone within a set of users they care about.

Where RLN shouldn't be used

RLN shouldn't be used in the following scenario -

  • Applications which employ traditional DoS protection mechanisms like IP address tracking, and user KYC

How can I use RLN today?

1. Define your application's registration and slashing criteria

By using RlnBase.sol, as described above, you have full overriding capabilities over the registration process.

This could mean, you accept an arbitrary amount of erc20, check if the user has a soul bound token, or any other mechanism, with which you wish to verify that a given user can join your membership group.
This example will just check if the provided idCommitment starts with 0xdead.

We will also not require a membership deposit.

Our slashing model will not use a proof, and only the owner can slash the users.

2. Start a new project

Use any of the smart contract tooling, foundry/hardhat/truffle to scaffold your project, and install rln-contract as a dependency. We will use Foundry. Installation instructions are provided here.

  1. Start a new project
    ​forge init hello_rln_app && cd hello_rln_app
    
  2. Install the rln-contract dependency
    ​forge install vacp2p/rln-contract
    
  3. Install the Openzeppelin-contracts dependency
    ​forge install Openzeppelin/openzeppelin-contracts
    

3. Create the contract

  1. Create a new contract in src/ called HelloRln.sol
    ​​​​// SPDX-License-Identifier: MIT
    ​​​​pragma solidity 0.8.15;
    
    ​​​​import "rln-contract/RlnBase.sol";
    ​​​​import {Ownable} from "openzeppelin-contracts/contracts/access/Ownable.sol";
    
    ​​​​contract HelloRln is Ownable, RlnBase {
    ​​​​    bytes2 public constant start = 0xdead;
    ​​​​    uint256 private membershipDeposit = 0;
    ​​​​    uint256 private depth = 20;
    
    ​​​​    constructor(address _poseidonHasher) Ownable() RlnBase(membershipDeposit, depth, _poseidonHasher, address(0)) {}
    
    ​​​​    function _validateRegistration(uint256 idCommitment) internal pure override {
    ​​​​        if (bytes2(bytes32(idCommitment)) != start) revert FailedValidation();
    ​​​​    }
    
    ​​​​    function _validateSlash(uint256 idCommitment, address payable receiver, uint256[8] calldata proof)
    ​​​​        internal
    ​​​​        view
    ​​​​        override
    ​​​​        onlyOwner
    ​​​​    {}
    ​​​​}
    
  2. Compile
    ​forge build
    
  3. You can write tests in the test directory to test out this logic. A full example can be found here

4. Deploy the contract

  1. Deploy the contract, and obtain the address.

5. Use the new rln app with nwaku

  1. Follow the rln-relay guide, and replace the address with the newly deployed contract
  2. Done! you are now running rln-relay, with your app-specific validation enabled 🚀

OR

5. Use the new rln app with your own p2p system

  1. Implement rln-relay for your application, using zerokit's public/ffi api

Attribution

Most of this work would not be possible without the efforts of the PSE group and past contributors at Vac

References

  1. circom-rln
  2. pmtree
  3. RLN Spec
  4. RLN-Relay Spec
  5. Zerokit