Свои токены: выпуск, перевод, сжигание
Зачем это нужно
В Ethereum свой токен — это контракт. Надо написать код, реализовать стандарт ERC-20 по букве, развернуть, проверить. Мы этим занимались четыре главы, и там было чего бояться: одна ошибка в transferFrom — и токен ломается.
В Waves токен — это транзакция. Одна, типа 3. Кода нет вовсе: перевод, учёт балансов, сжигание встроены в саму сеть и работают одинаково для любого токена. Ошибиться в них невозможно, потому что писать их не надо.
Эта глава — про то, что задают при выпуске, что после этого уже не поменять, и кто какие права получает. Все ответы узла — с локального узла Waves 1.6.4.
Выпускаем токен
const { issue } = require('@waves/waves-transactions');
const tx = issue({
name: 'PGKPoint',
description: 'Ball za praktiku',
quantity: 100000,
decimals: 2,
reissuable: true,
chainId: 'R',
}, seed);
тип: 3 | комиссия: 100000000 | id актива: 3fyDK2DaHYR9idYmbgwjJQ33r7t6zQTCQQTcQMQugAUm
в блоке: 26
Сведения об активе доступны сразу:
{"assetId":"3fyDK2Da…","issueHeight":26,"issuer":"3M5HPFG1r9q79uxff6rm1Z3UFZcXXXHX32p",
"name":"PGKPoint","description":"Ball za praktiku","decimals":2,"reissuable":true,
"quantity":100000,"scripted":false,"minSponsoredAssetFee":null}
Идентификатор актива — это идентификатор транзакции выпуска. Отдельного адреса, как у контракта в Ethereum, у токена нет. Поэтому и «взломать токен» в Waves не получится: у него нет кода, который можно сломать.
Знаки после запятой
Проверим границу:
decimals: 9 → код 400
invalid decimals value: 9, decimals should be in interval [0; 8]
Число знаков задают один раз и не меняют никогда. Ошиблись — выпускайте новый токен: старый так и останется с неправильной запятой.
Ноль знаков — законный и часто правильный выбор. Билеты, места, голоса, экземпляры — всё, что не делится, выпускают с decimals: 0. Тогда quantity: 100 означает ровно сто штук, и никакой арифметики с запятой в приложении не будет.
Переводим и проверяем баланс
Перевод токена — та же транзакция типа 4, что и перевод WAVES, только с полем assetId:
const tx = transfer({ amount: 25000, assetId: '3fyDK2Da…', recipient: b, chainId: 'R' }, seed);
в блоке: 26 | комиссия платится в WAVES: 100000
баланс держателя: {"assetId":"3fyDK2Da…","balance":25000}
25000 при двух знаках — это 250,00 балла. А комиссия — 0,001 WAVES, не токена.
Аккаунт, на котором лежат токены, но нет WAVES, не может их перевести. Это первое, обо что спотыкаются в приложениях: пользователю прислали токен, а он не может им распорядиться. Лечится либо выдачей небольшой суммы WAVES, либо спонсированием комиссии — механизмом, при котором за перевод платит выпустивший.
Кто что может
Допвыпуск чужого токена отвергается:
код: 400
{"error":112,"message":"State check failed. Reason: Asset was issued by other address"}
Допвыпуск неперевыпускаемого токена — даже самим выпустившим:
код: 400
{"error":112,"message":"State check failed. Reason: Asset is not reissuable"}
Это и есть способ раз и навсегда пообещать держателям, что токенов больше не станет: выпустить с reissuable: false либо позже закрыть допечатку транзакцией допвыпуска с этим флагом.
Сжигание доступно любому держателю — но только со своего счёта:
const tx = burn({ assetId, amount: 10000, chainId: 'R' }, seedДержателя);
в блоке: 27 | комиссия: 100000
остаток у держателя: 15000
общее количество: 90000
Обратите внимание: общее число токенов уменьшилось — со 100 000 до 90 000. Сожжённые токены исчезают из обращения насовсем.
Отобрать чужие токены нельзя никаким способом: ни выпустивший, ни владелец узла не могут списать их с чужого счёта. Если в задании нужен «отзыв», его реализуют иначе — например, токен выдают на смарт-аккаунт, который умеет вернуть его по запросу.
Что всё-таки можно поменять
Имя и описание меняются отдельной транзакцией — тип 17:
const tx = updateAssetInfo({ assetId, name: 'PGKPoint', description: 'Novoe opisanie', chainId: 'R' }, seed);
тип: 17 | код: 200 | принято
В основной сети между такими обновлениями есть обязательный промежуток — сто тысяч блоков, около двух месяцев. На локальном узле его нет, поэтому в опытах команда проходит сразу. Не удивляйтесь, если в тестовой сети она откажет с жалобой на интервал.
Типичные ошибки
Ошибка 1. Имя короче четырёх знаков.
tx "name", has wrong data: "ABC". Check tx data.
Библиотека ловит это ещё до отправки. Границы — от 4 до 16 знаков.
Ошибка 2. Описание длиннее тысячи знаков.
Тоже ловится библиотекой. Тысяча — потолок.
Ошибка 3. Путать quantity и «сколько штук».
quantity: 100000, decimals: 2 // это 1000,00, а не сто тысяч
Считать надо в «копейках», как и везде в сети.
Ошибка 4. Рассчитывать на отзыв токенов.
Отобрать выданное нельзя. Если задание требует отзыв, продумывать схему надо до выпуска, а не после.
Ошибка 5. Выпускать токен на каждый чих.
Выпуск стоит 1 WAVES. Там, где нужен просто счётчик или статус, хватит записи в состояние аккаунта — она в тысячу раз дешевле.
Шпаргалка по главе
| Что нужно | Как |
|---|---|
| Выпустить | issue({ name, description, quantity, decimals, reissuable, chainId }, seed) |
| Перевести | transfer({ amount, assetId, recipient, chainId }, seed) |
| Допечатать | reissue({ assetId, quantity, reissuable, chainId }, seed) |
| Сжечь | burn({ assetId, amount, chainId }, seed) |
| Сменить описание | updateAssetInfo({ assetId, name, description, chainId }, seed) |
| Сведения об активе | GET /assets/details/<id> |
| Баланс токена | GET /assets/balance/<адрес>/<id> |
| Все токены адреса | GET /assets/balance/<адрес> |
Словарь главы
| Термин | Что это |
|---|---|
| Актив | Токен; идентифицируется идентификатором транзакции выпуска |
decimals | Число знаков после запятой, 0–8; задаётся навсегда |
reissuable | Разрешение допечатать; закрывается навсегда, обратно не открывается |
| Допвыпуск | Транзакция типа 5; доступна только выпустившему |
| Сжигание | Транзакция типа 6; доступна любому держателю со своего счёта |
| Спонсирование | Механизм, при котором комиссию за перевод платит выпустивший |
scripted | Признак «на токен навешен скрипт» — отдельная возможность |
Цель: скорость ≥ 95 зн/мин, точность ≥ 88%
const { issue, burn, reissue } = require('@waves/waves-transactions');
Что должен уметь после главы
- выпустить токен и объяснить каждое поле выпуска;
- назвать границы имени, описания и числа знаков;
- объяснить, откуда берётся идентификатор актива;
- перевести токен и объяснить, в чём платится комиссия;
- сказать, кто может допечатать и кто может сжечь;
- объяснить, почему отобрать выданные токены нельзя;
- решить, когда токен не нужен и хватит записи в состояние.
Проверка по главе
Сводная проверка по всей главе: 10 вопросов, 5:00 на всё, без подсказок по ходу. Вопросы показываются по одному, ответ изменить нельзя. Если время выйдет — экзамен завершится с тем, что успел ответить. Пересдавать можно сколько угодно раз.
Куда дальше: проверенные ресурсы
- Токены Waves — типы, поля, возможности.
- Транзакция выпуска — все ограничения полей.
- Спонсирование комиссий — как платить за пользователя.
- Смарт-активы — когда токену всё-таки нужен код.
Комментарии
Обсуждение живёт в GitHub Discussions и грузится с чужого домена — поэтому только по нажатию.