В отличии от блокчейн платформ, где необходимо публиковать смарт-контакт стандарта ERC-20
для создания нового токена, в сети WE имеется нативная возможность выпуска токенов при помощи транзакции выпуска токена.
После выпуска (когда транзакция выпуска токена будет принята сетью), выпущенным токеном можно свободно распоряжаться: совершать переводы, массовые трансферы другим участникам сети.
Кроме того, выпускаемые токены могут быть довыпущены после создания, если такой параметр (reissuable = true
) был установлен при выпуске, и даже сожжены, что не возможно делать с системным токеном WEST.
Также выпущенный токен может быть спонсирован при помощи обеспечения системным токеном, что позволяет платить комиссии за транзакции в сети, например, в маркетинговых целях для привлечения новых пользователей.
Note: Токены, выпущенные смарт-контрактом, пока не имеют такой функциональности.
Смарт-контракты WE - это отдельные приложения, общающиеся с блокчейн нодой по gRPC API, запускаемые по требованию в docker-контейнерах.
Контракты могут быть написаны на любом языке программирования, для которого существует gRPC клиент и поддержка Protobuf. Однако для упрощения разработки рекомендуется использовать Smart-Contract SDK, который реализует слой интеграции с блокчейн-нодой, предоставляя разработчику возможность описывать только бизнес-логику.
Подробно про низкоуровневую реализацию смарт-контрактов в платформе WE можно прочитать в нашей статье на Хабре.
Важно помнить, что:
- смарт-контракт должен быть детерминированным. А именно возвращать один и тот же результат, будучи запущенным на фиксированном состоянии с одинаковыми параметрами вызова. В противном случае результаты исполнения смарт-контракта будут отличаться у разных нод, что не позволит ему пройти валидацию;
- образ смарт-контракта должен быть легковесным, т.к. каждой ноде придётся его скачивать из Docker Registry для исполнения;
- до публикации транзакции создания контракта в блокчейне, Docker-образ смарт-контракта должен быть загружен в доступный для нод источник
- процессы скачивания и развёртывания Docker-образа смарт-контракта выполняются нодой автоматически;
- для публикации смарт-контракта в блокчейне требуется роль
contract-developer
При вызове смарт-контракт может получать входные параметры и платежи из транзакции вызова. При исполнении контракт может обращаться к ноде для чтения своего состояния.
По результатам исполнения своей логики смарт-контракт должен вернуть ноде ответ об успешной или не успешной операции. Если же смарт-контракт "упадёт" или не ответит по иным причинам, то сработает timeout и вызов будет считаться неуспешным.
Состояние смарт-контрактов хранится в виде пар "ключ-значение". Поддерживаемые типы данных для значений:
- Integer
- Boolean
- String
- Binary
Запись данных осуществляется в результате исполнения кода контракта, то есть записать что-то в состояние смарт-контракта без вызова нельзя.
Транзакциями вызова являются CreateContractTransaction и CallContractTransaction. Как ранее говорилось, при вызове смарт-контракту можно передать параметры и платежи. Это делается при помощи полей params
и payments
соответственно.
Note: транзакция типа
CreateContractTransaction
используется для публикации контракта в сети и может быть отправлена один раз на один смарт-контракт
После успешного исполнения, транзакция вызова оборачивается в транзакцию исполненного контракта, которая помимо электронной подписи майнера и доказательств от валидаторов содержит также поле results
, в котором могут быть пары "ключ-значение", записываемые в состояние смарт-контракта. Помимо этого существует поле assetOperations
, в которое смарт-контракт может записать операции с токенами.
При вызове смарт-контракта при помощи поля payments
ему можно передать любые токены, включая системные WEST, которых должно быть в достаточном количестве на балансе у отправителя.
По результатам выполнения смарт-контракт может сделать ряд операций над токенами, которые имеются у него на балансе, а именно:
- выпуск нового токена
- перевод токена пользователю (на блокчейн адрес)
- довыпуск токена
- сжигание токена, имеющегося на балансе (кроме системного токена WEST)
Note: довыпустить можно только тот токен, который был выпущен данным смарт-контрактом
Следует ещё раз обратить внимание, что пополнение баланса контракта учитывается при исполнении кода смарт-контракта сразу, то есть контракт, получая активы на свой баланс в транзакции вызова, может оперировать ими сразу.
Важные тезисы:
- идентификатор смарт-контракту присваивается при создании, т.е. при отправке транзакции
CreateContractTransaction
. Идентификатор называетсяcontractId
и он соответствует идентификатору (id
) транзакции создания; - каждый смарт-контракт с уникальным
contractId
имеет своё состояние; - для одного Docker-образа можно создавать неограниченное количество смарт-контрактов со своими состояниями и идентификаторами.
В общем случае алгоритм состоит из базовых шагов:
- Собрать docker-образ смарт-контракта
- Добавить docker-образ в доступный для нод Docker Registry (hub.docker.com)
- Отправить от имени адреса с ролью contract-developer подписанную транзакцию CreateContractTransaction
Можно воспользоваться следующей командой:
docker inspect --format='{{.Id}}' YOUR_IMAGE_NAME:IMAGE_VERSION | awk '{print \"ImageHash: \" substr($0,8)}'
где
YOUR_IMAGE_NAME:IMAGE_VERSION
— название и версия собранного Docker-образа с контрактом.
- После подписания и отправки в сеть транзакции смарт-контракта попадают в UTX пул нод, проверять так.
- После отправки транзакции создания или вызова смарт-контракта статус исполнения можно посмотреть используя данный API метод.
- После подписания и отправки в сеть транзакции вызова смарт-контракта успешный результат выполнения можно посмотреть, найдя соответствующую ExecutedContract транзакцию в API ноды так.
- Посмотреть значения данных на стэйте смарт-контракта можно так.
Шаблон для быстрого бутстрапирования (node SDK:
npm create web3tech-scnt-hackathon-bootstrap@latest
)Базовый пример с использованием шаблона из предыдущего пункта (Примеры с отдельными операциями для нативных токенов на смарт-контракте)