Стартовый пакет Leo Development
Tags: aleo, instructions, install, privacy
Published: 2022-09-03 11:44:27

В предыдущем посте мы объяснили, как разрабатывать на базе Aleo с помощью инструкций Aleo. В этом посте мы расскажем о том, как использовать Leo, язык более высокого уровня, чем инструкции Aleo, который компилируется до инструкций Aleo, чтобы начать разработку на базе Aleo.

Aleo SDK - это набор инструментов, который делает разработку на Aleo простой и удобной для разработчиков. С помощью этого инструмента вы можете создавать новые аккаунты, структуры (также известные как программы в экосистеме Aleo), создавать транзакции и отправлять их в сеть.

## 1. Подготовка среды

Чтобы начать работать с Leo, вам понадобится пакет инструментов Aleo и Leo в вашей среде. Вам также понадобится компилятор Rust (v1.62 или выше) для сборки Aleo SDK. Если вы еще не установили его, просто запустите следующее в терминале:

```javascript
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
```
Если вам нужно только обновить версию Rust, вы можете выполнить команду:

```javascript
rustup update stable
```
Вы должны обновить переменные среды, чтобы иметь возможность использовать Rust на данном этапе. Это легко сделать, закрыв терминал и открыв его снова.


Далее, чтобы установить Aleo SDK, выполните команду:

```javascript
# Download the source code
git clone https://github.com/AleoHQ/aleo && cd aleo

# Install Aleo
$ cargo install --path .
```
Теперь вы можете проверить, работает ли он:

```javascript
aleo -h
```
и вы должны увидеть следующий результат:

```javascript
aleo
The Aleo Team <hello@aleo.org>

USAGE:
    aleo [OPTIONS] <SUBCOMMAND>

OPTIONS:
    -h, --help                     Print help information
    -v, --verbosity <VERBOSITY>    Specify the verbosity [options: 0, 1, 2, 3] [default: 2]

SUBCOMMANDS:
    account    Commands to manage Aleo accounts
    build      Compiles an Aleo program
    clean      Cleans the Aleo package build directory
    help       Print this message or the help of the given subcommand(s)
    new        Create a new Aleo package
    node       Commands to operate a local development node
    run        Executes an Aleo program function
    update     Update Aleo
```

Чтобы установить компилятор Leo:

```javascript
# Download the source code
git clone https://github.com/AleoHQ/leo && cd leo

# Install Leo
$ cargo install --path .
```
Теперь вы можете проверить, работает ли он:

```javascript
leo -h
```
и вы должны увидеть следующий результат:

```javascript
leo
The Aleo Team <hello@aleo.org>
CLI Arguments entry point - includes global parameters and subcommands

USAGE:
    leo [OPTIONS] [API] <SUBCOMMAND>

ARGS:
    <API>    Custom Aleo PM backend URL [env: APM_URL=]

OPTIONS:
    -d                   Print additional information for debugging
    -h, --help           Print help information
        --path <PATH>    Optional path to Leo program root folder
    -q                   Suppress CLI output

SUBCOMMANDS:
    build    Compile the current package as a program
    clean    Clean the output directory
    help     Print this message or the help of the given subcommand(s)
    new      Create a new Leo package in a new directory
    run      Run a program with input variables
```

Легко и просто. Идем дальше.

## 2. Создание и построение простой программы Leo

В этом шаге мы создадим простую программу Aleo для передачи наших собственных токенов. Для этого мы определим нашу собственную запись под названием token (базовая структура Aleo для работы с состоянием) и напишем функцию для передачи этих токенов между аккаунтами.

**Создание программы**

Давайте запустим новый проект Leo:

```javascript
leo new token
cd token
```

Это создаст наш шаблон для начала кодирования вашей новой программы Leo под названием token.

Пока что мы заполним наш файл _main.leo_ следующим кодом:

