Смарт-контракты на платформе Semux. Quick Start Guide

Savel
SEMUX на русском
8 min readAug 22, 2019

Semux — это экспериментальная блокчейн-платформа с открытым исходным кодом, написанная на JAVA. Ее фундаментальным активом является нативная криптовалюта, имеющая обозначение SEM. Проект запущен в 2017 году, а основная сеть работает в продакшене с января 2018 года.

Безопасность и окончательность транзакций обеспечивается консенсуным механизмом Semux BFT, в основе которого работа 100 избираемых валидаторов, генерирующих новые блоки каждые 30 сек.

Начиная с версии протокола Semux v.1.5.0 в ядре платформы реализована виртуальная машина, использующая формат Ethereum VM совместимый с языком Solidity и позволяющая создавать программную логику в блокчейне. Для выполнения смарт-контрактов используется механизм газа, схожий с тем, как это работает в Etherium. При этом лимит газа в блоке ограничен 30 млн, что обеспечивает производительность блокчейна на уровне 200 TPS. Виртуальная машина Semux поддерживает все конструкции “византийского” Эфириума, а также два новых метода, специфичных для платформы Semux — Vote и Unvote.

Данное руководство предназначено для тех, кто хочет научиться создавать смарт-контракты на блокчейн-платформе Semux. Предполагается что вы уже знакомы с понятиями блокчейна и криптовалют и имеете представление о языке Solidity. Данное руководство также будет полезно, если вы уже имеете опыт написания смарт-контрактов на базе Etherium и поможет вам быстрее разобраться в тонкостях их создания и использования в Semux.

Для написания смарт-контрактов мы будет использовать язык Solidity версии 0.4.26. Писать и тестировать мы будем в среде Remix IDE. Для запуска контрактов мы будем использовать клиент Semux v.2.0.0-RC3, работающий в сети тестнет.

Часть 1. Запуск клиента Semux в сети testnet

Для своей работы мы будем использовать актуальную на момент написания статьи версию клиента Semux v.2.0.0-RC3, скачать которую можно отсюда. Внимание! Перед скачиванием рекомендуется проверить наличие более новой версии.

Клиент работает только в х64 операционных системах. Под Windows может потребоваться установка пакета Microsoft Visual C++ 2012 Redistributable Package (x64).

Установите окружение и распакуйте архив с клиентом в отдельную папку. Для подключения к сети тестнет требуется запустить клиент с параметром:

./semux-gui.sh --network testnet

Если вы работаете в среде Windows, то удобнее производить запуск через ярлык, в свойствах которого необходимо прописать:

semux.jar --network testnet

После запуска клиента указываем пароль для входа в аккаунт или создаем новый аккаунт. Затем необходимо дождаться полной синхронизации. Это может занять несколько минут, т.к. клиент запускает ноду, скачивая копию всего блокчейна тестнета.

Далее переходим на сайт https://www.semux.org/testnetfaucet, вводим адрес своего аккаунта и через пару минут получаем тестовые монеты. Убедитесь, что транзакция с вашим адресом отобразилась в блок-эксплорере http://testnet.semux.info/.

Часть 2. Наш первый смарт-контракт “HelloWorld”

Теперь мы напишем самый простой смарт-контракт на языке Solidity, скомпилируем его в байт-код, а затем развернём в блокчейне тестнета Semux и проверим его работу.

Традиционно, наш первый смарт-контракт выводит приветствие «Hello, world!». Для работы нам понадобятся:

  1. клиент Semux, запущенный в тестнете
  2. любой текстовый редактор, например Notepad++
  3. любой hex-декодер, можно онлайновый, например, http://crypt-online.ru/crypts/text2hex/

Для написания и тестирования смарт-контрактов мы будем использовать онлайновый редактор Remix.

Примечание: Remix — это онлайн IDE для Solidity со встроенным отладчиком и средой тестирования.

Сначала настроим компилятор, выбрав язык Solidity, версию компилятора 0.4.26+commit.4563c3fc и “византийскую” версию EVM:

Затем создадим новый файл hello.sol, перейдем в редактор и напишем код контракта:

pragma solidity ^0.4.26;
contract HelloWorld {
function getData() public pure returns (string) {
return "Hello, world!";
}
}

