# Noir 101 for Solidity Devs

By [crisgarner.eth](https://paragraph.com/@crisgarner) · 2023-08-02

---

_In this tutorial, we will create a simple “Secret Public Contract”, using Noir and Foundry. The contract will be deployed with an execute function which can only be executed with a secret calldata, meaning that only if you know the secret function and prove it, you can execute the contract functionality._

_You can see the complete code used in this tutorial in_ [**_the following repository._**](https://github.com/crisgarner/noir101-tutorial)

Getting Started
---------------

Noir is a Domain Specific Language for SNARK proving systems. Its design choices are influenced heavily by Rust and focus on a simple, familiar syntax. While Noir can be used for different purposes this tutorial focuses on Solidity development. We will use Noir to create the circuits and Foundry to test the Solidity contracts.

### Installing Noir

As Noir evolves constantly, the recommended way to install it is by using `noirup` which installs Nargo, a command line tool for interacting with Noir programs (compiling, proving, verifying, creating contracts, etc). In OSX or Linux run the following command on the terminal:

    $ curl -L https://raw.githubusercontent.com/noir-lang/noirup/main/install | bash
    

You can check that the installation was successful by running `nargo --version`. Other options for installation are available in the [**official documentation**](https://noir-lang.org/getting_started/nargo_installation)**.**

### Installing Foundry

Just like Noir, the recommended way to install Foundry is by using `foundryup`. Run the following command to install it:

    curl -L https://foundry.paradigm.xyz | bash
    

As it’s outside the scope of this tutorial, you can read more information about Foundry on the [**official documentation site.**](https://book.getfoundry.sh/)

### Installing Noir Language Support (Optional)

If you use VS Code I will suggest installing the Noir Language Support extension, It adds syntax highlighting, compilation errors and warnings, and useful snippets.

[https://marketplace.visualstudio.com/items?itemName=noir-lang.vscode-noir](https://marketplace.visualstudio.com/items?itemName=noir-lang.vscode-noir)

Creating a Project
------------------

With Nargo and Foundry installed, we can make a project. While we can use the `forge init projectName` and `nargo new projectName` commands, we would need to do some file ordering and cleaning, so I will suggest you use the Noir starter with the Foundry repo.

[https://github.com/noir-lang/noir-starter/tree/main/with-foundry](https://github.com/noir-lang/noir-starter/tree/main/with-foundry)

You can fork it or use it as inspiration to order the files from scratch. Just keep in mind that you will need to edit the `foundry.toml` file and add `ffi` and `fs_permissions` for Foundry tests to access the proofs generated by noir.

    [profile.default]
    src = "src"
    out = "out"
    libs = ["lib"]
    fs_permissions = [{ access = "read-write", path = "./"},{ access = "read-write", path = "/tmp/"}]
    ffi = true
    
    # See more config options https://github.com/foundry-rs/foundry/tree/master/config
    

Creating the Circuits
---------------------

We are ready to create our circuit, move to the `circuits/src` folder and create a new Noir file `main.nr`. This is a pretty simple circuit, only checks that the values sent from the contract are the ones we define in secret. We use the Pedersen hash function to create a unique hash based on the parameters then we compare them with the hash of our secret parameters to see if they match.

![main.nr](https://storage.googleapis.com/papyrus_images/624162e132a1d07d20b09613194df93f36e69a92f3a05b5e805db3a36f7bec69.png)

main.nr

We can then build the output files by running:

    $ nargo check 
    

This will generate two files: `Prover.toml` which holds input values and `Verifier.toml` which has public values. We fill in the values on the Prover.toml if we already know which function we want to call and prove the valid execution by creating a proof running:

This is going to generate a new folder `proofs` and it will contain a proof file with the name that you specify, depending on your computer and code this command might take a few seconds to execute. We can then go ahead and verify the correct execution of our program by running the following command:

    $ nargo verify nameOfProof
    

If there are no errors, no message will be shown. We can finally generate the verifier contract by running.

    $ nargo codegen-verifier
    

Which will create the `contract` folder and the `plonk_vk.sol` contract, which we can later use to verify our contracts.

Creating the Contracts
----------------------

Head back to the project folder and create two solidity files in the `contract` folder. `MyToken.sol` is going to be a simple ERC20 Token with a public function mint that anyone can call, add the solmate library running:

    $ forge install transmissions11/solmate
    

![MyToken.sol](https://storage.googleapis.com/papyrus_images/8fbe79fde19be32a05d6e1e6bf6b71504dcf73c3c3acd0518853a015f89be40b.png)

MyToken.sol

And now let’s create `SecretCaller.sol` where we will use our `plonk_vk.sol` file to verify that the user making the call knows the secret.

![SecretCaller.sol](https://storage.googleapis.com/papyrus_images/63e67d8c2d174663358faeb9be3e8b11826553b8a881569b5a032944d7dcb112.png)

SecretCaller.sol

We import the verifier contract and assign it to the constructor, we can call the verify function in the `secretCall` function. We must pass the `proof` as bytes and generate the `publicInputs` as an array of bytes32 and we pass it to the verifier.

![SecretCaller.sol](https://storage.googleapis.com/papyrus_images/ad7b063579165d1a564d18dae7f8027adf7cb166495ca48d53312a60bd14ba9b.png)

SecretCaller.sol

Once we verify that the proof is correct we can execute the contract call with the information we sent.

Testing the Contracts
---------------------

As we now have the contracts we want to test, let’s fill the `Prover.toml` file with the correct values (you can use console.log on the test files to see the values) generate a proof, and test everything using Foundry. Start creating the `SecretCaller.t.sol` file under the `test` directory and let’s discuss what’s happening:

![SecretCaller.t.sol](https://storage.googleapis.com/papyrus_images/7967bac2affc9e3d653e147eaebd6698b2d7c27a76bec2ad8f12d6a5ea7154e4.png)

SecretCaller.t.sol

We import the contracts that we are going to test, deploy them and use a helper function to grab the proof we generated in the previous steps, then, we are going to create two test functions that send correct and bad data and see if we can execute the secretCall function.

![SecretCall.t.sol](https://storage.googleapis.com/papyrus_images/cce65b799f6077a771f8c3660acc10139c0d638944c1e7815b514114c043f7e9.png)

SecretCall.t.sol

We can then run the `$ forge test` command in the console and the two tests should pass.

* * *

**_That’s all! remember that this code is for testing purposes and if someone makes a contract call, the data will be public on-chain meaning that anyone can replicate the call._**

_This tutorial was built using the Noir version_ `0.7.1`_. As expected with an evolving language many changes are expected to come, I’ll suggest you follow the_ [**_official Twitter_**](https://twitter.com/NoirLang) _account and join the_ [**_official discord_**](https://discord.gg/4XHr6KqDfz) _in case you have any doubts. Feel free to send me a DM on Twitter (X) with questions or comments_ [**_@crisgarner_**](https://twitter.com/crisgarner)**_._**

---

*Originally published on [crisgarner.eth](https://paragraph.com/@crisgarner/noir-101-for-solidity-devs)*
