# Что такое dApp
dApp — это аккаунт Waves с установленным dApp-скриптом.
dApp-скрипт представляет собой код на языке Ride. Он содержит вызываемые (сallable) функции, которые могут быть вызваны извне путем отправки транзакции вызова скрипта.
Транзакция вызова скрипта содержит:
- адрес dApp;
- имя вызываемой функции и значения аргументов;
- дополнительно транзакция вызова может содержать платежи, которые будут зачислены на баланс dApp.
Пример транзакции вызова скрипта
Результатом выполнения вызываемой функции могут быть:
- добавление, редактирование, изменение записей в хранилище данных аккаунта dApp;
- переводы средств;
- выпуск, довыпуск, сжигание токенов;
- настройка спонсирования.
Набор доступных действий скрипта зависит от версии Стандартной библиотеки.
# Структура dApp-скрипта
dApp-скрипт содержит одну или несколько вызываемых функций.
Кроме того, dApp-скрипт может содержать функцию-верификатор, которая проверяет транзакции и ордера, отправляемые с аккаунта dApp.
# Директивы
Каждый скрипт Ride должен начинаться с директив. Для dApp набор директив следующий:
{-# STDLIB_VERSION 8 #-}
{-# CONTENT_TYPE DAPP #-}
{-# SCRIPT_TYPE ACCOUNT #-}
Приведенные директивы сообщают компилятору, что:
- в скрипте будет использоваться Стандартная библиотека версии 8;
- тип скрипта — dApp;
- скрипт будет привязан к аккаунту (а не к ассету).
# Контекст скрипта
Контекст скрипта включает встроенные переменные и встроенные функции. Кроме того, между директивами и вызываемой функцией можно объявить собственные переменные и вспомогательные функции, которые будут доступны в пределах всего dApp.
Пример:
let someConstant = 42
func doSomething() = {
1+1
}
# Вызываемые функции
Вызываемая функция может быть вызвана извне при помощи транзакции вызова скрипта. Такая функция помечается аннотацией @Callable(i)
, где i
— структура Invocation, которая содержит поля транзакции вызова скрипта, доступные вызываемой функции.
Результат выполнения вызываемой функции — набор действий скрипта, которые будут выполнены на блокчейне: добавление записей в хранилище данных аккаунта, переводы токенов и др. Формат результата и доступные действия зависят от версии Стандартной библиотеки.
Подробное описание приведено в разделе Вызываемая функция.
Ниже приведен пример вызываемой функции, которая переводит вызвавшему ее аккаунту 1 WAVES и записывает информацию об этом в хранилище данных аккаунта. Если тот же аккаунт снова пытается вызвать функцию, она не делает ничего.
@Callable(i)
func faucet () = {
let isKnownCaller = match getBoolean(this, toBase58String(i.caller.bytes)) {
case hist: Boolean =>
hist
case _ =>
false
}
if (!isKnownCaller) then
(
[
BooleanEntry(toBase58String(i.caller.bytes), true),
ScriptTransfer(i.caller, 100000000, unit)
],
unit
)
else ([],unit)
}
# Функция-верификатор
Функция-верификатор проверяет транзакции и ордера, отправляемые с аккаунта dApp (то есть работает аналогично скрипту аккаунта). Эта функция помечается аннотацией @Verifier(tx)
, где tx
— текущая проверяемая транзакция или ордер.
Подробное описание приведено в разделе Функция-верификатор.
Ниже приведен пример функции-верификатора, которая разрешает только транзакции перевода: отправка транзакций другого типа и ордеров запрещена. Задать правила верификации в зависимости от типа транзакции (или ордера) можно с помощью оператора match.
@Verifier(tx)
func verify() = {
match tx {
case ttx:TransferTransaction => sigVerify(ttx.bodyBytes, ttx.proofs[0], ttx.senderPublicKey)
case _ => false
}
}
Если в dApp нет функции верификации, то выполняется верификация по умолчанию, то есть проверка, что транзакция или ордер действительно подписаны этим аккаунтом.
# Данные, к которым имеет доступ dApp
dApp может использовать данные блокчейна:
- Записи в хранилищах данных аккаунтов (как аккаунта самого dApp, так и любых других).
- Балансы аккаунтов.
- Параметры ассетов.
- Высота блокчейна.
- Заголовки блоков.
- Транзакции перевода (по идентификатору транзакции).
См. разделы Функции хранилища данных аккаунта и Функции блокчейна.
Кроме того:
- Вызываемая функция имеет доступ к полям транзакции, которая вызвала dApp-скрипт. Cм. раздел Invocation.
- Функция-верификатор имеет доступ к полям транзакции или ордера, отправляемых с аккаунта dApp, включая подтверждения (proofs).
# Установка dApp-скрипта
Чтобы прикрепить dApp к аккаунту, отправьте с этого аккаунта транзакцию установки скрипта.
Отправить транзакцию установки скрипта можно:
- В Waves IDE: создайте или импортируйте аккаунт, откройте dApp-скрипт и нажмите Deploy.
- С помощью одной из клиентских библиотек. См. также примеры в разделе Создание и отправка транзакций.
Комиссия за транзакцию установки скрипта — 0,01 WAVES.
Если скрипт содержит функцию-верификатор и ее сложность больше порога сложности отправителя, то минимальная комиссия за каждую транзакцию, отправленную с аккаунта dApp, увеличивается на 0,004 WAVES.
# Ограничения
Ограничения на размер, сложность скрипта, а также на функции и переменные приведены в разделе Ограничения.
# Примеры
Примеры dApp-скриптов можно найти:
- В разделе Практические руководства.
- В Waves IDE в меню Library.
- На Github в репозитории ride-examples.
Руководство по созданию dApp приведено в разделе Создание и запуск dApp.
# Статьи в блоге Waves Tech
- Чем хорош протокол Waves для DeFi-приложений? (25 мартa 2021)
- 5 вещей, которые я хотел бы знать до того, как начал разрабатывать децентрализованные приложения (17 июня 2020)
- Как создать dApp для мотивации сотрудников (9 июня 2020)
- Как избежать ошибок при разработке dApp (8 мая 2020)
- Что такое смарт-контракты и как их использовать в приложении (19 мартa 2020)