```javascript
record Token {
    owner: address,
    gates: u64,
    amount: u64,
}

@program
function mint_token(
    token_address: address,
    token_amount: u64,
    password: field,
) -> Token {
    // checks if the password is correct
    let candidate: field = Poseidon2::hash(password); 
    let is_correct: bool = candidate == 7202470996857839225873911078012225723419856133099120809866608931983814353616field;

    // stores amount input into r5 if the password was right 
    // otherwise, it stores 0u64 to avoid token creation
    let new_amount: u64 = is_correct ? token_amount : 0u64;

    // create a new token
    let new_token: Token = Token {
        owner: token_address,
        gates: 0u64,
        amount: new_amount,
    };

    return new_token;
}

@program 
function transfer_token(
    sender: Token,
    receiver: address,
    transfer_amount: u64,
) -> (Token, Token) {
    // final balance for sender
    let sender_balance: u64 = sender.amount - transfer_amount;

    // final balance for receiver
    let receiver_balance: u64 = 0u64 + transfer_amount;

    // Sender token record after the transfer.
    let sender_token: Token = Token {
        owner: sender.owner,
        gates: sender.gates,
        amount: sender_balance,
    };

    // Receiver token record after the transfer.
    let receiver_token: Token = Token {
        owner: receiver,
        gates: 0u64,
        amount: receiver_balance,
    };

    return (sender_token, receiver_token);
}
```

