Skip to main content
info

zkApp programmability is not yet available on the Mina Mainnet, but zkApps can now be deployed on Berkeley Testnet.

o1js Basic Concepts

o1js is a TypeScript (TS) library for writing general-purpose zk programs and writing zk smart contracts for Mina.

Field

Field elements are the basic unit of data in zero knowledge proof programming. Each field element can store a number up to almost 256 bits in size. You can think of a field element as a uint256 in Solidity.

note

For the cryptography inclined, the exact max value that a field can store is: 28,948,022,309,329,048,855,892,746,252,171,976,963,363,056,481,941,560,715,954,676,764,349,967,630,336

For example, in typical programming, you might use:

const sum = 1 + 3.

In o1js, you write this as:

const sum = new Field(1).add(new Field(3))

This can be simplified as:

const sum = new Field(1).add(3)

Note that the 3 is auto-promoted to a field type to make this cleaner.

Built-in data types

Some common data types you may use are:

new Bool(x);   // accepts true or false
new Field(x); // accepts an integer, or a numeric string if you want to represent a number greater than JavaScript can represent but within the max value that a field can store.
new UInt64(x); // accepts a Field - useful for constraining numbers to 64 bits
new UInt32(x); // accepts a Field - useful for constraining numbers to 32 bits

PrivateKey, PublicKey, Signature; // useful for accounts and signing
new Group(x, y); // a point on our elliptic curve, accepts two Fields/numbers/strings
Scalar; // the corresponding scalar field (different than Field)

CircuitString.from('some string'); // string of max length 128

In the case of Field and Bool, you can also call the constructor without new:

let x = Field(10);
let b = Bool(true);

Conditionals

Traditional conditional statements are not supported by o1js:

// this will NOT work
if (foo) {
x.assertEquals(y);
}

Instead, use the o1js built-in Circuit.if() method, which is a ternary operator:

const x = Circuit.if(new Bool(foo), a, b); // behaves like `foo ? a : b`

Functions

Functions work as you would expect in TypeScript. For example:

function addOneAndDouble(x: Field): Field {
return x.add(1).mul(2);
}

Common methods

Some frequently used common methods are:

let x = new Field(4); // x = 4
x = x.add(3); // x = 7
x = x.sub(1); // x = 6
x = x.mul(3); // x = 18
x = x.div(2); // x = 9
x = x.square(); // x = 81
x = x.sqrt(); // x = -9

let b = x.equals(8); // b = Bool(false)
b = x.greaterThan(8); // b = Bool(true)
b = b.not().or(b).and(b); // b = Bool(true)
b.toBoolean(); // true

let hash = Poseidon.hash([x]); // takes array of Fields, returns Field

let privKey = PrivateKey.random(); // create a private key
let pubKey = PublicKey.fromPrivateKey(privKey); // derive public key
let msg = [hash];
let sig = Signature.create(privKey, msg); // sign a message
sig.verify(pubKey, msg); // Bool(true)

For a full list, see the o1js reference.