Пишем свой токен ERC20 на Solidity с помощью Truffle

Solidity — это язык написания умных контрактов (smart contracts) для EVM (Ethereum Virtual Machine). Solidity не был первым ЯП и не является единственным. Существуют также:

  • Serpent. Похож на Python. Морально устарел.
  • Mutan. Для любителей языка C. Репозиторий не обновлялся уже 2 года.
  • LLL (Low-Level-Lisp). Низкоуровневый на уровне ассемблера, документации почти нет.
  • Viper. Новый и пока экспериментальный ЯП, снова Python.

Есть мнение, что выбор такого легкомысленного ЯП, как Javascript в качестве прототипа для языка Solidity был не слишком удачен. Главное, на что пеняют противники Ethereum это то, что к Solidity невозможно применить аппарат атоматической проверки теорем, а значит ошибки в умных контрактах будут всегда стоить очень дорого.

Официальный сайт Ethereum содержит достаточно хорошую документацию по Solidity. Есть также попытки перевести ее на русский (спасибо Денису Солдатову), однако чтобы начать что-то разрабатывать на новом ЯП иногда не хватает ободряющего пинка под зад. Эта статья призвана понизить порог вхождения и служит цели помочь написать свой первый контракт на языке Solidity.

Выбираем фреймворк

Хотя программирование умных контрактов как жанр появилось сравнительно недавно, разработчики тут же стали писать инструменты для более удобной и быстрой разработки. Появились даже фреймворки. Вот небольшой обзор:

Embark

Вебсайт: https://github.com/iurimatias/embark-framework
Язык: Javascript
Тесты: Javascript/Mocha

Embark поддерживает не только Ethereum, но и IPFS, Swarm, Whisper и Orbit. В комплекте удобная консоль. Пока нет поддержки пакетов ERC190.

Dapp (ранее dapple)

Вебсайт: https://github.com/iurimatias/embark-framework
Язык: Bash
Тесты: Solidity

Это даже не фреймворк, а набор утилит для работы с проектом. С помощью менеджера пакетов nix инсталлируются все необходимые зависимости. Неудобно, что утилиту ethrun нужно ставить вручную и прописывать в PATH.

Populous

Вебсайт: http://populus.readthedocs.io/en/latest/quickstart.html
Язык: Python
Тесты: py.tests

Написан на Питоне и тесты контрактов приходится писать также на нем. Находится в Alpha.

Truffle

Вебсайт: https://github.com/trufflesuite/truffle
Язык: Javascript
Тесты: Javascript/Mocha/Chai либо Solidity

Трюфель разработан и поддерживается компанией ConsenSys, стоящей за Виталиком Бутериным. Имеется поддержка миграций. Есть консоль.

OpenZeppelin

Вебсайт: https://github.com/OpenZeppelin/zeppelin-solidity
Язык: Solidity

OpenZeppelin не фреймворк, а библиотека часто используемых классов и интерфейсов, проверенных аудиторами безопасности. Интегрируется с Truffle.

Обзор утилит

Создатели фреймворков стараются не изобретать велосипеды. Коротко познакомимся с общеупотребимыми инструментами:

  • ethereumjs: набор утилит и Javascript-библиотек для работы с Ethereum. Утилита ethereumjs-vm, входящая в набор является эмулятором EVM (Ethereum Virtual Machine).
  • geth: официальный клиент Ethereum для командной строки. Также является нодой и может майнить в основном блокчейне, тестовом или приватном. С ним можно коммуницировать через интерфейс RPC.
  • testrpc: также из набора ethereumjs. Запускает эмуляцию EVM с помощью ethereumjs-vm и предоставляет RPC-интерфейс аналогичный geth.
  • solc: компиллятор скриптов на Solidity.

Инсталлируем инструменты

Для нашего игрушечного проекта я выбрал Truffle, т.к. разрабатывая на Solidity тесты логично писать также на нем. На компьютере должен быть установлен node.js и пакетный менеджер npm. Сначала поставим testrpc:

npm install -g ethereumjs-testrpc

Теперь пришла очередь поставить Truffle:

npm install -g truffle

Теперь создадим пустую папку и проинициализируем проект:

mkdir try-solidity && cd try-solidity && truffle init

Пишем свой ERC20 токен

Дальнейшее есть краткий пересказ туториала. Наш игрушечный проект — это обычный умный контракт для токенов стандарта ERC20. OpenZeppelin уже содержит весь необходимый код, нам понадобится его только отконфигурировать под себя. Сперва поставим OpenZeppelin:

npm install zeppelin-solidity

Наш контракт будет унаследован от цеппелиновского StandardToken, создадим файл contracts/TutorialToken.sol и заполним его следующим содержимым:


pragma solidity ^0.4.18;

import 'zeppelin-solidity/contracts/token/StandardToken.sol';

contract TutorialToken is StandardToken {
  string public name = 'TutorialToken';
  string public symbol = 'TT';
  uint public decimals = 2;
  uint public INITIAL_SUPPLY = 12000;

  function TutorialToken() {
    totalSupply = INITIAL_SUPPLY;
    balances[msg.sender] = INITIAL_SUPPLY;
  }
}

Теперь следует создать скрипт миграции migrations/2_deploy_contracts.js:


var TutorialToken = artifacts.require("TutorialToken");

module.exports = function(deployer) {
  deployer.deploy(TutorialToken);
};

Конечно наш токен никаких методов оригинального StandardToken не переписывает, а следовательно ошибок в себе содержать не должен и цеппелиновским тестам мы можем доверять, мы все равно напишем пару тестов. Truffle поддерживает как тесты на Javascript, так и на Solidity, однако последний довольно убог (в силу своего предназначения), так что лучше сразу на первом. Создадим файл tests/tutorial_token.js:


var TutorialToken = artifacts.require("TutorialToken");

contract('TutorialToken', function(accounts) {
  let owner = accounts[0];
  let second_account = accounts[1];
  let token;

  beforeEach(async function() {
    token = await TutorialToken.deployed();
  });

  it('should return the correct totalSupply after construction', async function() {
    let totalSupply = await token.totalSupply();

    assert.equal(totalSupply, 12000);
  });

  it('transfer updates balance of counterparties', async function() {
    await token.transfer(second_account, 100);
    let owner_balance = await token.balanceOf(owner);
    let second_account_balance = await token.balanceOf(second_account);

    assert.equal(owner_balance, 12000 - 100);
    assert.equal(second_account_balance, 100);
  });
});

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

truffle test

За фасадом трюфель сам запустит testrpc, задеплоит контракт и прогонит тесты. И вот наш собственный токен с блекджеком и тестами готов, можно деплоить в основную сеть и собирать бабло.

По теме

Комментарии закрыты.