Теперь нам нужно скомпилировать контракт и получить байткод. Для этого выполним следующие действия:

  1. Переходим на вкладку Solidity Compiler и нажимаем Compile Hello.sol.
  2. Если все прошло успешно и контракт был скомпилирован, то нажимаем на кнопку Bytecode, чтобы скопировать его в буфер обмена.
  3. Вставим содержимое буфера обмена в текстовый редактор.

В результате мы получаем объект со следующей структурой:

{
"linkReferences": {},
"object": "608060405234801561001057600080fd5b50610…0029",
"opcodes": "PUSH1 0x80 PUSH1 0x40 MSTORE … STOP 0x29 ",
"sourceMap":
"25:119:0:-;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;25:119:0;;;;;;;"
}

Здесь нас интересует только значение поля object, начинающееся на 608… — это и есть наш байт-код.

Деплой контракта

Теперь мы можем опубликовать наш смарт-контракт в тестовой сети платформы Semux. Запускаем наш клиент (если он еще не был запущен) через ярлык для работы в тестнете и синхронизируемся с сетью.

Переходим на вкладку Contract (Умный контракт) и выбираем тип Deploy a contract (Развернуть контракт) и вставляем в поле Data (Hex) наш байткод:

Также необходимо установить значение лимита газа Gas, на достаточном уровне. Установленного по умолчанию лимита Gas = 21 000 будет недостаточно. Мы установим значение Gas = 200 000.

Нажимаем кнопку отправить и подтверждаем отправление:

Затем в клиенте Semux переходим на вкладку Транзакции и ждем подтверждения сетью (около 30 сек). После подтверждения нашей транзакции (статус принял значение Подтверждено), кликаем по ней, чтобы увидеть детали. В открывшемся окне нажимаем кнопку Show result (Результат транзакции) и если всё прошло успешно, то видим адрес нашего контракта:

Если адрес оказался контракта пуст, то значит вам не удалось опубликовать контракт. Причина может быть связана либо с ошибкой в байт-коде (например, байт-код получен неподдерживаемой версией компилятора), либо c недостатком газа — тогда необходимо увеличить лимит газа Gas и повторить попытку опубликовать контракт в новой транзакции.

Вызов контракта

Возвращаемся обратно в онлайновый редактор Remix и выполняем следующие действия:

  1. Переходим на вкладку Deploy and run transactions. В поле «Environment» выбираем «JavaScript VM» — это тестовая среда в которой мы будем исполнять наши контракты
  2. Выбираем наш контракт HelloWorld и нажимаем кнопку Deploy. Таким образом мы публикуем наш контракт локально и можем его протестировать.
  3. Нажимаем кнопку getData, затем переходим в консоль и нажимаем стрелочку рядом с кнопкой Debug. В раскрывшемся листе нас интересует поле Input, содержащее данные ABI для вызова функции getData.

Нажмите на иконку рядом с полем Input, чтобы скопировать его значение в буфер обмена — оно нам понадобится для вызова функции getData нашего контракта, опубликованного в блокчейне тестовой сети Semux.

Теперь у нас есть все необходимые данные для вызова нашего контракта на платформе Semux. Открываем клиент Semux, переключаемся на вкладку Contract (Умный контракт), выбираем тип Call a contract (Вызов контракта), указываем адрес нашего контракта, а в поле Data (Данные) вставляем значение для вызова функции getData:

Также необходимо установить значение лимита газа Gas, на достаточном уровне. Установленного по умолчанию лимита Gas = 21 000 будет недостаточно. Мы установим значение Gas = 25 000.

Нажимаем кнопку отправить и подтверждаем отправление. Затем переходим на вкладку Транзакции и ждем подтверждения сетью (около 30 сек). После подтверждения нашей транзакции, кликаем по ней, чтобы увидеть детали. В открывшемся окне нажимаем кнопку Show result (Результат транзакции) и если всё прошло успешно, то в поле Return Data (Возврат данных) мы можем увидеть HEX-строку, декодировав которую мы получим сообщение “Hello, world!”:

