IZZZIO BigNet¶
Содержание¶
IZZZIO BigNet¶
IZZZIO BigNet - это универсальная блокчейн платформа для любых задач. В основе платформы лежит идея создания блокчейн экосистемы, максимально приближеной к потребностям бизнеса, облегчающая интеграцию и использование технологии блокчейн в процессах компаний.
BigNet основан на универсальной блокчейн платформе IZZZIO и разработан одноимённой компанией IZZZIO LLC. (ООО «Изио»). Исходный код платформы открыт и доступен по лицензии Apache-2.0. Использование частей или всего кода платформы в любом из проектов требует публикации исходного кода этих проектов любым доступным способом.
BigNet в качестве основы сети использует систему смарт-контрактов, выполняющихся в специальной среде выполнения EcmaContracts, которая использует JavaScript движок V8 для создания виртуализированного окружения исполнения кода контрактов. Это позволяет полностью изолировать произвольный код контрактов как от системы, так и от других контрактов, а также контролировать доступность ресурсов (ОЗУ, процессорное время, лимиты вызовов) для каждой сущности виртуальной машины.
EcmaContracts реализует принцип управления состоянием (state) сущностей контракта, при котором в цепочку блокчейн сохраняется только информация о вызовах методов смарт-контрактов и их аргументах. Результаты работы смарт контрактов сохраняются локально на ноде пользователя, и загружаются при следующем вызове контракта. Все ноды в сети одновременно повторяют каждую транзакцию цепочки с самого первого блока, до последнего существующего, что приводит к полной сихнронизации состояний контрактов на каждой из нод.
В отличии от большинства схожих платформ, BigNet предлагает альтернативную схему платы за использование ресурсами плаформы:
- Вызовы смарт контрактов а также транзакции токенов в сети бесплатны
- При запуске кода контракта (deploy), взимается плата за аренду доступных в будущем ресурсов сети: ОЗУ, процессорное время, лимит вызовов в минуту
- Вводится понятие «контрактов-продавцов», которые продают информацию или услуги другим контрактам в сети
- Одномерный блокчейн. Принцип 1 транзакция - 1 блок. В большинстве платформ транзакции собираются по нескольку в блок, в BigNet - нет.
- В сети отсутствуют майнеры и специальные генераторы блоков. Генерация блока происходит на той ноде, которой необходимо добавить блок в сеть.
Характеристики сети¶
Характеристика Значение Алгоритм консенсуса DLCPoA - Dynamic Limited Confidence Proof of Activity* Программная платформа Node.js 10 Хеш-функция SHA256 Алгоритм цифровых подписей ECDSA-secp256k1. Основанная на bitcore-lib Криптопровайдер bitcore-lib Структура основной цепи блоков JSON блоки с произвольным содержимым. Объем блока до 2 Мб База данных LevelDB, Sqlite3 Смарт контракты EcmaContracts-V8. JavaScript ES6, с управляемым состоянием p2p протокол WebSocket Based + DNS-SD Multicast Discovery API/RPC/SDK PHPClass / JSON based / JavaScript DApp SDK Дополнительно Протокол децентрализованной передачи сообщений StarWave
- DLCPoA - модификация алгоритма LCPoA с изменяемой сложностью. Описание алгоритма LCPoA можно найти в этой статье
Быстрый старт¶
Язык смарт - контрактов¶
Система выполнения смарт-контрактов IZZZIO позволяет писать контракты с помощью языка JavaScript ES6. Смарт контракты являются полными по тьюрингу и имеют широкий функционал возможностей. При разработке доступно большинство стандартных методов и классов.
- Заменён метод Math.random(). Добавлена поддержка сохранения состояния
- Заменены методы класса Date для поддержки сохранения состояния
При написании контрактов необходимо использовать несколько принципов, обеспечивающих безопасность и корректность выполнения кода:
- Необходимо писать код в синхронном стиле. Асинхронность не поддерживается.
- Имена всех приватных методов и свойств должны начинатся со знака «_» для предоствращения несанкционированного обращения к ним
- Не использовать стандартный конструктор класса. Для инициализации класса необходимо использовать метод init и deploy для обработки первого запуска
- Для сохранения данных между запусками, необходимо использовать сохраняемые объекты KeyValue, TypedKeyValue, BlockchainArray, BlockchainMap
Рекомендации написания безопасных смарт контрактов:
Эти рекомендации позволят избежать большинство ошибок в проектировании и написании контракта. Помните, что запущенный контракт в последующем невозможно модифицировать или обновить!
- Для реализации токена использовать тип данных TokenRegister или наследовать контракт от TokenContract
- Для работы с числами, для которых важна точность вычислений, использовать класс BigNumber
- Рекомендуется наследовать любой контракт от класса Contract, который реализует основные системы защиты и обработки данных для контрактов
- Выполнять проверку всех входных данных на типы, а также обязательное приведение данных к нужному типу
- Выполнять проверки окружения выполнения контракта с помощью assert и других методов
- Важные данные, такие как адрес владельца контракта, следует определять заранее в константе перед классом контракта
- Помните, что данные, записанные в блокчейн являются открытыми, и доступны всем.
Советы по оптимизации:
- Минимизировать чтение и запись данных в сохраняемые объекты KeyValue, TypedKeyValue, BlockchainArray, BlockchainMap
- Минимизировать или не использовать циклы с перебором неопределенного или очень большого количества параметров
Простейший токен¶
Блокчейн 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 вы сможете прочитать в соответствующем разделе.
EcmaContracts¶
EcmaContracts реализует среду управления и выполнения смарт контрактов. EcmaContracts контролирует состояние, запущенные сущности виртуальных машин, потребление ресурсов, и обеспечивает среды выполнения контрактов необходимыми для работы методами и объектами. Взаимодействие с такими объектами позволяет мощные и функциональные децентрализованные системы.
Доступные объекты¶
Объекты-хранилища¶
Объекты, реализующие перенос и сохранение состояния между вызовами методов смарт контракта. Необходимы для сохранение любой информации (состояние счетов пользователя, балансы и другие)
KeyValue¶
Единственный реальный сохраняемый объект внутри виртуальной машины. Другие сохраняемые объекты зависят от объекта KeyValue, и по сути являются обёртками на его базе. KeyValue - объект, реализующий хранилице ключ-значение. Максимальное количество записей - не ограничено. Максимальная длина ключа и записи - 512 кБ.
new KeyValue
(название хранилища)¶
Аргументы:
- название хранилища (string) – Название хранилища для загрузки и записи данных
get
(ключ)¶
Аргументы:
- ключ (string) – Ключ по которому будет выполнятся поиск значения в хранилище
Результат: Значение. Если не найдено - false
put
(ключ, значение)¶
Аргументы:
- ключ (string) – Ключ по которому будет выполнена запись в хранилище
- значение (string) – Строка для записи в хранилище
Пример инициализации и использования методов:
class Test extends Contract { init(){ super.init(); //Создаём/загружаем хранилище this._db = new KeyValue('name'); } putKeyValue(){ this._db.put('key','value'); } getKeyValue(){ console.log(this._db.get('key')); //Выведет "value" } }TypedKeyValue¶
Аналог KeyValue, сохраняющий типы значений, при условии, что их можно сереализовать.
new TypedKeyValue
(название хранилища)¶
Аргументы:
- название хранилища (string) – Название хранилища для загрузки и записи данных
get
(ключ)
Аргументы:
- ключ (string) – Ключ по которому будет выполнятся поиск значения в хранилище
Результат: Значение. Если не найдено - false
put
(ключ, значение)
Аргументы:
- ключ (string) – Ключ по которому будет выполнена запись в хранилище
- значение (*) – Строка для записи в хранилище
Пример инициализации и использования методов:
class Test extends Contract { init(){ super.init(); //Создаём/загружаем хранилище this._db = new KeyValue('name'); } putKeyValue(){ this._db.put('number',1337); this._db.put('string',"Hello"); } getKeyValue(){ console.log(typeof this._db.get('number')); //Выведет "number" console.log(typeof this._db.get('string')); //Выведет "string" } }BlockchainArraySafe¶
Массивоподобная структура на основе KeyValue. Не содержит методы, которые могут привести к проблеме переполнения ОЗУ (join(), slice(), splice() и другие).
new BlockchainArraySafe
(название хранилища)¶
Аргументы:
- название хранилища (string) – Название хранилища для загрузки и записи данных
class Test extends Contract { init(){ super.init(); //Создаём/загружаем хранилище this._db = new BlockchainArraySafe('name'); } doSomething(){ this._db[0]=1; } doSomethingNext(){ this._db[0]++; } test(){ this.doSomething(); this.doSomethingNext(); console.log(this._db[0]); //Выведет "2" } }BlockchainArray¶
Данный объект является расширением BlockchainArraySafe. Содержит полифиллы методов, которые могут привести к переполнению доступной памяти. Рекомендуется использовать только на небольших массивах данных
new BlockchainArray
(название хранилища)¶
Аргументы:
- название хранилища (string) – Название хранилища для загрузки и записи данных
class Test extends Contract { init(){ super.init(); //Создаём/загружаем хранилище this._db = new BlockchainArraySafe('name'); } doSomething(){ this._db.push('Hello'); } doSomethingNext(){ this._db.push('world!'); } test(){ this.doSomething(); this.doSomethingNext(); console.log(this._db.join(' ')); //Выведет "Hello world!" } }BlockchainMap¶
Объекто-подобная структура. Не сереализуема. Сохраняет типы объектов при условии, что их можно сереализовать.
new BlockchainMap
(название хранилища)¶
Аргументы:
- название хранилища (string) – Название хранилища для загрузки и записи данных
class Test extends Contract { init(){ super.init(); //Создаём/загружаем хранилище this._db = new BlockchainMap('name'); this._db['hello'] = 'Hello'; this._db['world'] = 'world!'; console.log(this._db['hello']+' '+this._db['world']); //Выведет "Hello world!" } }TokenRegister¶
Класс, реализующий безопасную логику работы реестра токенов. Является основой для TokenContract и большинства токенов в системе. Содержит основные методы по управлению балансами кошельков, переводами, поддержкой минтинга, сжигания токенов, и учета существующего объема. Работает с числами до 256 знаков.
new TokenRegister
(название хранилища)¶
Аргументы:
- название хранилища (string) – Название хранилища для загрузки и записи данных
balanceOf
(адрес)¶
Аргументы:
- адрес (string) – Адрес для проверки баланса
Returns BigNumber: Баланс кошелька
totalSupply
()¶
Returns BigNumber: Суммарный объем существующих токенов
setBalance
(адрес, баланс)¶
Аргументы:
- адрес – Адрес для установки баланса
- баланс – Баланс, который необходимо установить
withdraw
(адрес, сумма)¶
Аргументы:
- адрес – Адрес для списания токенов
- сумма – Сумма списания
minus
(адрес, сумма)¶
Аргументы:
- адрес – Адрес для списания токенов
- сумма – Сумма списания
deposit
(адрес, сумма)¶
Аргументы:
- адрес – Адрес для начисления токенов
- сумма – Сумма начисления
plus
(адрес, сумма)¶
Аргументы:
- адрес – Адрес для начисления токенов
- сумма – Сумма начисления
transfer
(адрес отправителя, адрес получателя, сумма)¶
Аргументы:
- отправителя (адрес) – Адрес списания токенов
- получателя (адрес) – Адрес начисления токенов
- сумма – Сумма перевода
burn
(адрес, сумма)¶
Аргументы:
- адрес – Адрес для сжигания токенов
- сумма – Сумма сжигания
mint
(адрес, сумма)¶
Аргументы:
- адрес – Адрес для выпуска токенов
- сумма – Сумма выпуска
class Test extends Contract { init(){ super.init(); this._wallets = new TokensRegister('TKN'); this._wallets.mint('ME',1000); console.log(this._wallets.balanceOf('ME').toFixed()); //1000 this._wallets.transfer('ME','FRIEND',100); console.log(this._wallets.balanceOf('ME').toFixed()); //900 console.log(this._wallets.balanceOf('FRIEND').toFixed()); //100 } }События¶
Генерируемые события используются для построения индекса событий контракта. Например, база данных событий позволяет быстро узнать баланс токенов на определенном кошельке на момент появления определенного блока.
Events¶
Events - глобальный объект, реализующий возможность создания (выпуск) события смарт-контракта. Метод
emit
испускает событие. Внимание: Мы не рекомендуем использовать объект Events напрямую. Используйте объект Event для создания экземпляра события и его выпуска.
emit
(событие, аргументы)¶
Аргументы:
- событие (string) – Название события
- аргументы (array) – До 10 аргументов события
Event¶
Класс-обёртка, реализующий безопасное и удобное использование объекта Events. Event реализует проверку типов входящих параметров, а также корректно приводит данные к верному формату.
new Event
(событие, массив типов аргументов)¶
Аргументы:
- событие (string) – Название события
- массив типов аргументов (array) – До 10 типов аргументов события („number“,“string“,“array“,“object“)
emit
(аргументы)
Аргументы:
- аргументы (array) – До 10 аргументов события, соответствующих ранее указаному типу
class Test extends Contract { init(){ super.init(); this._helloEvent = new Event('Hello',['string']); this._helloEvent.emit('Hello world!'); } }Предупреждение
Event может принимать не более 10 параметров в качестве входных аргументов.
Объекты контрактов¶
Contract¶
Объект, рекомендуемый к наследованию всеми контрактами платформы. Объект Contract реализует:
- Базовый функционал проверки доступа
- Определение состояния запуска (deploy)
- Прием и подтверждение оплаты
- Взаимодействие с системой межконтрактных взаиморасчётов
- Интерфейс внешнего приложения
Внутренний метод init инициализирует внутренний функционал контракта, в том числе определение состояния запуска (deploy)
super.
init
()¶Вызывается единожды в жизни смарт контракта, позволяет определить момент запуска (deploy)
deploy
()¶Позволяет получить информацию об оплате. см. Pay Object
payProcess
()¶
Returns object: Объект с информацией оплаты Проверка на то, что вызывающий является владельцем контракта
assertOwnership
([msg])¶
Аргументы:
- msg (string) – Сообщение на случай ошибки проверки
Проверка на то, что вызывающий является мастер-контрактом
assertMaster
([msg])¶
Аргументы:
- msg (string) – Сообщение на случай ошибки проверки
Проверка на то, что метод вызван извне (т.е. не из другого контракта)
assertExternal
([msg])¶
Аргументы:
- msg (string) – Сообщение на случай ошибки проверки
Проверка на то, что метод вызван с передачей информации об оплате
assertPayment
([msg])¶
Аргументы:
- msg (string) – Сообщение на случай ошибки проверки
Добавление инфо-метода для внешнего приложения
_registerAppInfoMethod
(имя метода, типы аргументов)¶
Аргументы:
- имя метода (string) – Название метода
- типы аргументов (array) – Типы принимаемых значений метода
Добавление исполнительного-метода для внешнего приложения
_registerAppDeployMethod
(имя метода, типы аргументов)¶
Аргументы:
- имя метода (string) – Название метода
- типы аргументов (array) – Типы принимаемых значений метода
Добавление исходного кода приложения
_registerApp
(исходный код[, тип = "web"])¶
Аргументы:
- исходный код (string) – Исходный код внешнего приложения или информация для его поиска
- тип (array) – Тип внешнего приложения
Получение данных внешнего приложеия
getAppData
()¶
Returns string: Сереализованный объект внешнего приложения Регистрация обратного вызова для межконтрактных-покупок
_registerC2CResultCallback
(адрес контракта продавца, функция обратного вызова)¶
Аргументы:
- контракта продавца (адрес) – Адрес контракта-продавца, у которого сделан заказ
- обратного вызова (функция) – Функция, которая будет вызвана когда придёт заказ function(объект результата, номер заказа, адрес продавца)
TokenContract¶
Объект, рекомендуемый к наследованию всеми контрактами-токенами. Реализует интерфейс контракта стандарта IZ3 Token.
Свойство _wallets - экземпляр объекта TokenRegister
Свойство _TransferEvent - экземпляр объекта Event
Свойство _MintEvent - экземпляр объекта Event
Свойство _BurnEvent - экземпляр объекта Event
super.
init
(initialEmission[, mintable = false])
Аргументы:
- initialEmission – Стартовая эмиссия токенов
- mintable (boolean) – Разрешен ли минтинг в будующем
_getSender
()¶
Результат: Адрес отправителя вызова
balanceOf
(address)
Аргументы:
- address (string) – Адрес владельца токенов
Returns string: Баланс токенов
totalSupply
()
Returns string: Количество всего выпущеных токенов
transfer
(to, amount)
Аргументы:
- to (string) – Получатель токенов
- amount (string) – Количество токенов
burn
(amount)
Аргументы:
- amount (string) – Количество сжигаемых токенов
mint
(amount)
Аргументы:
- amount (string) – Количество выпускаемых токенов
getActionFee
(action, args)¶
Аргументы:
- action (string) – Действие
- args (array) – Аргументы
Returns string: Стоимость действия
getTransferFee
(amount)¶
Аргументы:
- amount (string) – Сумма перевода
Returns string: Стоимость перевода
Коннекторы¶
Коннекторы EcmaContracts - классы-обёртки, реализующие упрощенный интерфейс взаимодействия с внешними контрактами определённых типов.
ContractConnector¶
Базовый класс для коннекторов. Позволяет регестрировать методы и их алиасы.
TokenContractConnector¶
Класс коннектора, реализующий взаимодействие с контрактом-токеном из другого контракта
new TokenContractConnector
(address)¶
Аргументы:
- address (string) – Адрес контракта, к которому происходит подключение
balanceOf
(address)
Аргументы:
- address (string) – Адрес владельца токенов
Returns string: Баланс токенов
totalSupply
()
Returns string: Количество всего выпущеных токенов
transfer
(to, amount)
Аргументы:
- to (string) – Получатель токенов
- amount (string) – Количество токенов
burn
(amount)
Аргументы:
- amount (string) – Количество сжигаемых токенов
mint
(amount)
Аргументы:
- amount (string) – Количество выпускаемых токенов
class Test extends Contract { init(){ super.init(); let tokenContract = new TokenContractConnector(1); console.log(tokenContract.balanceOf('INVALID_ADDR')); //Выведет 0 } }SellerContractConnector¶
Класс коннектора, реализующий взаимодействие с контрактом-продавцом. Контракты-продавцы - это контракты, продающие данные или услугу внутри сети.
getPrice
(args)¶
Аргументы:
- args (array) – Аргументы заказа
Результат: Цена заказа
buy
(args)¶
Аргументы:
- args (array) – Аргументы заказа
Результат: id заказа
getResult
(orderId)¶
Аргументы:
- orderId (string) – id заказа
Результат: Объект содержащий заказ
Require¶
Require - не относится к стандартным коннекторам, однако реализует сходный функционал. Require позволяет создать экземпляр класса внешнего контракта с произвольными методами и свойствами. Наличие методов и свойств во внешнем классе проверяется во время выполнения кода.
new Require
(externalContract)¶
Аргументы:
- externalContract (string) – Адрес подключаемого контракта
class Test extends Contract { init(){ super.init(); let tokenContract = new Require(1); console.log(tokenContract.balanceOf('INVALID_ADDR')); //Выведет 0 console.log(tokenContract.invalidMethod('INVALID_ADDR')); //Бросит исключение } }Альтернативный синтаксис c методом-фабрикой:
require
(externalContract)
Аргументы:
- externalContract (string) – Адрес подключаемого контракта
Системные классы¶
assert¶
Предоставляет функционал проверки каких - либо условий. Невыполнение этих условий ведёт к бросу исключения, и завершению вызова контракта с ошибкой. Состояние контракта откатывается до состояния до вызова.
Предоставляются следующие методы для проверки условий:
- Простая проверка на истину
assert
(условие[, сообщение])
Аргументы:
- условие – условие, истина
- сообщение (string) – сообщени
- Проверка на несоответствие типу undefined
defined
(условие[, сообщение])¶
Аргументы:
- условие – простое условие с использованием условных операторов
- сообщение (string) – сообщение при неверности условия
- Проверяет верность условия a > b
gt
(a, b[, сообщение])¶
Аргументы:
- a – числовой параметр
- b – числовой параметр
- сообщение (string) – сообщение при неверности условия
- Проверяет верность условия a < b
lt
(a, b[, сообщение])¶
Аргументы:
- a – числовой параметр
- b – числовой параметр
- сообщение (string) – сообщение при неверности условия
- Проверяет истинность условия. Алиас assert.assert
true
(условие[, сообщение])¶
Аргументы:
- условие – условие
- сообщение (string) – сообщение при неверности условия
- Проверка ложности условия (аналогично «Неверно, что…»)
false
(условие[, сообщение])¶
Аргументы:
- условие – условие; условие
- сообщение (string) – сообщение при неверности условия
class Test extends Contract { init(){ super.init(); assert.gt(100,200,'100 не может быть больше 200'); } }contracts¶
Предоставляет функционал для управления текущим или взаимодействия с внешними контрактами. Доступны следующие методы:
Вызов метода другого контракта с сохранением изменённого состояния.
callMethodDeploy
(адресКонтракта, метод[, аргументы])¶
Аргументы:
- адресКонтракта (string) – адрес вызываемого контракта.
- метод (string) – метод вызываемого контракта.
- аргументы (array) – передаваемый методу аргументы в виде массива.
Бросает исключение:
- Error1 – „You can’t call method from himself“ - вызов изнутри.
- Error2 – „External call failed“ - ошибка при вызова метода.
Результат: результат вызова метода.
Вызов метода другого контракта выполняемый после завершения текущего вызова
callDelayedMethodDeploy
(адресКонтракта, метод[, аргументы])¶
Аргументы:
- адресКонтракта (string) – адрес вызываемого контракта.
- метод (string) – метод вызываемого контракта.
- аргументы (array) – передаваемый методу аргументы в виде массива.
Бросает исключение: Error1 – „You can’t call method from himself“ - вызов изнутри.
Запрос свойства другого контракта
getContractProperty
(адресКонтракта, свойство)¶
Аргументы:
- адресКонтракта (string) – адрес вызываемого контракта.
- свойство (string) – свойство контракта
Бросает исключение: Error1 – „You can’t call method from himself“ - вызов изнутри.
Результат: Значение свойства
Метод устарел. Вызов метода другого контракта с откатом изменённого состояния.
callMethodRollback
(адресКонтракта, метод[, аргументы])¶
Аргументы:
- адресКонтракта (string) – адрес вызываемого контракта.
- метод (string) – метод вызываемого контракта.
- аргументы (array) – передаваемый методу аргументы в виде массива.
Бросает исключение: Error1 – „You can’t call method from himself“ - вызов изнутри.
Результат: результат вызова метода.
getMasterContractAddress
()¶
Результат: Адрес мастер-контракта, определенный в конфигурации
caller
()¶
Результат: адрес вызывающего контракта; false, если вызов внешний
callingIndex
()¶
Результат: номер текущего вызова контракта в цепочке вызовов или 0, если вызов внешний
isChild
()¶:returns:: true, если контракт был вызван другим контрактом, в ином случае - false
isDeploy
()¶:returns:: true, если контракт находится в состоянии запуска (deploy), в ином случае - false
isDelayedCall
()¶
Результат: true если вызов выполнен с помощью callDelayedMethodDeploy
getExtendedState
()¶
Результат: Объект добавочного состояния crypto¶
Методы работы с криптографией
sha256
(data)¶
Аргументы:
- data (string) – Данные для хеширования
Результат: Строковое представление хеш-суммы
md5
(data)¶
Аргументы:
- data (string) – Данные для хеширования
Результат: Строковое представление хеш-суммы
Хеширование сконфигурированной функцией
hash
(data)¶
Аргументы:
- data (string) – Данные для хеширования
Результат: Строковое представление хеш-суммы
Проверка цифвровой подписи сконфигурированной функцией
verifySign
(data, sign, publicKey)¶
Аргументы:
- data (string) – Данные для проверки
- sign (string) – Подпись данных
- publicKey (string) – Публичный ключ
Returns boolean: true если проверка успешна
global¶
Другие глобальные методы
Передача класса контракта в виртуальную машину
registerContract
(контракт)¶
Аргументы:
- data (string) – Данные для проверки
- sign (string) – Подпись данных
- publicKey (string) – Публичный ключ
Returns boolean: true если проверка успешна
Вывод данных на экран (при условии включеного вывода)
console.
log
(данные)¶
Аргументы:
- данные (string) – Данные для проверки
getState
()¶
Returns object: Текущий объект state. Рекомендуется использовать вместо global.state Другие доступные объекты¶
BigNumber¶
Объект, позволяющий безопасно проводить арифметические операции с большими числами. Рекомендуется для любых вычислений связанных с балансами пользователей, и с необходимой точностью.
Date¶
Встроенный объект даты, однако ход времени объекта Date заморожен, и установлен в соответствии с состоянием, передаваемым в вызове.
Math¶
Встроенный объект. Отличием от стандартного
Math
является реализацияrandom
: использует внешний seed, устанавливаемый в соответствии с состоянием, передаваемым в вызове.
DApp¶
Децентрализованные приложения в IZZZIO позволяют создавать добавочный функционал для ноды. Такие приложения имеют широкий функционал: 1. Взаимодействие с цепочкой блоков, предобработка, реакция на изменения цепочки 2. Взаимодействие со смарт контрактами, в том числе запуск новых 3. Взаимодействие с другими децентрализованными приложениями посредством встроенных протколов. См. StarWave, StarWaveCrypto 4. Интеграция централизованных приложений с децентрализованным.
Для написания децентрализованных приложений в IZZZIO используется класс DApp. Класс предоставляет все необходимые методы для работы с функционалом сети, и обеспечивает совместимость приложений с разными версиями узлов блокчейна IZZZIO.
DApp¶
При создании класса наследуемого от DApp рекомендуется не объявлять конструктор, и использовать вместо него встроенный метод init
Для обработки состояния завершения используется метод terminate(cb)
Глобальные переменные¶
Для использования в DApp доступны следующие глобальные переменные:
- global.PATH.mainDir - путь до корневой директори файлов блокчейна IZZZIO
- global.PATH.configDir - путь до директории конфигурационного файла
Эти переменные обычно используются для включения файлов модулей ядра в проект.
const DApp = require(global.PATH.mainDir + '/app/DApp'); //Поиск DApp будет выполнен в корневой директории блокчейна
class TestDapp extends DApp {
init(){
console.log('DApp ready!');
}
terminate(cb){
console.log('DApp terminated');
}
}
Доступные объекты¶
logger¶
Внутренний путь: modules/logger
logger обеспечивает стандартизацию вывода сообщений в консоль.
Свойство: disable
- true - отключение вывода сообщений; false - вывод включения
-
new Logger
([prefix])¶ Аргументы: - prefix (string) – Префикс, с которым будет выводится сообщение
-
getPrefix
()¶ Результат: Текущий установленный префикс
-
log
(type, data)¶ Аргументы: - type (string) – Тип сообщения для вывода
- data (string) – Сообщение
-
info
(type, data)¶ Аргументы: - data (string) – Сообщение информационного типа
-
init
(type, data)¶ Аргументы: - data (string) – Сообщение инициализации
-
error
(type, data)¶ Аргументы: - data (string) – Сообщение об ошибке
-
fatal
(type, data)¶ Аргументы: - data (string) – Сообщение о критической ошибке
-
warning
(type, data)¶ Аргументы: - data (string) – Предупреждение
const DApp = require(global.PATH.mainDir + '/app/DApp');
const logger = new (require(global.PATH.mainDir + '/modules/logger'))("TestDApp");
class TestDApp extends DApp {
init(){
logger.info('Test DApp ready!'); //Выведет "Fri, 01 Feb 2019 14:12:48 GMT Info: ECMAContract: Test DApp ready"
}
}
assert¶
Внутренний путь: modules/testing/assert
Предоставляет функционал проверки каких - либо условий. Невыполнение этих условий ведёт к бросу исключения, и завершению вызова контракта с ошибкой. Состояние контракта откатывается до состояния до вызова.
Реализация идентична реализации для EcmaContract.
Перейти на описание assert
instanceStorage¶
Внутренний путь: modules/instanceStorage
Предоставляет доступ к созданным экземплярам объектов на основе ключей.
-
instanceStorage.
get
(objName)¶ Аргументы: - name (string) – Название сохранённой сущности
Результат: Сохранённая сущность или null при отсутствии
-
instanceStorage.
put
(objName, value)¶ Аргументы: - name (string) – Название сохраняемой сущности
- value – Объект сущности
По умолчанию instanceStorage содержит следующие сущности:
- Blockchain - главный экземпляр объекта сети
- config - экземпляр объекта конфигурации
- wallet - текущий кошёлёк
- blocks - хранилище данных блоков
- blockHandler - экземпляр объекта обработчика блоков
- frontend - экземпляр объекта RPC интерфейса и оболочки
- transactor - экземпляр объекта контроля траназкций
- cryptography - экземпляр объекта криптографии
- blockchainObject - алиас объекта Blockchain
Опциональные объекты и значения:
- ecmaContract - экземпляр объекта смарт контрактов (если включены)
- dapp - экземпляр объекта децентролизованного приложения (если включено)
- terminating - флаг завершения работы
const DApp = require(global.PATH.mainDir + '/app/DApp');
const storj = require(global.PATH.mainDir + '/modules/instanceStorage');
class TestDApp extends DApp {
init(){
console.log(storj.get('config').p2pPort); //6015
}
}
StarWaveCrypto¶
См. раздел StarWaveCrypto
Коннекторы¶
Коннекторы DApp - классы-обёртки, реализующие упрощенный интерфейс взаимодействия с контрактами определённых типов.
DApp-ContractConnector¶
Внутренний путь: modules/smartContracts/connectors/ContractConnector
Базовый абстрактный класс для коннекторов. Позволяет регестрировать методы и их алиасы.
DApp-TokenContractConnector¶
Внутренний путь: modules/smartContracts/connectors/TokenContractConnector
Класс коннектора, реализующий взаимодействие с контрактом-токеном для DApp
-
new TokenContractConnector
(EcmaContractsInstance, contractAddress)¶ Аргументы: - EcmaContractsInstance – Экзмпляр объекта EcmaContracts
- contractAddress (string) – Адрес контракта, к которому происходит подключение
-
async balanceOf
(address)¶ Аргументы: - address (string) – Адрес владельца токенов
Returns string: Баланс токенов
-
async totalSupply
()¶ Returns string: Количество всего выпущеных токенов
-
async transfer
(to, amount)¶ Аргументы: - to (string) – Получатель токенов
- amount (string) – Количество токенов
-
async burn
(amount)¶ Аргументы: - amount (string) – Количество сжигаемых токенов
-
async mint
(amount)¶ Аргументы: - amount (string) – Количество выпускаемых токенов
-
async contract
()¶ Returns string: Свойство contract из контракта. Данные о контракте
Выполнение метода из другого контракта с оплатой
-
async pay
(address, method, txAmount, args)¶ Аргументы: - address (string) – Адрес контракта для вызова метода
- method (string) – Метод
- txAmount (string) – Сумма перевода
- args (array) – Аргументы вызова
Результат: Новый созданный блок
const DApp = require(global.PATH.mainDir + '/app/DApp');
const TokenContractConnector = require(global.PATH.mainDir + '/modules/smartContracts/connectors/TokenContractConnector');
class TestDApp extends DApp {
async init(){
let mainToken = new TokenContractConnector(this.ecmaContract, this.getMasterContractAddress());
console.log(await mainToken.balanceOf(this.getCurrentWallet().id)); //Выведет баланс текущего кошелька
//Вызовет метод processPayment из контракта SOME_CONTRACT_ADDRESS с параметром 'Hello', передав состояние проведения оплаты на 1 токен с текущего кошелька
await mainToken.pay(SOME_CONTRACT_ADDRESS, "processPayment", '1', ['Hello']);
}
}
Внутренние объекты DApp¶
DApp.network¶
Предоставляет базовый функционал взаимодействия с сетевым интерфейсом, а также регистрацию RPC и обрбаотчиков интерфейса.
- Возвращает массив текущих пиров в формате ws://address:port
-
getCurrentPeers
()¶ Результат: пиры
- Получение сокета по адресу шины (адрес внешней ноды)
-
getSocketByBusAdress
(address)¶ Аргументы: - address (string) – адрес шины
Результат: объект сокета или false, если адрес не был найден.
- Прямая отправка сообщения в сокет
-
socketSend
(ws, message)¶ Аргументы: - ws – сокет.
- message (string) – сообщение.
- Регистрация метода обратного вызова для get запроса
-
rpc.
registerGetHandler
(url, callback)¶ Аргументы: - url (string) – Обрабочтик ссылки
- callback (function) – Метод обратного вызова
- Регистрация метода обратного вызова для post запроса
-
rpc.
registerPostHandler
(url, callback)¶ Аргументы: - url (string) – Обрабочтик ссылки
- callback (function) – Метод обратного вызова
Методы rpc.registerGetHandler
и rpc.registerPostHandler
основаны на использовании фреймворка Express.js. Подробнее об обработчиках в документации Express.js
DApp.messaging¶
Устаревший функционал Предоставляет базовый функционал обмена собщениями между узлами сети.
1.Регистрация обработчика сообщений
-
registerMessageHandler
(message, handler)¶ Аргументы: - message (string) – идентификатор сообщения
- handler (function) – функция - обработчик сообщений
- Метод широковещательной передачи сообщений по сети
-
broadcastMessage
(data, message, receiver)¶ Аргументы: - data – передаваемый объект
- message (string) – идентификатор сообщения
- receiver (string) – получатель сообщения
- Метод передачи сообщения близжайшему получателю
-
sendMessage
(data, message, receiver)¶ Аргументы: - data – объект, содержащий само сообщение.
- message (string) – идентификатор сообщения.
- receiver (string) – получатель сообщения.
Методы DApp.messaging.starwave описаны в разделе StarWave
DApp.blocks¶
Предоставляет доступ к функционалу генерации и добавления блоков, обработчику событий.
Генерирует блок без добавления в цепочку блоков
-
generateBlock
(blockData, cb, cancelCondition)¶ Аргументы: - blockData (Block) – Подписанный блок Block
- cb (function) – функция обратного вызова function(newBlock)
- cancelCondition – Функция условия отмены генерации блока
Генерация блока с добавлением в цепочку блоков и уведомлением узлов о новом блоке
-
generateAndAddBlock
(blockData, cb, cancelCondition)¶ Аргументы: - blockData (Block) – Подписанный блок Block
- cb (function) – функция обратного вызова function(newBlock)
- cancelCondition – Функция условия отмены генерации блока
Добавление сгенерированного блока
-
addBlock
(newBlock, cb)¶ Аргументы: - newBlock – Готовый блок
- cb – callback - обратного вызова
Методы обработчика блоков
Возвращает экземпляр текущего обработчика блоков
-
handler.
get
()¶ Результат: объект обработчика (ловца) блоков.
Регистрация обработчика блока по типу
-
handler.
registerHandler
(type, handler)¶ Аргументы: - type (string) – Тип блока
- handler (function) – функция - обработчик блоков function(blockData, blockSource, callback)
Предупреждение
Вызов callback в обработчике блоков обязателен. Отсутствие обратного вызова приведёт к зависанию обработчика блоков.
DApp.contracts¶
Предоставляет функционал доступа к модулю EcmaContracts.
contracts.ecma
- предоставляет прямой доступ к объекту EcmaContracts. См. EcmaContracts
contracts.ecmaPromise
- предоставляет основные методы EcmaContracts для использования с асинхронным режимом (async-await)
Выполняет запуск контракта в сети
-
ecmaPromise.
deployContract
(source, resourceRent)¶ Аргументы: - source (string) – Исходнй код контракта
- resourceRent (number) – Количество токенов, выделяемых на аренду ресурсов контракта
Результат: объект нового блока
Выполняет запуск метода из контракта
-
ecmaPromise.
deployMethod
(address, method, args, state)¶ Аргументы: - address (string) – Адрес контракта
- method (string) – Метод контракта
- args (array) – Массив с аргументами вызова
- state (object) – Объект передаваемого состояния
Результат: объект нового блока
Выполняет запуск метода из контракта с откатом состояния
-
ecmaPromise.
callMethodRollback
(address, method, args, state)¶ Аргументы: - address (string) – Адрес контракта
- method (string) – Метод контракта
- args (array) – Массив с аргументами вызова
- state (object) – Объект передаваемого состояния
Результат: Результат выполнения метода контракта
Внутренние методы DApp¶
-
DApp.
getConfig
()¶ Результат: объект конфигурации
-
DApp.
getBlockHandler
()¶ Результат: объект обработчика блоков
-
DApp.
getCurrentWallet
()¶ Результат: объект текущего кошелька
-
DApp.
getMasterContractAddress
()¶ Результат: адрес мастер-контракта или false если не существует
StarWave¶
StarWave - протокол высокоскоростной передачи данных внутри децентрализованной сети IZZZIO. Протокол автоматически составляет кратчайший маршрут доставки сообщения до получателя. В случае нарушения маршрута, происходит его перестроение по такому-же принципу.
Методы StarWave доступны в DApp DApp.messaging.starwave
Методы messaging.starwave¶
Регистрация обработчика сообщений
-
starwave.
registerMessageHandler
(message, handler)¶ Аргументы: - message (string) – идентификатор сообщения
- handler (function) – функция - обработчик сообщений
Метод передачи сообщения близжайшему получателю
-
starwave.
sendMessage
(data, message, receiver)¶ Аргументы: - data – объект, содержащий само сообщение.
- message (string) – идентификатор сообщения.
- receiver (string) – получатель сообщения.
Метод создания структуры сообщения
-
starwave.
createMessage
(data, reciver, sender = undefined, id, timestamp = undefined, TTL = undefined, relevancyTime = undefined, route = undefined, type = undefined, timestampOfStart)¶ Аргументы: - data – объект, содержащий само сообщение.
- reciver (string) – получатель сообщения
- sender (string) – отправитель сообщения; undefined - используются системное инфо об отправителе
- id (string) – Идентификатор сообщения
- timestamp (number) – Метка времени сообщения; undefined - автоматически
- TTL (number) – Возможное количество скачков сообщения; undefined - автоматически
- relevancyTime (number) – время актуальности сообщения; undefined - автоматически
- timestamp – Метка времени сообщения; undefined - автоматически
- route (array) – Маршрут сообщения; undefined - автоматически
- type (string) – Тип сообщения; undefined - автоматически
- timestampOfStart (number) – Метка времени отправки сообщения; undefined - автоматически
Результат: Объект структуры сообщения
StarWaveCrypto¶
Внутренний путь: modules/starwaveCrypto
StarWaveCrypto - модуль, реализующий создание шифрованного канала для обмена данными между узлами сети. При создании подключения, между узлами просходит генерация и обмен ключами по протоколу Диффи - Хеллмана (DH).
Для cоздания шифрованного канала используется метод, осуществляющий «рукопожатие». Таким образом, принимающая сторона, используя метод обработки получаемых сообщений, сразу создаст новое защищеное соъединение, или использует существующее. Пример установки соединения:
const DApp = require(global.PATH.mainDir + '/app/DApp');
const StarwaveCrypto = require(global.PATH.mainDir + '/modules/starwaveCrypto');
class TestDApp extends DApp {
init() {
let that = this;
starwave.registerMessageHandler('SW_TEST', function (message) {
console.log('New message', message);
});
let crypto = new StarwaveCrypto(this.starwave, this.blockchain.secretKeys).makeConnection(RECIVER_ADDRESS, function(who, secretKey){
console.log('Connected!');
let message = that.starwave.createMessage('Hello Node Two' + Math.random(), 'RECIVER_ADDRESS', undefined, 'SW_TEST');
crypto.sendMessage(m);
});
};
}
Стандарты¶
IZ3 Token¶
Сандарт токена определяет обязательные условия:
- Свойство contract возвращающее информацию о токене
{name, ticker, owner, emission, type}
иtype="token"
- Метод init(исходная эмиссия [, разрешен минтинг = false])
- Метод balanceOf(адрес)
- Метод totalSupply() возвращающий общую сумму выпущеных токенов
- Метод transfer(адрес получателя, сумма перевода)
- Метод burn(сумма сжигания)
- Метод mint(сумма минтинга)
- Метод getTransferFee(сумма) передающий стоимость операции перевода
- Метод getActionFee(действие, параметры) передающий стоимость выполнения какой-либо операции
- События Transfer(адрес отправителя,адрес получателя, сумма) вызываемого при любом движении средств
- События Mint(адрес, сумма)
- События Burn(адрес, сумма)
Стандарт токена в полной мере реализован встроенным классом TokenContract.
Pay Object¶
Объект, возвращаемый методой payProcess класса Contract.
{
amount, //Сумма платежа, BigNumber
rawAmount, //Сумма платежа, исходный вид
ticker, //Тикер валюты платежа
balance, //Новый баланс контракта, BigNumber
rawBalance, //Новый баланс контракта, исходный вид
caller, //Адрес контракта токена платежа
contractName, //Имя контракта-токена платежа
}
Для проверки валюты платежа рекомендуется проверять адрес вызывающего таким образом:
assert.true(Number(PayObject.caller) === Number(WANTED_TOKEN_ADDR));
Для приема платежа только основного токена сети, используйте:
assert.true(Number(PayObject.caller) === Number(contracts.getMasterContractAddress()));
state¶
Объект текущего состояния запуска. Один из самых важных объектов виртаульной среды
Рекомендованный метод получить текущий state const state = global.getState();
Содержимое объекта может сильно менятся в зависимости от текущего состояния запуска контракта, поэтому рекомендуется проверять наличие или отсутсвие необходимых свойств перед работой с ними.
Основные свойства:
- state.from - Адрес пользователя, иницировавшего запуск методов смарт контракта. Видно всем контрактам в цепочке вызовов
- state.block - Опциональное свойство. Объект блока текущего вызова. См. Block
- state.contractAddress - Адрес контракта текущего вызова.
- state.extend - Опциональное свойство. Объект дополнительного состояния.
- state.randomSeed - Опциональное свойство. Текущая настройка генератора случайных чисел
- state.calledFrom - Опциональное свойство. Адрес контракта, совершиевшго текущий вызов
- state.delayedMethod - Опциональное свойство. Флаг отложенного вызова
- state.callingIndex - Опциональное свойство. Номер текущего вызова в цепочке вызовов
Block¶
Объект блока. Свойства:
- index - текущий номер
- previousHash - хеш предыдущего блока
- timestamp - метка времени блока
- startTimestamp - мета начала генерации блока
- data - строка данных
- hash - хеш блока
- sign - цифровая подпись блока