В этом посте мы сделаем обзор различных инструментов, доступных в Aleo SDK, чтобы начать разработку на Aleo.
Aleo SDK - это набор инструментов, который делает разработку на Aleo простой и удобной для разработчиков. С помощью этого инструмента вы можете создавать новые аккаунты, структуры (также известные как программы в экосистеме Aleo), создавать транзакции и отправлять их в сеть.
1. Настройка среды
Чтобы начать работать с Aleo, вам понадобится Aleo CLI, доступный в вашей среде. Вам также понадобится сборник rust (v1.62 или выше) для создания Aleo SDK. Если вы еще не установили его, просто запустите следующее в терминале:
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
Если вам нужно только обновить версию rust, вы можете выполнить команду:
rustup update stable
Вы должны обновить переменные среды, чтобы иметь возможность использовать Rust на данном этапе. Вы можете сделать это, просто закрыв терминал и открыв его снова.
Далее, чтобы установить Aleo SDK, запустите программу:
# Download the source code
git clone https://github.com/AleoHQ/aleo && cd aleo
# Install Aleo
$ cargo install --path .
Теперь вы можете проверить, работает ли она:
aleo -h
и вы должны увидеть следующий результат:
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
Легко и просто. Идем дальше.
2. Создание и построение простой программы
В этом шаге мы создадим простую программу Aleo для передачи наших собственных токенов. Для этого мы определим нашу собственную запись под названием token (базовая структура Aleo для работы с состоянием) и напишем функцию для передачи этих токенов между аккаунтами.
Создание программы
Давайте запустим новый проект Aleo:
aleo new token
cd token
Это создаст наш шаблон для начала кодирования вашей новой программы Aleo под названием token.
Пока что мы заполним наш файл main.aleo следующим кодом:
// The 'token.aleo' program.
program token.aleo;
// Our own defined record called token
record token:
owner as address.private;
gates as u64.private;
amount as u64.private;
// function to mint a new token
function mint_token:
// token address
input r0 as address.private;
// token amount
input r1 as u64.private;
// password
input r2 as field.private;
// checks if the password is correct
hash.psd2 r2 into r3;
// it will continue running only is the password hashes match
// the execution will fail otherwise.
assert.eq r3 7202470996857839225873911078012225723419856133099120809866608931983814353616field;
// create a new token in r2 register
cast r0 0u64 r1 into r4 as token.record;
// return the new token
output r4 as token.record;
// Function to transfer tokens between accounts
function transfer_token:
// sender token record
input r0 as token.record;
// receiver address
input r1 as address.private;
// amount to transfer
input r2 as u64.private;
// final balance for sender
sub r0.amount r2 into r3;
// final balance for receiver
add 0u64 r2 into r4;
// sender token record after the transfer
cast r0.owner r0.gates r3 into r5 as token.record;
// receiver token record after the transfer
cast r1 0u64 r4 into r6 as token.record;
// sender new token record
output r5 as token.record;
// receiver new token record
output r6 as token.record;
Эти строки кода называются инструкциями Aleo. Инструкции Aleo - это своего рода язык ассемблера для виртуальной машины Aleo snarkVM (виртуальная машина, на которой будут выполняться наши программы), но с довольно высокоуровневыми функциями, такими как система типизации, сложные инструкции для хеширования и так далее.
Подробнее об этих инструкциях вы можете прочитать в этом посте: Начало работы с инструкциями Aleo.
Давайте создадим нашу программу Aleo:
aleo build
⏳ Compiling 'token.aleo'...
• Loaded universal setup (in 1459 ms)
• Built 'transfer' (in 23549 ms)
✅ Built 'token.aleo' (in "/[...]/token")
Примечание:
Если вы впервые создаете программу Aleo, вам, вероятно, придется подождать, пока загрузится "universal setup". Не паникуйте, если в первый раз вы увидите другой результат!
После создания в каталоге /build вы найдете 3 файла:
- main.avm: Файл, содержащий ваш скомпилированный код.
- 2 файла для каждой функции в вашем файле main.aleo:
- function_name.prover: провера для ваших функций
- function_name.verifier: верификатор для ваших функций
Эти файлы будут очень важны при развертывании нашего приложения.
3. Создание аккаунтов
Мы создадим два аккаунта Aleo для работы и осуществления переводов:
Аккаунт S:
aleo account new
Private Key APrivateKey1zkpAQpLeFgujVMkMEVKXhotR9XVa8B8nGfugMXYXHMdeHnN
View Key AViewKey1f6ZSnCkgsatCTDDSX5UgXXfjR14pyQ8oizxE5QGcWTxB
Address aleo1nmjzszxsejh0ec6s9tgdx03g24l8e3ev0jy6fx2ckz7s4vt7hgxqu8hz04
Аккаунт R:
aleo account new
Private Key APrivateKey1zkpFoVnVMTGvYKRALnzHkU9nKbMZ9Ueu9ZdsouvdmZzEmhh
View Key AViewKey1jf1aLTv7mu1zQ8FyNK4So6VrVoE5rk2xT7jywzS9Nptq
Address aleo13tny7lhjh7ckjm6ettxvzvdhj856dq6s657nef0p9h9gfruyavzqftkscg
Мы будем использовать аккаунт S для отправки и аккаунт R для получения.
В Aleo у каждого аккаунта есть несколько связанных ключей:
Их можно представить как пару ключей в асимметричной криптографической системе, где Private key
- это закрытый ключ пары, а другой - открытый ключ, который вытекает из него. В этом понимании Address
- это открытый ключ, который идентифицирует аккаунт, а View Key
- открытый ключ, который позволяет расшифровать записи, принадлежащие адресу аккаунта (любому, кто его знает).
Пока хватит разговоров! Давайте запустим и развернем нашу программу.
4. Запуск нашей программы
Чтобы запустить нашу программу token, нам нужно сначала настроить файл program.json. Обновите private_key и адрес разработки на адрес только что созданного аккаунта S.
Он должен выглядеть следующим образом:
{
"program": "token.aleo",
"version": "0.0.0",
"description": "",
"development": {
"private_key": "APrivateKey1zkpAQpLeFgujVMkMEVKXhotR9XVa8B8nGfugMXYXHMdeHnN",
"address": "aleo1nmjzszxsejh0ec6s9tgdx03g24l8e3ev0jy6fx2ckz7s4vt7hgxqu8hz04"
},
"license": "MIT"
}
Это важно, поскольку с точки зрения выполнения Aleo, аккаунт S будет тем, кто запускает программу для отправки токенов на аккаунт R. Это имеет некоторые последствия для безопасности, поскольку вы можете вводить записи только при запуске программы, принадлежащей аккаунту, указанному в program.json, как мы увидим через секунду.
Сначала нам нужно запустить функцию mint, чтобы сгенерировать начальное количество токенов, принадлежащих S. Эта функция требует ввода пароля для вывода записи с указанным количеством. Если заданный пароль неверен, выполнение завершится неудачей, что позволит избежать создания токенов.
Пароль для данного примера следующий:
3634422524977942384127113436866104517282080062207687912678345956934082270693field
Нам нужно выполнить следующую команду:
aleo run mint_token aleo1nmjzszxsejh0ec6s9tgdx03g24l8e3ev0jy6fx2ckz7s4vt7hgxqu8hz04 100u64 3634422524977942384127113436866104517282080062207687912678345956934082270693field
и мы получаем следующую запись токена:
• Loaded universal setup (in 1472 ms)
🚀 Executing 'token.aleo/mint_token'...
• Executing 'token.aleo/mint_token'...
• Executed 'mint_token' (in 2174 ms)
➡️ Output
• {
owner: aleo1nmjzszxsejh0ec6s9tgdx03g24l8e3ev0jy6fx2ckz7s4vt7hgxqu8hz04.private,
gates: 0u64.private,
amount: 100u64.private,
_nonce: 3024738992072387217402876176731225730589877991873828351104009809002984426287group.public
}
✅ Executed 'token.aleo/mint_token' (in "[...]/token")
Теперь давайте используем эту запись для передачи 10 токенов из S в R
aleo run transfer_token "{
owner: aleo1nmjzszxsejh0ec6s9tgdx03g24l8e3ev0jy6fx2ckz7s4vt7hgxqu8hz04.private,
gates: 0u64.private,
amount: 100u64.private,
_nonce: 3024738992072387217402876176731225730589877991873828351104009809002984426287group.public
}" aleo13tny7lhjh7ckjm6ettxvzvdhj856dq6s657nef0p9h9gfruyavzqftkscg 10u64
и на выходе мы должны увидеть две записи, каждая из которых представляет текущее состояние наших записей токенов для каждого аккаунта.
• Loaded universal setup (in 1473 ms)
🚀 Executing 'token.aleo/transfer_token'...
• Executing 'token.aleo/transfer_token'...
• Executed 'transfer_token' (in 3620 ms)
➡️ Outputs
• {
owner: aleo1nmjzszxsejh0ec6s9tgdx03g24l8e3ev0jy6fx2ckz7s4vt7hgxqu8hz04.private,
gates: 0u64.private,
amount: 90u64.private,
_nonce: 2178231086979351800436660566645386776768595203243256243508388701123108642520group.public
}
• {
owner: aleo13tny7lhjh7ckjm6ettxvzvdhj856dq6s657nef0p9h9gfruyavzqftkscg.private,
gates: 0u64.private,
amount: 10u64.private,
_nonce: 4704084834675699921301424200265500298050115484153136728500446828605991979105group.public
}
✅ Executed 'token.aleo/transfer_token' (in "[...]/token")
Вот и все! Мы выполнили нашу первую передачу токенов.
В качестве тестового примера посмотрим, что произойдет, если мы поменяем местами два адреса (S и R) в последней команде aleo run transfer_token
:
aleo run transfer_token "{
owner: aleo13tny7lhjh7ckjm6ettxvzvdhj856dq6s657nef0p9h9gfruyavzqftkscg.private,
gates: 0u64.private,
amount: 100u64.private,
_nonce: 3024738992072387217402876176731225730589877991873828351104009809002984426287group.public
}" aleo1nmjzszxsejh0ec6s9tgdx03g24l8e3ev0jy6fx2ckz7s4vt7hgxqu8hz04 10u64
Мы получим следующий результат:
• Loaded universal setup (in 1461 ms)
⚠️ Input record for 'token.aleo' must belong to the signer
Это говорит нам о том, что владелец входной записи не принадлежит адресу отправителя, то есть адресу, который мы обновили в нашем program.json.
Как вы уже видите, программы Aleo выполняют несколько высокоуровневых проверок на уязвимости, что делает нашу программу достаточно отказоустойчивой по умолчанию.
5. Развертывание нашей программы на локальном уровне
Чтобы запустить Aleo Node локально, достаточно выполнить следующую команду внутри пути программы в другом терминале:
aleo node start
Подождите пару секунд и обратите внимание на первые результаты:
⏳ Starting a local development node for 'token.aleo' (in-memory)...
• Loaded universal setup (in 1471 ms)
• Executing 'credits.aleo/genesis'...
• Executed 'genesis' (in 1872 ms)
• Loaded universal setup (in 1423 ms)
• Verified 'genesis' (in 46 ms)
• Verified 'genesis' (in 46 ms)
🌐 Server is running at http://0.0.0.0:4180
📦 Deploying 'token.aleo' to the local development node...
• Built 'mint_token' (in 11832 ms)
• Certified 'mint_token': 264 ms
• Built 'transfer_token' (in 23166 ms)
• Certified 'transfer_token': 537 ms
• Calling 'credits.aleo/fee'...
• Executed 'fee' (in 2616 ms)
• Verified certificate for 'mint_token': 89 ms
• Verified certificate for 'transfer_token': 143 ms
• Verified 'fee' (in 47 ms)
• Verified certificate for 'mint_token': 89 ms
• Verified certificate for 'transfer_token': 141 ms
• Verified 'fee' (in 47 ms)
• Verified certificate for 'mint_token': 88 ms
• Verified certificate for 'transfer_token': 143 ms
• Verified 'fee' (in 46 ms)
🛡️ Produced block 1 (ab1cz4e3zrw8xje7q6gutsjkqktvmwhq0yx3j4tqjeqnfr3c2j0f5gs5hwmf9)
{
"previous_state_root": "1864323752948026853541213650623314215454919286649566834473029713121712183360field",
"transactions_root": "2938300578986025380747616267226890561116633830917000361321232469947771414785field",
"metadata": {
"network": 3,
"round": 1,
"height": 1,
"coinbase_target": 18446744073709551615,
"proof_target": 18446744073709551615,
"timestamp": 1660331897
}
}
✅ Deployed 'token.aleo' in transaction 'at13pzudena0mk7xrj7m4tyar5x96ynr7m2q30c27lvc3gr7w5rn58q4agsk2'
• Executing 'credits.aleo/transfer'...
• Executed 'transfer' (in 3336 ms)
• Verified 'transfer' (in 47 ms)
• Verified 'transfer' (in 47 ms)
🛡️ Produced block 2 (ab1d2cypkhgv7fpardzd8pnn8mq8pwtwk453jyzc36cvt7z9r24vcpskj4tmd)
...
Как вы можете видеть здесь, у нас есть локальная нода, работающая и добывающая блоки, наша программа токенов уже развернута в транзакции, а сервер, работающий на http://localhost:4180, ждет запросов. Довольно удивительно, правда?
Обзор наиболее важных конечных точек сервера
В этом разделе мы расскажем о наиболее полезных конечных точках HTTP RESTful, которые вы можете вызвать для получения информации из реестра вашей ноды. Вы можете использовать либо веб-браузер, либо команду curl
.
💡 По умолчанию веб-служба ноды прослушивает соединение на порту 4180.
Получение высоты последнего блока
Чтобы получить последнюю высоту реестра вашей ноды, вы можете сделать GET
-запрос к http://localhost:4180/testnet3/latest/block/height
.
Ответ содержит значение последней высоты вашей работающей ноды.
Получение хэша последнего блока
Чтобы получить хэш последнего блока реестра вашей ноды, вы можете сделать GET
-запрос по адресу
http://localhost:4180/testnet3/latest/block/hash
Вы увидите ответ, содержащий хэш, подобный этому:
"ab14ja24wr9rdg2hmpym35kvw08ywwp6eyhknn23zr3ypwrxvqsjyzqpns7ml"
Получение последнего блока реестра
Чтобы получить последний блок реестра вашей ноды, вы можете сделать GET
-запрос по адресу
http://localhost:4180/testnet3/latest/block
Вы увидите ответ в формате JSON, который содержит атрибуты блока.
Корневыми атрибутами являются: block_hash
, previous_hash
, header
, transactions
и signature
.
Получение блока по высоте
Чтобы получить блок на заданной высоте из реестра вашей ноды, вы можете сделать GET
-запрос по адресу
http://localhost:4180/testnet3/block/{height}
Например:http://localhost:4180/testnet3/block/8
вернет блок высотой 8.
Получение записей, относящихся к аккаунту
Вы можете получить записи тремя различными способами, в зависимости от того, какой тип записей вы хотите запросить. Для этого вам понадобится ваш ключ ViewKey
. Существует два типа записей, потраченные и неизрасходованные, о них мы поговорим позже. Список связанных конечных точек вы можете увидеть ниже:
-
GET /testnet3/records/all
: Эта конечная точка извлекает все записи, принадлежащие заданному ключуViewKey
.
curl --location --request GET 'localhost:4180/testnet3/records/all' -H 'Content-Type: application/json' -d '"AViewKey1iAf6a7fv6ELA4ECwAth1hDNUJJNNoWNThmREjpybqder"'
-
GET /testnet3/records/spent
: Эта конечная точка извлекает только потраченные записи, принадлежащие данному ключуViewKey
.
curl --location --request GET 'localhost:4180/testnet3/records/spent' -H 'Content-Type: application/json' -d '"AViewKey1iAf6a7fv6ELA4ECwAth1hDNUJJNNoWNThmREjpybqder"'
-
GET /testnet3/records/all
: Эта конечная точка извлекает только неизрасходованные записи, принадлежащие данному ключуViewKey
.
curl --location --request GET 'localhost:4180/testnet3/records/unspent' -H 'Content-Type: application/json' -d '"AViewKey1iAf6a7fv6ELA4ECwAth1hDNUJJNNoWNThmREjpybqder"'
В следующих постах мы начнем совершать и транслировать транзакции на наш локальный блокчейн разработки, добиваясь частного исполнения вне сети и частного хранения состояния на сети - ключевых особенностей экосистемы Aleo.
Top comments (0)