Написание смарт-контрактов на Rust | Привет, Ink!
Автор: Ли Дагоу (Ли Аохуа) / Пост-редактор: Чжан Ханьдун
Что такое смарт-контракт WASM?
В прошлом, когда мы говорили о смарт-контрактах, все они были смарт-контрактами Solidity, основанными на EVM.
В настоящее время с развитием технологии смарт-контрактов появилась новая возможность: смарт-контракт WASM,
WASM — это не новый язык программирования, а новый низкоуровневый двоичный синтаксис.
WASM (WebAssembly) — это новый формат байт-кода и совершенно новый лежащий в его основе двоичный синтаксис.Инструкции кода, которые он компилирует, имеют небольшой размер, переносимы, быстро загружаются и совместимы с новым форматом WEB. WASM может поддерживать C/C++/RUST/GO и другие языки для компиляции контрактов после компиляции кода раздела, а разные языки имеют богатые базовые стандартные библиотеки для вызова.
Преимущества ВАСМ:
Будучи совершенно новым форматом байт-кода, WASM благодаря собственным инновациям и оптимизации делает инструкции кода, написанные на поддерживаемых языках, небольшими по размеру, что может быть улучшено с точки зрения хранения, хранения на жестком диске и использования полосы пропускания. оптимизации экономят сетевые ресурсы блокчейна и значительно повышают эффективность передачи по сети.
Использование WASM в смарт-контрактах также будет иметь вышеуказанные характеристики.Наиболее очевидными аспектами являются то, что он требует меньше ресурсов, быстрее и стабильнее выполняет контракты и более эффективно передает информацию по сети. Это может позволить развернуть больше смарт-контрактов в сети блокчейн, а также может предоставить пользователям лучший опыт при использовании смарт-контрактов.
——Анализ преимуществ смарт-контракта WASM:zhuanlan.zhihu.com/p/344347968
Судя по текущей тенденции, публичные сети, такие как Substrate и ETH 2.0, а также ряд сетей альянсов указали, что они будут поддерживать смарт-контракты WASM.
На каких языках можно писать смарт-контракты WASM?
Wasm расширяет семейство языков, доступных разработчикам смарт-контрактов, включая Rust, C/C++, C#, Typescript, Haxe и Kotlin. Это означает, что вы можете писать смарт-контракты на любом языке, с которым вы знакомы.
С точки зрения адаптивности язык Rust в настоящее время лучше адаптируется к смарт-контрактам WASM, цепочка инструментов более полная, а написанные смарт-контракты более безопасны.
Итак, в этой серии в качестве примера будет взят смарт-контракт Ink! на Subtrate, чтобы начать курс 101 по смарт-контрактам WASM.
В этой статье есть ссылка на официальное руководство по Ink!:
Конфигурация среды Rust
1. Конфигурация окружения Rust
В операционных системах Linux, таких как MacOS или Ubuntu, мы можем легко установить Rust с помощью одной строки команды:
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
Кроме того, установитеnightly
Версия:
rustup install nightly
Для установки под Windows см.:
https://forge.rust-lang.org/infra/other-installation-methods.html
2. Добавьте Rust в среду
Добавьте следующее утверждение в~/.bashrc
или~/.zshrc
середина:
export PATH=~/.cargo/bin:$PATH
Потом:
source ~/.bashrc # source ~/.zshrc
3. Измените источник
Мы переключаем исходный код Rust на внутренний, установив следующие переменные среды:
export RUSTUP_DIST_SERVER=https://mirrors.ustc.edu.cn/rust-static
export RUSTUP_UPDATE_ROOT=https://mirrors.ustc.edu.cn/rust-static/rustup
существует~/.cargo/config
Запишите в файл следующее содержимое:
[source.crates-io]
registry = "https://github.com/rust-lang/crates.io-index"
replace-with = 'ustc'
[source.ustc]
registry = "git://mirrors.ustc.edu.cn/crates.io-index"
Конфигурация среды Ink!
После настройки базовой среды Rust мы можем настроить среду разработки, необходимую для Ink!.
# for substrate
rustup component add rust-src --toolchain nightly
rustup target add wasm32-unknown-unknown --toolchain stable
# for canvas node
cargo install canvas-node --git https://github.com/paritytech/canvas-node.git --tag v0.1.4 --force --locked
# for ink!CLI
cargo install cargo-contract --vers 0.10.0 --force --locked
Мы также должны установить/обновитьbinaryen
, Binaryen — это компилятор для WebAssembly.
Установить на Mac:
# for mac
brew upgrade binaryen # 如果没安装用 brew install
Установить в Linux:
Создать проект ink!
Выполните следующую команду:
cargo contract new flipper
После завершения создания заходим в папку:
cd flipper/
Структура каталога проекта контракта:
flipper
|
+-- lib.rs <-- Contract Source Code
|
+-- Cargo.toml <-- Rust Dependencies and ink! Configuration
|
+-- .gitignore
контрактный тест
cargo +nightly test
Если все пойдет хорошо, будет выведен следующий вывод:
$ cargo +nightly test
running 2 tests
test flipper::tests::it_works ... ok
test flipper::tests::default_works ... ok
test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
составление контракта
cargo +nightly contract build
Если все пойдет хорошо, каталог сгенерируетtarget/ink
папку, в которой находятся следующие файлы:
в,flipper.contract
файл контракта, который будет использоваться во время развертывания, который можно рассматривать какsolidity
в контрактеbin
документ.
metadata.json
является метаданными и может рассматриваться какsolidity
в контрактеabi
документ.
Развертывание контракта
пройти черезcanvas
Запустите локальную работающую ноду разработки!
canvas --dev --tmp
Откройте следующий URL-адрес, и эта страница автоматически подключится к локально запущенному узлу разработки:
загрузитьflipper.contract
этот файл:
Щелкните полностью, чтобы развернуть:
вызов по контракту
нажмитеExecute
:
выберитеget():bool
функцию, нажмите «Позвонить»:
Вернуть результат вызова:
Интерпретация исходного кода Flipper
// Copyright 2018-2020 Parity Technologies (UK) Ltd.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#![cfg_attr(not(feature = "std"), no_std)]
use ink_lang as ink;
#[ink::contract]
pub mod flipper {
#[ink(storage)]
pub struct Flipper {
value: bool,
}
impl Flipper {
/// Creates a new flipper smart contract initialized with the given value.
#[ink(constructor)]
pub fn new(init_value: bool) -> Self {
Self { value: init_value }
}
/// Creates a new flipper smart contract initialized to `false`.
#[ink(constructor)]
pub fn default() -> Self {
Self::new(Default::default())
}
/// Flips the current value of the Flipper's bool.
#[ink(message)]
pub fn flip(&mut self) {
self.value = !self.value;
}
/// Returns the current value of the Flipper's bool.
#[ink(message)]
pub fn get(&self) -> bool {
self.value
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn default_works() {
let flipper = Flipper::default();
assert_eq!(flipper.get(), false);
}
#[test]
fn it_works() {
let mut flipper = Flipper::new(false);
assert_eq!(flipper.get(), false);
flipper.flip();
assert_eq!(flipper.get(), true);
}
}
}
1. cfg
иcfg_attr
использование
cfg
— это специальное свойство в Rust, которое позволяет нам компилировать код на основе флагов и передавать его компилятору.
В этом договоре мы видим:
#[cfg(test)]
Этот флаг означает, что приведенный ниже код является модульным тестом.
2. реализовать ключевое слово
Implement some functionality for a type.
Делайте реализации функций для типа.
Стандартный шаблон:
struct Example {
number: i32,
# 许多变量……
}
impl Example {
fn boo() {
println!("boo! Example::boo() was called!");
}
fn answer(&mut self) {
self.number += 42;
}
# 许多函数……
}
Примените к этому контракту, сначала мы определяем контрактstruct
:
pub struct Flipper {
value: bool, # 其中包含一个变量 value
}
тогда правильноstruct
Сделайте дополнительную реализацию:
impl Flipper {
……
}
3. #[ink(constructor)]
и#[ink(message)]
#[ink(constructor)]
Указывает, что эта строка функции оператора является конструктором контракта, который эквивалентенsolidity
в контрактеconstructor
.
#[ink(message)]
Указывает, что функция под этой строкой утверждения является нормальной функцией контракта, например, в примереget
функция:
/// Returns the current value of the Flipper's bool.
#[ink(message)]
pub fn get(&self) -> bool {
self.value
}
Об авторе:
Ли Дагоу (Li Aohua), заместитель директора Центра исследований технологий и приложений блокчейна Шанхайского университета международного бизнеса и экономики, технический директор Bailian Education, FISCO BCOS (WeBank Blockchain Framework), сертифицированный лектор по блокчейну, 5-летний инженер по блокчейну, Пекинский университет Владелец. Области исследований включают: системы блокчейна, механизмы консенсуса, смарт-контракты, приложения блокчейна, цифровую идентификацию и т. д.