Эти строки кода называются Leo.  Leo - это язык программирования высокого уровня с синтаксисом, похожим на Rust, который компилируется в Aleo Instructions. Подробнее об Aleo Instructions вы можете прочитать в [этом посте](https://dev.to/egormajj/startovyi-pakiet-aleo-development-nal).

Давайте создадим нашу программу Leo:

```javascript
leo build
```

```javascript
     Build ✅ Compiled 'main.leo' into Aleo instructions (in "/[...]/token/build/main.aleo")
⏳ Compiling 'token.aleo'...

 • Loaded universal setup (in 1468 ms)
 • Built 'mint_token' (in 11998 ms)
 • Built 'transfer_token' (in 23148 ms)

     Build ✅ Built 'token.aleo' (in "[...]/token/build")
```

> **Примечание**:
> Если вы впервые создаете программу Aleo, вам, вероятно, придется подождать, пока загрузится "universal setup". Не паникуйте, если в первый раз вы увидите другой результат!

После сборки вы найдете несколько файлов в каталоге _/build_:


- _main.aleo_: Файл, содержащий эквивалентный код инструкций Aleo.
- 2 файла для каждой функции в вашем файле _main.leo_:
  - _/build/function_name.prover_: проверка для ваших функций
  - _/build/function_name.verifier_: верификатор для вашей функции

Вы обнаружите, что код в файле _/build/main.aleo_ очень похож на код, который мы написали в посте [Стартовый пакет Aleo Development](https://dev.to/egormajj/startovyi-pakiet-aleo-development-nal), и в этом вся идея!

## 3. Создание аккаунтов

Мы создадим два аккаунта Aleo для работы и осуществления переводов, для этого мы будем использовать Aleo Cli:

**Аккаунт S:**

```javascript
aleo account new
```

```javascript
  Private Key  APrivateKey1zkpAQpLeFgujVMkMEVKXhotR9XVa8B8nGfugMXYXHMdeHnN
     View Key  AViewKey1f6ZSnCkgsatCTDDSX5UgXXfjR14pyQ8oizxE5QGcWTxB
      Address  aleo1nmjzszxsejh0ec6s9tgdx03g24l8e3ev0jy6fx2ckz7s4vt7hgxqu8hz04
```
**Аккаунт R:**

```javascript
aleo account new
```

```javascript
 Private Key  APrivateKey1zkpFoVnVMTGvYKRALnzHkU9nKbMZ9Ueu9ZdsouvdmZzEmhh
     View Key  AViewKey1jf1aLTv7mu1zQ8FyNK4So6VrVoE5rk2xT7jywzS9Nptq
      Address  aleo13tny7lhjh7ckjm6ettxvzvdhj856dq6s657nef0p9h9gfruyavzqftkscg
```
Мы будем использовать **аккаунт S** для отправителя и **аккаунт R** для получателя.

## 4. Запуск нашей программы

Чтобы запустить нашу программу token, нам нужно сначала настроить файл program.json. Обновите private_key и адрес разработки на адрес только что созданного аккаунта S.

Он должен выглядеть следующим образом:

```javascript
{
    "program": "token.aleo",
    "version": "0.0.0",
    "description": "",
    "development": {
        "private_key": "APrivateKey1zkpAQpLeFgujVMkMEVKXhotR9XVa8B8nGfugMXYXHMdeHnN",
        "address": "aleo1nmjzszxsejh0ec6s9tgdx03g24l8e3ev0jy6fx2ckz7s4vt7hgxqu8hz04"
    },
    "license": "MIT"
}
```
Это важно, поскольку с точки зрения выполнения Aleo, **аккаунт S** будет тем, кто запускает программу для отправки токенов на **аккаунт R**. Это имеет некоторые последствия для безопасности, поскольку вы можете вводить записи только при запуске программы, принадлежащей аккаунту, указанному в _program.json_, как мы увидим через секунду.

Сначала нам нужно запустить функцию mint, чтобы сгенерировать начальное количество токенов, принадлежащих **S**. Эта функция требует ввода пароля для вывода записи с указанным количеством. Если заданный пароль неверен, выполнение завершится неудачей, что позволит избежать создания токенов.

Пароль для данного примера следующий:

```javascript
3634422524977942384127113436866104517282080062207687912678345956934082270693field
```
Перед запуском нашей программы нам нужно поместить наши входные значения в файл _/inputs/token.in_. Он должен выглядеть следующим образом:

```javascript
// The program input for token/src/main.leo
[mint_token]
token_address: address = aleo1nmjzszxsejh0ec6s9tgdx03g24l8e3ev0jy6fx2ckz7s4vt7hgxqu8hz04;
token_amount: u64 = 100u64;
password: field = 3634422524977942384127113436866104517282080062207687912678345956934082270693field;

[transfer_token]
sender: Token = Token {
	owner: aleo1nmjzszxsejh0ec6s9tgdx03g24l8e3ev0jy6fx2ckz7s4vt7hgxqu8hz04,
	gates: 0u64,
	amount: 100u64,
	_nonce: 3876229187441842049461335878835982325882299702372891379463684506061517728045group
};
receiver: address = aleo13tny7lhjh7ckjm6ettxvzvdhj856dq6s657nef0p9h9gfruyavzqftkscg;
transfer_amount: u64 = 10u64;
```

Это будут входы команды _leo run [function_name]_. Итак, давайте запустим нашу программу:

```javascript
leo run mint_token
```
и мы должны увидеть следующий результат:

```javascript
     Build ✅ Compiled 'main.leo' into Aleo instructions (in "[...]/token/build/main.aleo")
     Build ✅ Built 'token.aleo' (in "[...]/token/build")
 • Loaded universal setup (in 1454 ms)
🚀 Executing 'token.aleo/mint_token'...

 • Executing 'token.aleo/mint_token'...
 • Executed 'mint_token' (in 2041 ms)

➡️  Output

 • {
  owner: aleo1nmjzszxsejh0ec6s9tgdx03g24l8e3ev0jy6fx2ckz7s4vt7hgxqu8hz04.private,
  gates: 0u64.private,
  amount: 100u64.private,
  _nonce: 3876229187441842049461335878835982325882299702372891379463684506061517728045group.public
}
```
Теперь давайте используем эту запись для передачи 10 токенов от **S** к **R**

(Не забудьте сначала обновить выходную запись в файле _/inputs/token.in_ в разделе [transfer_token])

```javascript
leo run transfer_token
```
и на выходе мы должны увидеть две записи, каждая из которых представляет текущее состояние наших записей токенов для каждого аккаунта.

```javascript
     Build ✅ Compiled 'main.leo' into Aleo instructions (in "[...]/token/build/main.aleo")
     Build ✅ Built 'token.aleo' (in "[...]/token/build")
 • Loaded universal setup (in 1435 ms)
🚀 Executing 'token.aleo/transfer_token'...

 • Executing 'token.aleo/transfer_token'...
 • Executed 'transfer_token' (in 3813 ms)

➡️  Outputs

 • {
  owner: aleo1nmjzszxsejh0ec6s9tgdx03g24l8e3ev0jy6fx2ckz7s4vt7hgxqu8hz04.private,
  gates: 0u64.private,
  amount: 90u64.private,
  _nonce: 3924935820556017546608088447675398982328122626644166445123029606162286460205group.public
}
 • {
  owner: aleo13tny7lhjh7ckjm6ettxvzvdhj856dq6s657nef0p9h9gfruyavzqftkscg.private,
  gates: 0u64.private,
  amount: 10u64.private,
  _nonce: 399066858986674923461032168044059424715982416876645955785093049578684887771group.public
}
```
Вот и все! Мы осуществили первую передачу токенов в Leo.