2020-05-21 21:03:43 +03:00
# The Leo Programming Language
2020-06-16 22:55:59 +03:00
2020-07-05 22:04:33 +03:00
![CI ](https://github.com/AleoHQ/leo/workflows/CI/badge.svg )
2020-06-23 02:01:54 +03:00
[![codecov ](https://codecov.io/gh/AleoHQ/leo/branch/master/graph/badge.svg?token=S6MWO60SYL )](https://codecov.io/gh/AleoHQ/leo)
2020-08-13 10:18:51 +03:00
# Overview
2020-06-16 22:55:59 +03:00
## Compiler Architecture
<!-- generated by mermaid compile action - START -->
![~mermaid diagram 1~ ](/.resources/README-md-1.png )
< details >
< summary > Mermaid markup< / summary >
```mermaid
graph LR
Pass1(Syntax Parser) -- ast --> Pass2(Type Resolver)
Pass2 -- imports --> Pass3(Import Resolver)
Pass3 -- statements --> Pass4
Pass2 -- statements --> Pass4(Synthesizer)
2020-06-20 11:40:56 +03:00
Pass4 -- constraints --> Pass5(Program)
2020-06-16 22:55:59 +03:00
```
< / details >
<!-- generated by mermaid compile action - END -->
## Language Specification
2020-04-24 03:43:58 +03:00
* Programs should be formatted:
1. Import definitions
2020-05-21 21:03:43 +03:00
2. Circuit definitions
2020-04-24 03:43:58 +03:00
3. Function definitions
2020-06-16 22:55:59 +03:00
## Defining Variables
Leo supports `let` and `const` keywords for variable definition.
```let a = true;``` defines an **allocated** program variable `a` with boolean value `true` .
```const a = true;``` defines a **constant** program variable `a` with boolean value `true` .
**Allocated** variables define private variables in the constraint system. Their value is constrained in the circuit on initialization.
**Constant** variables do not define a variable in the constraint system. Their value is constrained in the circuit on computation with an **allocated** variable.
2020-07-03 08:08:20 +03:00
**Constant** variables cannot be mutable. They have the same functionality as `const` variables in other languages.
2020-07-05 22:04:33 +03:00
```js
function add_one() -> {
2020-06-16 22:55:59 +03:00
let a = 0u8; // allocated, value enforced on this line
const b = 1u8; // constant, value not enforced yet
return a + b // allocated, computed value is enforced to be the sum of both values
}
```
Computations are expressed in terms of arithmetic circuits, in particular rank-1 quadratic constraint systems. Thus computing on an allocated variable always results in another allocated variable.
2020-05-21 21:03:43 +03:00
## Mutability
* All defined variables in Leo are immutable by default.
* Variables can be made mutable with the `mut` keyword.
2020-07-05 22:04:33 +03:00
```js
2020-05-21 21:03:43 +03:00
function main() {
let a = 0u32;
//a = 1 < - Will fail
let mut b = 0u32;
b = 1; // < - Ok
2020-04-24 03:43:58 +03:00
}
```
2020-07-05 22:04:33 +03:00
## Addresses
Addresses are defined to enable compiler-optimized routines for parsing and operating over addresses. These semantics will be accompanied by a standard library in a future sprint.
```js
2020-07-05 22:32:15 +03:00
function main(owner: address) {
2020-07-05 22:04:33 +03:00
let sender = address(aleo1qnr4dkkvkgfqph0vzc3y6z2eu975wnpz2925ntjccd5cfqxtyu8sta57j8);
2020-07-06 01:48:47 +03:00
let receiver: address = aleo1qnr4dkkvkgfqph0vzc3y6z2eu975wnpz2925ntjccd5cfqxtyu8sta57j8;
2020-07-05 22:32:15 +03:00
assert_eq!(owner, sender);
2020-07-06 01:48:47 +03:00
assert_eq!(sender, receiver);
2020-07-05 22:04:33 +03:00
}
```
2020-05-21 21:03:43 +03:00
## Booleans
Explicit types are optional.
2020-07-05 22:04:33 +03:00
```js
2020-05-21 21:03:43 +03:00
function main() -> bool {
let a: bool = true || false;
let b = false & & false;
let c = 1u32 == 1u32;
2020-04-24 03:43:58 +03:00
return a
}
```
2020-05-21 21:03:43 +03:00
## Numbers
2020-06-16 22:55:59 +03:00
* The definition of a number must include an explicit type.
2020-05-21 21:03:43 +03:00
* After assignment, you can choose to explicitly add the type or let the compiler interpret implicitly.
* Type casting is not supported.
* Comparators are not supported.
### Integers
Supported integer types: `u8` , `u16` , `u32` , `u64` , `u128`
2020-07-05 22:04:33 +03:00
```js
2020-05-21 21:03:43 +03:00
function main() -> u32 {
let a = 2u32; // explicit type
let a: u32 = 1 + 1; // explicit type
let b = a - 1; // implicit type
let c = b * 4;
let d = c / 2;
let e = d ** 3;
return e
}
```
### Field Elements
2020-07-05 22:04:33 +03:00
```js
2020-07-08 13:30:15 +03:00
function main() -> field {
2020-05-21 21:03:43 +03:00
let a = 1000field; // explicit type
2020-07-08 13:30:15 +03:00
let a: field = 21888242871839275222246405745257275088548364400416034343698204186575808495617; // explicit type
2020-05-21 21:03:43 +03:00
let b = a + 1; // implicit type
let c = b - 1;
let d = c * 4;
let e = d / 2;
2020-06-03 02:16:41 +03:00
return e
2020-05-21 21:03:43 +03:00
}
```
2020-07-05 22:04:33 +03:00
### Group Elements
An affine point on the elliptic curve passed into the Leo compiler forms a group.
2020-06-03 02:16:41 +03:00
Leo supports this set as a primitive data type.
2020-05-21 21:03:43 +03:00
2020-07-05 22:04:33 +03:00
```js
2020-05-21 21:03:43 +03:00
function main() -> group {
let a = 1000group; // explicit type
2020-06-03 02:16:41 +03:00
let a = (21888242871839275222246405745257275088548364400416034343698204186575808495617, 21888242871839275222246405745257275088548364400416034343698204186575808495617)group; // explicit type
let b = a + 0; // implicit type
let c = b - 0;
2020-05-21 21:03:43 +03:00
return c
}
```
### Operator Assignment Statements
2020-07-05 22:04:33 +03:00
```js
2020-05-05 02:52:32 +03:00
function main() -> u32 {
2020-07-04 08:44:09 +03:00
let mut a = 10;
a += 5;
a -= 10;
a *= 5;
a /= 5;
a ** = 2;
2020-05-05 02:52:32 +03:00
2020-07-04 08:44:09 +03:00
return a
2020-05-05 02:52:32 +03:00
}
```
2020-05-21 21:03:43 +03:00
## Arrays
2020-04-24 03:43:58 +03:00
Leo supports static arrays with fixed length.
2020-07-05 22:04:33 +03:00
```js
2020-05-05 02:52:32 +03:00
function main() -> u32[2] {
2020-04-24 03:43:58 +03:00
// initialize an integer array with integer values
2020-05-21 21:03:43 +03:00
let mut a: u32[3] = [1, 2, 3];
2020-04-24 03:43:58 +03:00
2020-05-21 21:03:43 +03:00
// set a mutable member to a value
2020-05-05 02:52:32 +03:00
a[2] = 4;
2020-04-24 03:43:58 +03:00
// initialize an array of 4 values all equal to 42
2020-05-21 21:03:43 +03:00
let b = [42u8; 4];
2020-04-24 03:43:58 +03:00
// initialize an array of 5 values copying all elements of b using a spread
2020-05-05 02:52:32 +03:00
let c = [1, ...b];
2020-04-24 03:43:58 +03:00
// initialize an array copying a slice from `c`
2020-05-05 02:52:32 +03:00
let d = c[1..3];
2020-04-24 03:43:58 +03:00
2020-07-08 13:30:15 +03:00
// initialize a field array
2020-05-21 21:03:43 +03:00
let e = [5field; 2];
2020-04-24 03:43:58 +03:00
// initialize a boolean array
2020-05-05 02:52:32 +03:00
let f = [true, false || true, true];
2020-04-24 03:43:58 +03:00
return d
}
```
2020-05-21 21:03:43 +03:00
### Multidimensional Arrays
2020-07-05 22:04:33 +03:00
```js
2020-05-21 21:03:43 +03:00
function main() -> u32[3][2] {
2020-07-04 08:44:09 +03:00
let m = [[0u32, 0u32], [0u32, 0u32]];
2020-04-24 03:43:58 +03:00
2020-07-04 08:44:09 +03:00
let m: u32[3][2] = [[0; 3]; 2];
2020-05-05 02:52:32 +03:00
2020-07-04 08:44:09 +03:00
return m
2020-05-05 02:52:32 +03:00
}
```
2020-05-21 21:03:43 +03:00
## Conditionals
2020-05-05 02:52:32 +03:00
2020-06-16 22:55:59 +03:00
Branching in Leo is different than traditional programming languages. Leo developers should keep in mind that every program compiles to a circuit which represents
all possible evaluations.
2020-05-21 21:03:43 +03:00
### If Else Ternary Expression
2020-06-16 22:55:59 +03:00
Ternary `if [cond] ? [first] : [second];` expressions are the cheapest form of conditional.
Since `first` and `second` are expressions, we can resolve their values before proceeding execution.
In the underlying circuit, this is a single bit multiplexer.
2020-07-05 22:04:33 +03:00
```js
2020-05-05 02:52:32 +03:00
function main() -> u32 {
2020-07-04 08:44:09 +03:00
let y = if 3==3 ? 1 : 5;
return y
2020-04-24 03:43:58 +03:00
}
```
2020-05-21 21:03:43 +03:00
### If Else Conditional Statement
2020-06-16 22:55:59 +03:00
Leo supports the traditional `if [cond] { [first] } else { [second] }` which can be chained using `else if` .
Since `first` and `second` are one or more statements, they resolve to separate circuits which will all be evaluated.
In the underlying circuit this can be thought of as a demultiplexer.
2020-07-05 22:04:33 +03:00
```js
2020-06-15 23:38:07 +03:00
function main(a: bool, b: bool) -> u32 {
2020-07-04 08:44:09 +03:00
let mut res = 0u32;
if a {
res = 1;
} else if b {
res = 2;
} else {
res = 3;
}
return res
2020-05-05 02:52:32 +03:00
}
```
2020-05-21 21:03:43 +03:00
### For loop
2020-07-05 22:04:33 +03:00
```js
2020-06-03 02:16:41 +03:00
function main() -> fe {
2020-07-04 08:44:09 +03:00
let mut a = 1field;
for i in 0..4 {
a = a + 1;
}
return a
2020-04-24 03:43:58 +03:00
}
```
2020-05-21 21:03:43 +03:00
## Functions
2020-07-05 22:04:33 +03:00
```js
2020-05-05 02:52:32 +03:00
function test1(a : u32) -> u32 {
2020-07-04 08:44:09 +03:00
return a + 1
2020-04-24 03:43:58 +03:00
}
2020-07-08 13:30:15 +03:00
function test2(b: fe) -> field {
2020-07-04 08:44:09 +03:00
return b * 2field
2020-04-24 03:43:58 +03:00
}
2020-05-05 02:52:32 +03:00
function test3(c: bool) -> bool {
2020-07-04 08:44:09 +03:00
return c & & true
2020-04-24 03:43:58 +03:00
}
2020-05-05 02:52:32 +03:00
function main() -> u32 {
2020-07-04 08:44:09 +03:00
return test1(5)
2020-04-24 03:43:58 +03:00
}
```
2020-05-21 21:03:43 +03:00
### Function Scope
2020-07-05 22:04:33 +03:00
```js
2020-07-08 13:30:15 +03:00
function foo() -> field {
2020-07-04 08:44:09 +03:00
// return myGlobal < - not allowed
return 42field
2020-05-05 02:52:32 +03:00
}
2020-07-08 13:30:15 +03:00
function main() -> field {
2020-07-04 08:44:09 +03:00
let myGlobal = 42field;
return foo()
2020-05-05 02:52:32 +03:00
}
```
2020-05-21 21:03:43 +03:00
### Multiple returns
2020-05-05 02:52:32 +03:00
Functions can return tuples whose types are specified in the function signature.
2020-07-05 22:04:33 +03:00
```js
2020-05-05 02:52:32 +03:00
function test() -> (u32, u32[2]) {
2020-07-07 20:18:18 +03:00
return (1, [2, 3])
2020-04-24 03:43:58 +03:00
}
2020-05-05 02:52:32 +03:00
function main() -> u32[3] {
let (a, b) = test();
2020-05-09 02:39:14 +03:00
// (a, u32[2] b) = test() < - explicit type also works
2020-05-05 02:52:32 +03:00
return [a, ...b]
2020-04-24 03:43:58 +03:00
}
```
2020-06-16 22:55:59 +03:00
### Function inputs
2020-06-15 23:38:07 +03:00
Main function inputs are allocated private variables in the program's constraint system.
`a` is implicitly private.
2020-07-05 22:04:33 +03:00
```js
2020-07-08 13:30:15 +03:00
function main(a: field) -> field {
2020-07-04 08:44:09 +03:00
return a
2020-06-03 02:16:41 +03:00
}
```
2020-06-16 22:55:59 +03:00
Normal function inputs are passed by value.
2020-07-05 22:04:33 +03:00
```js
2020-05-21 21:03:43 +03:00
function test(mut a: u32) {
2020-05-05 02:52:32 +03:00
a = 0;
}
function main() -> u32 {
let a = 1;
test(a);
return a // < - returns 1
}
```
2020-04-24 03:43:58 +03:00
2020-05-21 21:03:43 +03:00
## Circuits
2020-06-03 02:16:41 +03:00
Circuits in Leo are similar to classes in object oriented langauges. Circuits are defined above functions in a Leo program. Circuits can have one or more members.
2020-07-04 08:44:09 +03:00
#### Circuit member values
Members can be defined as fields which hold primitive values.
2020-07-05 22:04:33 +03:00
```js
2020-05-21 21:03:43 +03:00
circuit Point {
x: u32
y: u32
}
function main() -> u32 {
2020-06-03 02:16:41 +03:00
let p = Point {x: 1, y: 0};
2020-05-21 21:03:43 +03:00
return p.x
}
```
2020-06-03 02:16:41 +03:00
2020-07-04 08:44:09 +03:00
#### Circuit member functions
2020-06-03 02:16:41 +03:00
Members can also be defined as functions.
2020-07-05 22:04:33 +03:00
```js
2020-07-04 08:44:09 +03:00
circuit Foo {
2020-06-03 02:16:41 +03:00
function echo(x: u32) -> u32 {
return x
}
}
function main() -> u32 {
2020-07-04 08:44:09 +03:00
let c = Foo { };
2020-06-03 02:16:41 +03:00
return c.echo(1u32)
}
```
2020-07-04 08:44:09 +03:00
#### Circuit member static functions
2020-06-03 02:16:41 +03:00
Circuit functions can be made static, enabling them to be called without instantiation.
2020-07-05 22:04:33 +03:00
```js
2020-07-04 08:44:09 +03:00
circuit Foo {
2020-06-03 02:16:41 +03:00
static function echo(x: u32) -> u32 {
return x
}
}
function main() -> u32 {
2020-07-04 08:44:09 +03:00
return Foo::echo(1u32)
2020-06-03 02:16:41 +03:00
}
```
2020-07-04 08:44:09 +03:00
#### `Self` and `self`
2020-06-03 02:16:41 +03:00
The `Self` keyword is supported in circuit functions.
2020-07-05 22:04:33 +03:00
```js
2020-06-03 02:16:41 +03:00
circuit Circ {
b: bool
2020-07-04 08:44:09 +03:00
static function new() -> Self { // Self resolves to Foo
return Self { b: true }
}
2020-05-21 21:03:43 +03:00
}
2020-06-03 02:16:41 +03:00
2020-07-04 08:44:09 +03:00
function main() -> bool {
let c = Foo::new();
return c.b
2020-05-21 21:03:43 +03:00
}
```
2020-07-04 08:44:09 +03:00
The `self` keyword references the circuit's members.
```rust
circuit Foo {
b: bool
function bar() -> bool {
return self.b
}
2020-07-04 08:46:09 +03:00
function baz() -> bool {
return self.bar()
}
2020-07-04 08:44:09 +03:00
}
function main() -> bool {
let c = Foo { b: true };
2020-07-04 08:46:09 +03:00
return c.baz()
2020-07-04 08:44:09 +03:00
}
```
2020-05-21 21:03:43 +03:00
## Imports
2020-07-04 08:44:09 +03:00
Leo supports importing functions
}
} and circuits by name into the current file with the following syntax:
2020-05-05 02:52:32 +03:00
2020-07-05 22:04:33 +03:00
```js
2020-06-30 04:37:52 +03:00
import [package].[name];
2020-06-20 06:57:24 +03:00
```
2020-05-05 02:52:32 +03:00
2020-06-30 04:37:52 +03:00
#### Import Aliases
To import a name using an alias:
2020-07-05 22:04:33 +03:00
```js
2020-06-30 04:37:52 +03:00
import [package].[name] as [alias];
```
#### Import Multiple
To import multiple names from the same package:
2020-07-05 22:04:33 +03:00
```js
2020-06-30 04:37:52 +03:00
import [package].(
[name_1],
[name_2] as [alias],
);
```
#### Import Star
To import all symbols from a package:
2020-07-03 07:41:29 +03:00
Note that this will only import symbols from the package library `lib.leo` file.
2020-07-05 22:04:33 +03:00
```js
2020-06-30 04:37:52 +03:00
import [package].*;
```
### Local
2020-07-03 07:36:22 +03:00
You can import from a local file in the same package using its direct path.
`src/` directory by using its `[file].leo` as the `[package]` name.
2020-06-30 04:37:52 +03:00
2020-07-05 22:04:33 +03:00
```js
2020-06-30 04:37:52 +03:00
import [file].[name];
```
#### Example:
`src/bar.leo`
2020-07-05 22:04:33 +03:00
```js
2020-06-30 04:37:52 +03:00
circuit Bar {
b: u32
2020-04-24 03:43:58 +03:00
}
2020-05-05 02:52:32 +03:00
2020-06-30 04:37:52 +03:00
function baz() -> u32 {
return 1u32
}
```
`src/main.leo`
2020-07-05 22:04:33 +03:00
```js
2020-06-30 04:37:52 +03:00
import bar.(
Bar,
baz
);
function main() {
const bar = Bar { b: 1u32};
const z = baz();
2020-05-05 02:52:32 +03:00
}
2020-04-24 03:43:58 +03:00
```
2020-06-30 04:37:52 +03:00
### Foreign
You can import from a foreign package in the `imports/` directory using its `[package]` name.
2020-07-05 22:04:33 +03:00
```js
2020-06-30 04:37:52 +03:00
import [package].[name];
```
2020-05-05 02:52:32 +03:00
2020-06-30 04:37:52 +03:00
#### Example:
`imports/bar/src/lib.leo`
2020-07-05 22:04:33 +03:00
```js
2020-06-30 04:37:52 +03:00
circuit Bar {
b: u32
}
```
2020-04-24 03:43:58 +03:00
2020-06-30 04:37:52 +03:00
`src/main.leo`
2020-07-05 22:04:33 +03:00
```js
2020-06-30 04:37:52 +03:00
import bar.Bar;
2020-05-09 02:39:14 +03:00
2020-06-30 04:37:52 +03:00
function main() {
const bar = Bar { b: 1u32 };
}
```
2020-05-09 02:39:14 +03:00
2020-06-30 04:37:52 +03:00
### Package Paths
Leo treats directories as package names when importing.
2020-07-05 22:04:33 +03:00
```js
2020-06-30 04:37:52 +03:00
import [package].[directory].[file].[name]
```
#### Example:
We wish to import the `Baz` circuit from the `baz.leo` file in the `bar` directory in the `foo` package
`imports/foo/src/bar/baz.leo`
2020-07-05 22:04:33 +03:00
```js
2020-06-30 04:37:52 +03:00
circuit Baz {
b: u32
}
```
`src/main.leo`
2020-07-05 22:04:33 +03:00
```js
2020-06-30 04:37:52 +03:00
import foo.bar.baz.Baz;
function main() {
const baz = Baz { b: 1u32 };
2020-04-24 03:43:58 +03:00
}
```
2020-05-21 21:03:43 +03:00
## Constraints
### Assert Equals
This will enforce that the two values are equal in the constraint system.
2020-07-05 22:04:33 +03:00
```js
2020-05-21 21:03:43 +03:00
function main() {
2020-07-04 08:44:09 +03:00
assert_eq!(45, 45);
2020-05-21 21:03:43 +03:00
2020-07-04 08:44:09 +03:00
assert_eq!(2fe, 2fe);
2020-05-21 21:03:43 +03:00
2020-07-04 08:44:09 +03:00
assert_eq!(true, true);
2020-05-21 21:03:43 +03:00
}
```
2020-05-05 02:52:32 +03:00
2020-06-03 02:16:41 +03:00
## Testing
Use the `test` keyword to add tests to a leo program. Tests must have 0 function inputs and 0 function returns.
2020-07-05 22:04:33 +03:00
```js
2020-06-03 02:16:41 +03:00
function main(a: u32) -> u32 {
return a
}
test function expect_pass() {
2020-07-04 08:44:09 +03:00
let a = 1u32;
2020-06-03 02:16:41 +03:00
2020-07-04 08:44:09 +03:00
let res = main(a);
2020-06-03 02:16:41 +03:00
2020-07-04 08:44:09 +03:00
assert_eq!(res, 1u32);
2020-06-03 02:16:41 +03:00
}
test function expect_fail() {
2020-07-04 08:44:09 +03:00
assert_eq!(1u8, 0u8);
2020-06-03 02:16:41 +03:00
}
```
2020-07-10 04:55:53 +03:00
## Logging
2020-07-09 15:14:44 +03:00
2020-08-17 03:20:47 +03:00
Leo supports `console.log(` , `debug!` , and `error!` logging macros.
2020-07-09 15:14:44 +03:00
2020-07-10 05:23:15 +03:00
The first argument a macro receives is a format string. This must be a string literal. The power of the formatting string is in the `{}` s contained.
Additional parameters passed to a macro replace the `{}` s within the formatting string in the order given.
2020-07-09 15:14:44 +03:00
2020-08-17 03:20:47 +03:00
#### `console.log(`
2020-07-09 15:14:44 +03:00
Directly calls the `println!` macro in rust.
```js
function main(a: u32) {
2020-08-17 03:20:47 +03:00
console.log("a is {}", a);
2020-07-09 15:14:44 +03:00
}
```
#### `debug!`
Enabled by specifying the `-d` flag after a Leo command.
```js
function main(a: u32) {
debug!("a is {}", a);
}
```
#### `error!`
2020-07-10 05:23:15 +03:00
Prints the error to console.
2020-07-09 15:14:44 +03:00
```js
function main(a: u32) {
error!("a is {}", a);
}
```
2020-06-11 23:06:36 +03:00
# Leo Inputs
2020-06-15 23:38:07 +03:00
Private inputs for a Leo program are specified in the `inputs/` directory. The syntax for an input file is a limited subset of the Leo program syntax. The default inputs file is `inputs/inputs.leo` .
2020-06-11 23:06:36 +03:00
## Sections
A Leo input file is made up of sections. Sections are defined by a section header in brackets followed by one or more input definitions.
2020-06-12 00:40:27 +03:00
Section headers specify the target file which must have a main function with matching input names and types.
2020-06-11 23:06:36 +03:00
`inputs/inputs.leo`
```rust
[main] // < - section header
2020-06-15 23:38:07 +03:00
a: u32 = 1;
b: u32 = 2;
2020-06-11 23:06:36 +03:00
```
`src/main.leo`
```rust
2020-06-15 23:38:07 +03:00
function main(a: u32, b: u32) -> u32 {
2020-06-11 23:06:36 +03:00
let c: u32 = a + b;
return c
}
```
## Input Definitions
### Supported types
```rust
[main]
a: bool = true; // < - booleans
b: u8 = 2; // < - integers
2020-07-08 13:30:15 +03:00
c: field = 0; // < - fields
2020-06-11 23:06:36 +03:00
d: group = (0, 1)group // < - group tuples
```
### Arrays
```rust
[main]
2020-06-15 23:38:07 +03:00
a: u8[4] = [0u8; 4]; // < - single
b: u8[2][3] = [[0u8; 2]; 3]; // < - multi-dimensional
2020-06-11 23:06:36 +03:00
```
2020-04-24 03:43:58 +03:00
# Leo CLI
## Develop
2020-05-05 02:52:32 +03:00
### `leo new`
To setup a new package, run:
```
leo new {$NAME}
```
This will create a new directory with a given package name. The new package will have a directory structure as follows:
```
- inputs # Your program inputs
2020-06-11 23:06:36 +03:00
- inputs.leo # Your program inputs for main.leo
2020-05-05 02:52:32 +03:00
- outputs # Your program outputs
- src
- main.leo # Your program
- tests
2020-05-21 21:03:43 +03:00
- test.leo # Your program tests
2020-05-05 02:52:32 +03:00
- Leo.toml # Your program manifest
```
2020-06-30 05:36:30 +03:00
#### Flags
```rust
leo new {$Name} --bin
```
This will create a new directory with a given package name. The new package will have a directory structure as above.
```rust
leo new {$Name} --lib
```
This will create a new directory with a given package name. The new package will have a directory structure as follows:
```
- src
- lib.leo # Your program library
- Leo.toml # Your program manifest
```
2020-05-05 02:52:32 +03:00
### `leo init`
To initialize an existing directory, run:
```
leo init
```
This will initialize the current directory with the same package directory setup.
2020-06-30 05:36:30 +03:00
#### Flags
`leo init` supports the same flags as `leo new`
```rust
leo init --bin
```
```rust
leo init --lib
```
2020-05-05 02:52:32 +03:00
### `leo build`
2020-04-24 03:43:58 +03:00
To compile your program and verify that it builds properly, run:
```
leo build
```
2020-05-05 02:52:32 +03:00
### `leo test`
2020-04-24 03:43:58 +03:00
To execute unit tests on your program, run:
```
leo test
```
2020-06-03 02:16:41 +03:00
The results of test compilation and the constraint system will be printed:
```
INFO leo Running 2 tests
INFO leo test language::expect_pass compiled. Constraint system satisfied: true
ERROR leo test language::expect_fail errored: Assertion 1u8 == 0u8 failed
```
2020-04-24 03:43:58 +03:00
## Run
2020-05-05 02:52:32 +03:00
### `leo setup`
2020-04-24 03:43:58 +03:00
To perform the program setup, producing a proving key and verification key, run:
```
leo setup
```
Leo uses cryptographic randomness from your machine to perform the setup. The proving key and verification key are stored in the `target` directory as `.leo.pk` and `.leo.vk` :
```
{$LIBRARY}/target/{$PROGRAM}.leo.pk
{$LIBRARY}/target/{$PROGRAM}.leo.vk
```
2020-05-05 02:52:32 +03:00
### `leo prove`
2020-04-24 03:43:58 +03:00
To execute the program and produce an execution proof, run:
```
leo prove
```
Leo starts by checking the `target` directory for an existing `.leo.pk` file. If it doesn't exist, it will proceed to run `leo setup` and then continue.
2020-06-11 23:06:36 +03:00
Next any input files in the `inputs` directory are parsed and all input values are passed to the program.
2020-04-24 03:43:58 +03:00
Once again, Leo uses cryptographic randomness from your machine to produce the proof. The proof is stored in the `target` directory as `.leo.proof` :
```
{$LIBRARY}/target/{$PROGRAM}.leo.proof
```
2020-05-05 02:52:32 +03:00
### `leo verify`
2020-04-24 03:43:58 +03:00
To verify the program proof, run:
```
leo verify
```
Leo starts by checking the `target` directory for an existing `.leo.proof` file. If it doesn't exist, it will proceed to run `leo prove` and then continue.
After the verifier is run, Leo will output either `true` or `false` based on the verification.
## Remote
To use remote compilation features, start by authentication with:
```
leo login
```
You will proceed to authenticate using your username and password. Next, Leo will parse your `Leo.toml` file for `remote = True` to confirm whether remote compilation is enabled.
If remote compilation is enabled, Leo syncs your workspace so when you run `leo build` , `leo test` , `leo setup` and `leo prove` , your program will run the program setup and execution performantly on remote machines.
This speeds up the testing cycle and helps the developer to iterate significantly faster.
## Publish
To package your program as a gadget and publish it online, run:
```
leo publish
```
Leo will proceed to snapshot your directory and upload your directory to the circuit manager. Leo will verify that `leo build` succeeds and that `leo test` passes without error.
If your gadget name has already been taken, `leo publish` will fail.
## Deploy
2020-05-05 02:52:32 +03:00
To deploy your program to Aleo, run:
2020-04-24 03:43:58 +03:00
```
leo deploy
```
2020-05-21 21:03:43 +03:00
# Install
To install Leo from source, in the root directory of the repository, run:
```
cargo install --path .
```
2020-04-24 03:43:58 +03:00
## TODO
- Change `target` directory to some other directory to avoid collision.
- Figure out how `leo prove` should take in assignments.
2020-06-16 22:55:59 +03:00
- Come up with a serialization format for `.leo.pk` , `.leo.vk` , and `.leo.proof` .