Технология Ontology Wasm снижает стоимость переноса смарт контрактов dApp со сложной бизнес- логикой на блокчейн, тем самым значительно обогащая dApp экосистему.
В настоящее время Ontology Wasm одновременно поддерживает разработку как на языке Rust, так и на языке C++. Язык Rust лучше поддерживает Wasm, а сгенерированный байт-код проще, что может еще больше снизить стоимость контрактных вызовов. Итак, как использовать Rust для разработки контракта в сети Ontology?
Разработка WASM — контракта с помощью Rust
Создание контракта
Cargo — это хороший инструмент создания проектов и управления пакетами при разработке программ на Rust, который помогает разработчикам лучше организовывать взаимодействие кода и сторонних библиотек. Чтобы создать новый Ontology Wasm- контракт, просто выполните следующую команду:
Структура проекта, которую она генерирует:
Файл Cargo.toml используется для настройки базовой информации проекта и информации зависимой библиотеки. Секция [lib] в файле обязана быть установленной в значение crate-type = [“cdylib”]. Файл lib.rs используется для написания кода логики контракта. В добавок, Вам необходимо добавить параметры зависимостей в раздел [dependencies] файла конфигурации Cargo.toml:
С помощью этой зависимости разработчики могут вызывать интерфейсы, которые взаимодействуют с блокчейном Ontology, и инструменты такие, как параметр сериализации.
Функция ввода контракта
Каждая программа имеет функцию ввода, как например main- функция, которую мы обычно видим, но у контракта нет main- функции. Когда разрабатывается Wasm- контракт с использованием Rust, то функция invoke по умолчанию используется как функция ввода для использования контракта. Имя функции в Rust будет неясным при компиляции исходного кода Rust в байт- код, который может выполнять виртуальная машина. Чтобы предупредить компилятор от генерирования избыточного кода и сократить размер контракта, функция invoke добавляет аннотацию #[no_mangle].
Как функция invoke получает параметры для выполнения транзакции?
Библиотека ontio_std предоставляет функцию runtime :: input (), чтобы получить параметры для выполнения транзакции. Разработчики могут использовать ZeroCopySource для десериализации полученного массива байтов. В котором первый считанный массив байтов— это имя invoke- метода, далее параметры метода.
Как возвращается результат выполнения контракта?
Функция runtime::ret, которая предоставляется библиотекой ontio_std, возвращает результат выполнения метода.
Законченная invoke- функция выглядит следующим образом:
Сериализация и десериализация данных контракта
В процессе разработки контрактов разработчики всегда наталкиваются на проблемы сериализации и десериализации, а конкретно с тем, как сохранить struct- тип данных в базу данных и как массив байтов, считанный из базы данных, десериализовать, чтобы получить struct- тип данных.
Библиотека ontio_std предоставляет интерфейсы декодера и кодера для сериализации и десериализации данных. Поля структуры struct также реализуют интерфейсы декодера и кодера, так что структура может быть сериализована и десериализована. Экземпляры класса Sink необходимы, когда сериализуются различные типы данных. Экземпляр класса Sink имеет set- тип поле buf, которое хранит байт тип данные, а все сериализованные данные хранятся в buf.
Для данных с фиксированной длиной (к примеру: byte, u16, u32, u64 и т.д.) данные непосредственно преобразуются в массив байтов и затем сохраняются в buf; для данных нефиксированной длины сначала нужно сериализовать длину, а затем D\data (например целые числа без знака неизвестного размера, включая u16, u32 или u64 и т. д.).
Десериализация является прямой противоположностью. Для каждого метода сериализации есть соответствующий метод десериализации. Десериализация требует использования экземпляров класса Source. Этот экземпляр класса имеет два поля buf и pos. Buf используется для хранения данных, которые будут десериализованы, а pos используется, чтобы хранить текущую позицию считывания. Когда считывается конкретный тип данных, если вы знаете их длину, вы можете считывать их напрямую, для данных неизвестной длины— сначала считайте длину, а затем считайте содержимое.
Доступ и обновление данных в цепочке
Ontology-wasm-cdt-rust — инкапсулировал операционный метод работы с данными в цепи, который удобен для разработчиков, чтобы реализовывать операции такие, как добавление, удаление, изменение и запрашивание данных в цепи следующим образом:
- database::get(key) — используется, чтобы запросить данные из цепи, а key запрашивает реализацию интерфейса AsRef;
- database::put(key, value) — используется, чтобы хранить данные в сети. Key запрашивает выполнение интерфейса AsRef, а value запрашивает реализацию интерфейса Encoder;
- database::delete(key) — используется, чтобы удалить данные из цепочки, а key запрашивает реализацию интерфейса AsRef.
Тестирование контракта
Когда реализуются методы контракта нам нужен доступ к данным в цепи и нам нужна соответствующая виртуальная машина, чтобы выполнить байткод контракта, поэтому как правило необходимо развернуть контракт в цепи для тестирования. Но такой метод тестирования проблематичен. Чтобы сделать легче для разработчиков тестирование контрактов, библиотека ontio_std предоставляет mock- модуль для тестирования. Данный модуль обеспечивает симуляцию данных в цепи, делая легче для разработчиков юнит- тестирование методов в контракте. Конкретные примеры могут быть найдены здесь.
Отладка контракта
console::debug(msg) выводит отладочную информацию во время отладки контракта. Информация msg будет внесена в лог- файл ноды. Обязательным условием является установка уровня лог- файла в режим отладки, когда запущена локальная тест- нода Ontology.
runtime::notify(msg) выводит соответствующую отладочную информацию во время отладки контракта. Этот метод будет сохранять внесенную информацию в цепь и может быть запрошен из цепи с помощью метода getSmartCodeEvent.
Статья была переведена редакцией Hashrate&Shares специально для OntologyRussia. клик
Вы разработчик? Присоединяйтесь к нашему техническому сообществу на Discord. Кроме того, загляните в Центр разработчиков на нашем сайте, там вы можете найти инструменты разработчика, документацию и многое другое.