Skip to content
Permalink
Branch: master
Find file Copy path
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
141 lines (94 sloc) 10 KB

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

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

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

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

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

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

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

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

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

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

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

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

Блокчейн IZZZIO использует свой стандарт описания контрактов-токенов, схожий со стандартом ERC20 блокчейна Ethereum, однако с некоторыми отличиями. Стандарт IZ3 Token (IZ3T) подразумевает наличие определенных методов и свойств у контракта. Большинство этих методов уже реализованно во встроенном классе :ref:`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);

Note

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

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

На текущий момент (2019-02-01) единственным способом запуска контракт в сеть является запуск через :ref:`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);
            });
        };
}

Note

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

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

См. также: :ref:`Block`

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

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

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

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

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

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

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

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

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

You can’t perform that action at this time.