Edit## The structure of a SNAPP

## An example app

## Building the SNARK

## Using the SNARK

Here you can find documentation on how to use **snarky**, a DSL for using zk-SNARKS, as well as **snarkyjs-crypto** a companion JavaScript library providing a suite of cryptographic primitives suitable for use with **snarky**.

A SNAPP (or snarkified app) has two parts:

The definition of your zk-SNARK program. This part will be built using

**snarky**and specifically the snarky-universe standard library.The rest of the application, which calls into

**snarky**to create and verify proofs. There are currently APIs for Node.js and OCaml/ReasonML for interacting with**snarky**programs in this way.We'll use two Node.js libraries:

- snarkyjs-crypto, which gives us access to cryptographic hashes, merkle-trees, and signatures that mirror those in snarky-universe
- snarkyjs which gives us methods for creating and verifying SNARK proofs.

Let's build a simple app for proving we know a pre-image to a hash function. You can find the completed app here.

This first step in building our SNAPP is to define our SNARK. In this case, our SNARK
will prove, given a hash value **h**

I know a field element

xsuch thathash(x) = h.

where **hash** is the Poseidon hash function provided in snarky-universe.

The snarky component -- defined in this file -- is as follows:

```
module Universe = (val Snarky_universe.default());
open! Universe.Impl;
open! Universe;
let input = InputSpec.[(module Hash)];
module Witness = Field;
let main = (preimage: Witness.t, h, ()) =>
Field.assertEqual(Hash.hash([|preimage|]), h);
runMain(input, (module Witness), main);
```

Let's break down this file bit by bit. The top 3 lines

```
module Universe = (val Snarky_universe.default());
open! Universe.Impl;
open! Universe;
```

are just a preamble which brings in scope all the functions we need. It uses the "default" SNARK construction backend, which is the Groth16 SNARK instantiated using the bn128 curve.

The next line

```
let input = InputSpec.[(module Hash)];
```

declares that the public input to our SNARK will be a hash. The "public input" (or "statement") is the value that our SNARK is checked against.

The next line

```
module Witness = Field;
```

states that our top-level "witness" (that is, the thing we're proving we know) will be a single field element, as described above.

Next, we have the `main`

function, which really defines our SNARK

```
let main = (preimage: Witness.t, h, ()) =>
Field.assertEqual(Hash.hash([|preimage|]), h);
```

Here we write just what we described above: `main`

computes the hash of the witness and asserts that it is
equal to the public input `h`

.

The arguments to `main`

must be

- The top level witness value.
- Any public inputs. Here we just have one,
`h`

. - A dummy
`()`

argument.

The final line

```
runMain(input, (module Witness), main);
```

sets up our program to work with the Node.js API.

Now we're ready to use our SNARK. We're going to use the Node.js API.

The API is fairly straightforward. We can create a "snarky" object which has 2 methods:

`prove`

, which takes a statement and a witness and returns a promise of a proof.`verify`

, which takes a statement and a proof and returns a promise of a bool.

Here is how it all comes together:

```
const { bn128 } = require('snarkyjs-crypto');
const Snarky = require('snarkyjs');
const snarky = new Snarky("./ex_preimage.exe");
const preImage = bn128.Field.ofInt(5);
const statement = bn128.Hash.hash([ preImage ]);
snarky.prove({
statement: [ statement ],
witness: preImage
}).then((proof) => {
console.log("Created proof:\n" + proof + "\n");
return snarky.verify({
"statement": [ statement ],
"proof": proof
});
}, console.log).then((verified) => {
console.log("Was the proof verified? " + verified);
if (verified) {
process.exit(0);
} else {
process.exit(1);
}
}, () => { process.exit(1); });
```