Як будувати, розгортати та тестувати Waves RIDE dApp
Вітаю! У статті я покажу, як написати та запустити на ноді Waves звичайний dApp. Розглянемо необхідні інструменти, методи та приклад розробки.
Схема розробки dApps та звичайних додатків майже не відрізняється:
Пишемо код
Пишемо автоматизоване тестування
запускаємо програму
Тестуємо
Інструменти
1. docker для запуску ноди та Waves Explorer
Якщо не бажаєте запускати ноду, можете пропустити цей крок. Адже є тестова та експериментальна мережа. Але без розгортання своєї ноди процес тестування може тривати.
Вам постійно будуть потрібні нові облікові записи з тестовими токенами. Кран тестової мережі переводить по 10 WAVES кожні 10 хвилин.
Середній час блоків у тестовій мережі – 1 хвилина, у ноді – 15 секунд. Це особливо відчутно, коли транзакція потребує кількох підтверджень.
У загальнодоступних тестових нодах можливе агресивне кешування.
Ще вони можуть бути тимчасово недоступні через технічне обслуговування.
Встановіть Surfboard – інструмент, який дозволить запустити випробування на існуючій ноді.
npm install -g @waves/surfboard
3. Плагін Visual Studio Code
Крок необов'язковий, якщо ви не фанат IDE і віддаєте перевагу текстовим редакторам. Усі необхідні інструменти – це утиліти командного рядка. Якщо ви використовуєте vim, зверніть увагу на плагін vim-ride.
Завантажте та встановіть Visual Studio Code: https://code.visualstudio.com/
Відкрийте VS Code та встановіть плагін waves-ride:
Кінцева точка REST API ноди, яка буде використовуватися для запуску dApp та CHAIN_ID мережі.
Секретна фраза для облікового запису з токенами, які будуть джерелами токенів вашого тесту.
Як бачите, surfboard.config.json за промовчанням підтримує декілька середовищ. За замовчуванням виставлено локальне середовище (ключ defaultEnv – параметр, що змінюється).
Додаток Wallet-demo
Ця секція – не довідник мови RIDE. Скоріше, погляд на додаток, які розгортаємо та тестуємо, щоб краще зрозуміти, що відбувається у блокчейні.
Розглянемо простий додаток Wallet-demo. Кожен може надіслати на адресу dApp токени. Вивести можна лише свої WAVES. Дві функції @Callable доступні через InvokeScriptTransaction:
deposit(), яка вимагає прикріпленого платежу у WAVES
withdraw(amount: Int), який повертає токени
Протягом усього життєвого циклу dApp структура (address → amount) буде підтримуватися:
дію
Resulting state
початковий
порожній
Alice deposits 5 WAVES
alice-address → 500000000
Bob deposits 2 WAVES
alice-address → 500000000
bob-address → 200000000
Bob withdraws 7 WAVES
DENIED!
Alice withdraws 4 WAVES
alice-address → 100000000
bob-address → 200000000
Ось код для повного розуміння ситуації:
# In this example multiple accounts can deposit their funds and safely take them back. No one can interfere with this.
# An inner state is maintained as mapping `address=>waves`.
{-# STDLIB_VERSION 3 #-}
{-# CONTENT_TYPE DAPP #-}
{-# SCRIPT_TYPE ACCOUNT #-}
@Callable(i)
func deposit() = {
let pmt = extract(i.payment)
if (isDefined(pmt.assetId))
then throw("works with waves only")
else {
let currentKey = toBase58String(i.caller.bytes)
let currentAmount = match getInteger(this, currentKey) {
case a:Int => a
case _ => 0
}
let newAmount = currentAmount + pmt.amount
WriteSet([DataEntry(currentKey, newAmount)])
}
}
@Callable(i)
func withdraw(amount: Int) = {
let currentKey = toBase58String(i.caller.bytes)
let currentAmount = match getInteger(this, currentKey) {
case a:Int => a
case _ => 0
}
let newAmount = currentAmount - amount
if (amount < 0)
then throw("Can't withdraw negative amount")
else if (newAmount < 0)
then throw("Not enough balance")
else ScriptResult(
WriteSet([DataEntry(currentKey, newAmount)]),
TransferSet([ScriptTransfer(i.caller, amount, unit)])
)
}
@Verifier(tx)
func verify() = false
Плагін VSCode підтримує безперервну компіляцію під час редагування файлу. Тому ви завжди можете стежити за помилками у вкладці PROBLEMS.
Якщо хочете використовувати інший текстовий редактор під час компіляції файлу, використовуйте
surfboard compile ride/wallet.ride
Це виведе ряд base64 скомпільованого коду RIDE.
Тестовий сценарій для 'wallet.ride'
Подивимося на тестовий файл. Працює на фреймворку JavaScript's Mocha. Є функція «Before» та три тести:
"Before" фінансує кілька акаунтів через MassTransfer Transaction, компілює скрипт і розгортає його в блокчейні.
Can deposit відправляє в мережу InvokeScript Transaction, активуючи функцію deposit() для кожного з двох облікових записів.
"Can't withdraw more than was deposited" тестує, що ніхто не зможе вкрасти чужі токени.
Can deposit перевіряє, що висновки обробляються коректно.
Запуск тестів з Surfboard та аналіз результатів у Waves Explorer
Для запуску тесту виконайте
surfboard test
Якщо у вас є кілька сценаріїв (наприклад, потрібен окремий скрипт розгортання), можете запустити
surfboard test my-scenario.js
Surfboard збере тестові файли в папці ./test/ і запустить сценарій у ноді, яка налаштована на surfboard.config.json. Через кілька секунд ви спостерігатимете щось подібне:
wallet test suite
Generating accounts with nonce: ce8d86ee
Account generated: foofoofoofoofoofoofoofoofoofoofoo#ce8d86ee - 3M763WgwDhmry95XzafZedf7WoBf5ixMwhX
Account generated: barbarbarbarbarbarbarbarbarbar#ce8d86ee - 3MAi9KhwnaAk5HSHmYPjLRdpCAnsSFpoY2v
Account generated: wallet#ce8d86ee - 3M5r6XYMZPUsRhxbwYf1ypaTB6MNs2Yo1Gb
Accounts successfully funded
Script has been set
√ Can deposit (4385ms)
√ Cannot withdraw more than was deposited
√ Can withdraw (108ms)
3 passing (15s)
Ура! Тести пройдено. Тепер поглянемо на те, що відбувається при використанні Waves Explorer: переглянемо блоки або вставимо одну із зазначених вище адрес у пошук (наприклад, відповідна wallet#. Там можна знайти історію транзакцій, стан dApp, декомпільований двійковий файл.
Waves Explorer. Додаток, який щойно розгорнули.
Декілька порад з Surfboard:
1. Щоб тестувати у середовищі testnet, використовуйте:
Налаштування Waves Keeper для роботи з локальною нодою
2. Чи імпортуйте секретну фразу з токенами для мережі? Для простоти використовуйте початкове seed вашої ноди: waves private node seed with waves tokens. Адреса: 3M4qwDomRabJKLZxuXhwfqLApQkU592nWxF.