Для расшифровки, скопируем всё сообщение или его часть 0d48656c6c6f2c20776f726c6421 в любой hex-декодер (например, http://crypt-online.ru/crypts/text2hex/) и дешифруем:

Часть 3. Примеры работы с клиентом Semux

Вызовы из консоли

Чтобы попасть в консоль клиента Semux, в верхнем меню выберите Помощь > Консоль. Попав в консоль, выполните команду help для отображения списка с описанием всех команд.

Для создания контракта нас интересует команда create:

Create a contract
create <from> <data> <gas> <gasPrice> <value> <nonce>

Параметры:
from — адрес владельца контракта. Это тот адрес, с которого вы отправите транзакцию в сеть Semux для создания контракта

data — байт-код контракта. Мы уже знаем байт-код нашего контракта, но для валидности в начало байт-кода необходимо добавить 0x, чтобы в результате получилась строка вида “0x608…”

value — количество передаваемых монет SEM (1 000 000 000 = 1 SEM). В нашем случае 0, т.к. Мы не передаем монеты.

gas — лимит газа. Мы уже убедились, что для создания нашего контракта расходуется 136427, поэтому должны указать лимит не менее этого значения.

gasPrice — стоимость газа. В настоящий момент сети Semux установлена минимальная цена газа на уровне 100

nonce — порядковый номер текущей транзакции для вашего sem-адреса.

Для определения параметра nonce необходимо выполнить в консоли команду:

getAccount <ваш sem-адрес>

Например, для моего адреса 0xf41d18e1d7f2864c8995ace3fa6867d13a9eef81 параметр nonce = 20:

Теперь у нас есть все необходимые данные для создания контракта, и я могу отправить в консоль команду, чтобы опубликовать свой контракт HelloWorld:

create 0xf41d18e1d7f2864c8995ace3fa6867d13a9eef81 0x608060405234801561001057600080fd5b5061013f806100206000396000f300608060405260043610610041576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680633bc5de3014610046575b600080fd5b34801561005257600080fd5b5061005b6100d6565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561009b578082015181840152602081019050610080565b50505050905090810190601f1680156100c85780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b60606040805190810160405280600d81526020017f48656c6c6f2c20776f726c6421000000000000000000000000000000000000008152509050905600a165627a7a7230582078bb2dd601dae1158d11572564791b1abc15ff9b2db82c52ec0ca6445ec309c50029 200000 100 0 20

Сразу после отправки команды, я получил ответ из консоли:

{
“success” : true,
“message” : “successful operation”,
“result” : “0xfd34709f6800f800c922bd875a1723e670b4d5189fee017ba4ee10e83a39739d”
}

где в поле result указан хеш транзакции. После подтверждения (около 30 сек), детали этой транзакции доступны в блок-эксплорере https://testnet.semux.info/explorer/transaction/0xfd34709f6800f800c922bd875a1723e670b4d5189fee017ba4ee10e83a39739d

Теперь вы можете вызвать мой контракт из консоли своего клиента Semux запущенного в тестнете, используя команду call:

Call a contract.
call <from> <to> <gas> <gasPrice> <value> <nonce> <data>

Пример вызова:

call <ваш sem-адрес> 0xd8f87ab60141d21323e9d675a35c5aac055e6490 25000 100 0 <ваш nonce> 0x3bc5de30

Вызовы из командной строки

Для общения с клиентом Semux необходимо произвести настройки API в файле конфигурации config/semux.properties:

#================
# API
#================
# If you enable API, please protect the API password below. Once authenticated,
# clients will gain full access to your wallet.
api.enabled = true
# Listening address and port
api.listenIp = 127.0.0.1
api.listenPort = 5171
# Basic authentication
api.username = YOUR_API_USERNAME
api.password = YOUR_API_PASSWORD

Перезапустите клиент и используйте служебную программу командной строки для вызова контракта:

curl -X POST “http://127.0.0.1:5171/v2.3.0/transaction/call?from=YOUR_ADDR&to=0xd8f87ab60141d21323e9d675a35c5aac055e6490&gas=25000&gasPrice=100&value=0&nonce=YOUR_NONCE&data=0x3bc5de30" -H “accept: application/json” — user YOUR_API_USERNAME:YOUR_API_PASSWORD

Дополнительная информация:

  1. Репозиторий платформы Semux https://github.com/semuxproject/semux-core
  2. Документация Semux testnet (англ.)
  3. Документация Semux VM (англ.)
  4. Документация Semux VM Contracts (англ.)
  5. Блок-эксплорер http://testnet.semux.info/, https://testnet.semux.top/
  6. Публичный API https://api.testnet.semux.online/, https://api.testnet.semux.top/
  7. Общение напрямую с разработчиками https://discord.gg/qQVckKZ (англ.)
  8. Вопросы можно задать в русском Discord-сервере https://discordapp.com/invite/e3QYJBy на канале #смарт-контракты

--

--