Быстрый старт

Язык смарт - контрактов

Система выполнения смарт-контрактов IZZZIO позволяет писать контракты с помощью языка JavaScript ES6. Смарт контракты являются полными по тьюрингу и имеют широкий функционал возможностей. При разработке доступно большинство стандартных методов и классов.

  • Заменён метод Math.random(). Добавлена поддержка сохранения состояния
  • Заменены методы класса Date для поддержки сохранения состояния

При написании контрактов необходимо использовать несколько принципов, обеспечивающих безопасность и корректность выполнения кода:

  1. Необходимо писать код в синхронном стиле. Асинхронность не поддерживается.
  2. Имена всех приватных методов и свойств должны начинатся со знака «_» для предоствращения несанкционированного обращения к ним
  3. Не использовать стандартный конструктор класса. Для инициализации класса необходимо использовать метод init и deploy для обработки первого запуска
  4. Для сохранения данных между запусками, необходимо использовать сохраняемые объекты KeyValue, TypedKeyValue, BlockchainArray, BlockchainMap

Рекомендации написания безопасных смарт контрактов:

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

  1. Для реализации токена использовать тип данных TokenRegister или наследовать контракт от TokenContract
  2. Для работы с числами, для которых важна точность вычислений, использовать класс BigNumber
  3. Рекомендуется наследовать любой контракт от класса Contract, который реализует основные системы защиты и обработки данных для контрактов
  4. Выполнять проверку всех входных данных на типы, а также обязательное приведение данных к нужному типу
  5. Выполнять проверки окружения выполнения контракта с помощью assert и других методов
  6. Важные данные, такие как адрес владельца контракта, следует определять заранее в константе перед классом контракта
  7. Помните, что данные, записанные в блокчейн являются открытыми, и доступны всем.

Советы по оптимизации:

  1. Минимизировать чтение и запись данных в сохраняемые объекты KeyValue, TypedKeyValue, BlockchainArray, BlockchainMap
  2. Минимизировать или не использовать циклы с перебором неопределенного или очень большого количества параметров

Простейший токен

Блокчейн IZZZIO использует свой стандарт описания контрактов-токенов, схожий со стандартом ERC20 блокчейна Ethereum, однако с некоторыми отличиями. Стандарт IZ3 Token (IZ3T) подразумевает наличие определенных методов и свойств у контракта. Большинство этих методов уже реализованно во встроенном классе TokenContract, от которого рекомендуется наследовать любой токен-контракт.

Пример простейшего токена, соответствующему стандарту IZ3T и рекомендациям безопасности:

//Определение размера эмиссии
const EMISSION = 10000;

//Определение адреса владельца контракта
const CONTRACT_OWNER = 'SOME_ADDR';

class TestToken extends TokenContract{

    //Инициализация токена. Обратите внимание, что init используется в качестве конструктора
    init() {
        super.init(EMISSION);
    }

    //Свойство данных о контракте
    get contract() {
        return {
            name: 'Token name',
            ticker: 'TokenTicker',
            owner: CONTRACT_OWNER,
            emission: EMISSION,
            type: 'token',
        };
    }
}

//Передача класса контракта в управление виртуальной машине
global.registerContract(TestToken);

Примечание

Контракт наследует основные методы стандарта от класса TokenContract. При запуске контракта эмиссия токенов будет произведена на адрес CONTRACT_OWNER. Учет количества и движения токенов производится внутри TokenRegister объявленного в TokenContract

Запуск контракта

На текущий момент (2019-02-01) единственным способом запуска контракт в сеть является запуск через DApp SDK платформы IZZZIO. В будущем будет доступен запуск контракта с помощью пользовательских приложений и онлайн клиентов сети. Для запуска вам понадобятся токены, на аренду ресурсов сети для контракта. На простой токен, описанный выше хватит минимальных ресурсов.

Код DApp приложения для запуска контракта:

const CONTRACT_CODE = ''; //Переменная, содержащая код контракта

const RESOURCES = 1; //Количество токенов для покупки аренды ресурсов

//Модуль DApp SDK IZZZIO
const DApp = require(global.PATH.mainDir + '/app/DApp');

class App extends DApp {
        init() {
            that = this;
            that.contracts.ecmaContract.deployContract(CONTRACT_CODE, RESOURCES, function (deployedContract) {
                    console.log('Contract deployed at address', deployedContract.address);
            });
        };
}

Примечание

Для запуска DApp не забудьте добавить в config.json параметр appEntry и указать путь до точки входа в приложение. Например «appEntry»: «./BigNet/startNetwork.js», из файла BigNet/configStart.json в репозитории

После запуска DApp контракт будет запущен в сеть, и его адрес будет выведен на экран.

См. также: Block

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

Для взаимодействия в сети IZZZIO рекомендуется использовать методы ecmaContracts из DApp SDK. Например, для получения общего количества существующих токенов контракта-токена можно использовать метод:

let supply = await that.contracts.ecmaPromise.callMethodRollback(CONTRACT_ADDRESS, 'totalSupply', [], {});

Вызов этого метода запускает метод totalSupply из контракта. После завершения выполнения состояние контракта откатывается до состояния до запуска, и возвращается значение, которое вернул метод totalSupply, т.е. общее количество существующих токенов.

Для взаимодействия с некоторыми стандартными форматами контрактов существуют встроенные классы-обёртки, облегчающие вызовы методов и получения свойств. Например для IZ3 Token класс-обертка - DApp-TokenContractConnector. Использовать его можно так:

let token = new TokenContractConnector(that.ecmaContract, CONTRACT_ADDRESS);

//Аналог примера выше
let supply =  await token.totalSupply();

//Выполнение транзакции на 10 токенов
await token.transfer(SOME_ADDRESS,'10');

Подробнее про DApp-TokenContractConnector вы сможете прочитать в соответствующем разделе.