Фреймовк Truffle дает нам комплекс инструментов, которые позволяют упростить разработку, тестирование и деплой смарт-контрактов в Блокчейн. Давайте рассмотрим их подробнее.
- Для каких блокчейнов предназначен Truffle?
- Что позволяет делать Truffle?
- Установка Truffle
- Создание нового проекта Truffle
- Инициализация нового проекта из боксов
- Инициализация чистого нового проекта
- Структура проекта
- Конфигурация проекта
- Настройка конфигурации подключения к блокченам
- Настройка конфигурации компилятора
- Выбор и запуск локального блокчейна
- Работа с Truffle Develop
- Работа с Ganache
- Создание артефактов проекта
- Создание нового файла смарт-контракта
- Созадние нового файла теста для смарт-контракта
- Компиляция файлов в Truffle
- Подготовка и миграция смарт-контактов в Truffle
- Подготовка скриптов миграции
- Настройка конфигурации соединения с блокчейном
- Написание и запуск автотестов для смарт-контрактов
- Создание автотестов
- Запуск автотестов
- Интерактивное взаимодействие с контрактом
- Инициализация смарт-контракта и получение списка доступных адресов
- Проверка баланса монет нашего контракта на аккаунте
- Проверка баланса Эфира на аккаунте
- Перевод наших монет с одного аккаунта на другой
- Проверка количества монет контракта на балансе отправителя
- Проверка количества монет контракта на балансе получателя
- Получить ABI интерфейс контракта
- Просмотр лога транзакции
- Создать новый экземпляр контракта
- Использовать контракт по указанному адресу
- Отправка эфира на контракт
- Работа с цифрами
- Работа с датами
Для каких блокчейнов предназначен Truffle?
Truffle можно использовать для любых блокчейнов использующих Ethereum Virtual Machine (EVM) в качестве среды исполнения смарт-контрактов. В первую очередь это конечно же блокчейн Ethereum. Но как вы знаете, многие блокчейны были созданы на базе самого блокчейна Ethereum, либо были образованы путем форка Ethereum, либо взяли его код за основу для создания своих блокчейнов. Вам однозначно подойдет Truffle если выбранный вами блокчейн для разработки использует Solidity на базе EVM.
Что позволяет делать Truffle?
Вот основные достоинства Truffle, которые помогут вам быстро разрабатывать смарт-контракты:
- Компиляция и автоматическое тестирование смарт-контрактов.
- Миграции и деплой смарт-контрактов в различные блокчены, конфигурация которых определяется настройками вашего проекта.
- Возможность управления при помощи пакетных менеджеров EthPM и NPM по стандарту ERC190.
- Интерактивная консоль для взаимодействия с развернутым смарт-контрактом.
- Настариваемый сборщик pipeline с поддержкой тесной интеграции.
- Возможность запускать и управлять Truffle внешними скриптами.
Установка Truffle
Установка производится из менеджера пакетов NPM командой.
npm install -g truffle
Предварительные требования:
- NodeJS v8.9.4 or later
- Windows, Linux or Mac OS X
Создание нового проекта Truffle
Большинство Truffle команд вам нужно запускать находясь в директории проекта. Создадим директорию под под проект с названием MetaCoin и перейдем в нее.
mkdir MetaCoin cd MetaCoin
Инициализация нового проекта из боксов
В Truffle есть предустановленные шаблоны использующие различный стек технологий, на базе которого вы можете создавать ваш проект. Их называют боаксами (от “boxes”) и найти их можно здесь. Таким образом вы можете взять за основу готовый бокс и на базе него реализовать свое решение. Для инициализации проекта из бокса, выполните команду, где вместо <box-name> укажите название выбранного вами бокса.
truffle unbox <box-name>
Инициализация чистого нового проекта
Если же вам нужен чистый проект, вы можете инициализировать его командой.
truffle init
Структура проекта
В результате инициализации вы получите готовую структуру проекта, которая включает:
contracts/
: Директория для смарт-контрактовmigrations/
: Директория для скриптов миграцийtest/
: Директория для скриптов автотестовtruffle-config.js
: Конфигурация проекта Truffle
Конфигурация проекта
Конфигурация проекта находится в корневом файле truffle-config.js
и включает в себя настройки соединения с нодами блокчейна и информацию о компиляторе.
Настройка конфигурации подключения к блокченам
Как правило проект с момента разработки до деплоя проходит несколько этапов:
- Разработка и локальное тестироавние. Используется локальный блокчейн, конфигурация которого задается в блоке
development
. - Тестирования в публичной сети. Используется одна из публичных тестовых сетей, например, Rinkeby. В этому случае её конфигурацию будете описывать в блоке
rinkeby
. - Деплой проекта в Mainnet. Конфигурацию подключения описываете в блоке
live
.
Пример:
// See <http://truffleframework.com/docs/advanced/configuration> networks: { development: { host: "localhost", port: 8545, // for Ganache use: 7545 network_id: "5777", // for any set: network_id: "*", gas: 6721975 }, rinkeby: { host: "localhost", // Connect to geth on the specified port: 8545, from: "MY_ADDRESS", // default address to use for any transaction Truffle makes during migrations network_id: 4, // rinkeby network id gas: 6712390 // Gas limit used for deploys }, live: { host: "localhost", port: 8545, from: "ACCOUNT_ADDRESS", network_id: 1 } },
Настройка конфигурации компилятора
Далее нужно указать название и версию используемого компилятора.
compilers: { solc: { version: "^0.8.0" } }
Выбор и запуск локального блокчейна
Командой Truffle разработано 2 варианта локального блокчейна:
- Truffle Develop – консольный вариант блокчейна, запускается в отдельном окне терминала командой
truffle develop
. - Ganache – UI вариант оконного приложения нужно устанавливать отдельно, скачать можно здесь либо установить клиенсткую часть из менеджера пакетов командой
npm install -g ganache-cli
.
Работа с Truffle Develop
После исполнения команды truffle develop
, вы увидите в консоли 10 адресов с их приватными ключами, которые можно использовать для тестирования, а также адрес и порт для подключения к данному локальному блокчейну. Все логи операций с блокчейном будут выводиться в консоли.
Truffle Develop started at http://127.0.0.1:9545/ Accounts: (0) 0x627306090abab3a6e1400e9345bc60c78a8bef57 (1) 0xf17f52151ebef6c7334fad080c5704d77216b732 (2) 0xc5fdf4076b8f3a5357c5e395ab970b5b54098fef (3) 0x821aea9a577a9b44299b9c15c88cf3087f3b5544 (4) 0x0d1d4e623d10f9fba5db95830f7d3839406c6af2 (5) 0x2932b7a2355d6fecc4b5c0b6bd44cc31df247a2e (6) 0x2191ef87e392377ec08e7c08eb105ef5448eced5 (7) 0x0f4f2ac550a1b4e2280d04c21cea7ebd822934b5 (8) 0x6330a553fc93768f612722bb8c2ec78ac90b3bbc (9) 0x5aeda56215b167893e80b4fe645ba6d5bab767de Private Keys: (0) c87509a1c067bbde78beb793e6fa76530b6382a4c0241e5e4a9ec0a0f44dc0d3 (1) ae6ae8e5ccbfb04590405997ee2d52d2b330726137b875053c36d94e974d162f (2) 0dbbe8e4ae425a6d2687f1a7e3ba17bc98c673636790f1b8ad91193c05875ef1 (3) c88b703fb08cbea894b6aeff5a544fb92e78a18e19814cd85da83b71f772aa6c (4) 388c684f0ba1ef5017716adb5d21a053ea8e90277d0868337519f97bede61418 (5) 659cbb0e2411a44db63778987b1e22153c086a95eb6b18bdf89de078917abc63 (6) 82d052c865f5763aad42add438569276c00d3d88a2d062d36b2bae914d58b8c8 (7) aa3680d5d48a8283413f7a108367c7299ca73f553735860a87b08f39395618b7 (8) 0f62d96d6675f32685bbdb8ac13cda7c23436f63efbb9d07700d8669ff12b7c4 (9) 8d5366123cb560bb606379f90a0bfd4769eecc0557f1b362dcae9012b548b1e5 Mnemonic: candy maple cake sugar pudding cream honey rich smooth crumble sweet treat ⚠️ Important ⚠️ : This mnemonic was created for you by Truffle. It is not secure. Ensure you do not use it on production blockchains, or else you risk losing funds. truffle(development)>
Работа с Ganache
После запуска Ganache вы увидете интерфейс на котором будет расположено 10 адресов с эфиром. Их вы можете использовать для тестирования. Кроме этого в окне приложения будет отображаться информация об адресе и порте для подключения и другие артефакты.
Обратите внимание, что порт подключения к Ganache: 7545 отличается от порта подключения к Truffle Develop: 8545. Поэтому в файле конфигурации, в секцииdevelopment
укажите правильныйport
.
Создание артефактов проекта
Файлы в проекте вы можете создавать либо в ручную из редактора кода либо при помощи следующих команд в консоли.
Создание нового файла смарт-контракта
truffle create contract ContractName
Созадние нового файла теста для смарт-контракта
truffle create test ContractName
Компиляция файлов в Truffle
Компиляция файлов осуществляется при помощи команды:
truffle compile
В результате будет сфорированы артефакты, готовые к деплою вашего контракта.
Повторный запуск команды откомпилирует только те файлы, которые были изменены с момента последней компиляции. Чтобы заново откомпилировать все файлы, в том числе те, которые не были изменены, используйте флаг –all:
truffle compile --all
Подготовка и миграция смарт-контактов в Truffle
Миграция это не что иное, как деплой вашего контракта в сеть блокчейна, где он будет развернут. Но прежде чем это сделать, нужно подготовить скрипты для деплоя.
Подготовка скриптов миграции
Вам нужно создать скрипты миграции в директории migrations/
для каждого вашего смарт-контракта. Основная роль такого скрипта, это создать объект из вашего файла смарт-контракта, определить перечень аргументов для конструктора смарт-контракта и задеплоить контракт в выбранную сеть блокчейна.
Пример скрипта деплоя:
const MyContract = artifacts.require("./MyContract.sol"); module.exports = function(deployer, network, accounts) { let minter = "ACCOUNT_ADDRESS_BY_DEFAULT"; if (network == "rinkeby") { minter = "ACCOUNT_ADDRESS_FOR_RINKEBY"; } else if (network == "development") { minter = accounts[1]; } deployer.deploy(MyContract, minter); };
Настройка конфигурации соединения с блокчейном
В файле truffle-config.js
для деплоя на локальный блкочейн нужно сконфигурировать в блоке development
параметры соединения с локальным блокчейном. Для публичных тестовых блокчейнов или для Mainnet, также нужно определить конфигурацию подключения, как описывалось выше.
Если в файле конфигурации truffle-config.js
у вас заданы настройки только для одной сети, то деплой в нее вы можете выполнить командой.
truffle migrate
Если же в файле truffle-config.js
у вас заданы настройки к двум или большему количеству сетей, то для деплоя нужно явно указать, какую конфигурацию сети использовать вместо <network-name>.
truffle migrate --network <network-name>
Написание и запуск автотестов для смарт-контрактов
Автотесты для смарт-контрактов создаются либо на языке JavaScript либо на Solidity. Причем на Solidity обычно создаются автотесты для проверки более сложных сценариев.
Задача автотеста покрыть как можно больше сценариев проверки и при каждом деплое после очередной доработки кода, они будут проганятсья автоматически, провяряя ваши смарт-контракты на возможные ошибки и уязвимости. Учитывая то, что цена ошибки при разработке смарт-контрактов для блокчейна велика, то вам нужно максимально написать автотесты под все возможные и невозможные сценарии, это снизит ваши риски. Поэтмоу, уделите этому большую часть времени при разработке!
Создание автотестов
Автотесты создаются в директории test/
под каждый смарт-контракт. Если вы пишите автотест на JS, то как правило в нем используются встроенные в Truffle фреймвоки Mocha и Chai. Один дает возможность описывать тест-кейс, а второй делать необходимые проверки.
Пример автотеста.
const Web3 = require('web3'); const ERC20Token = artifacts.require("./ERC20Token.sol"); let token; beforeEach(async () => { token = await ERC20Token.deployed(); }); contract('ERC20Token', accounts => { const minter = accounts[1]; it('has a name', async function () { const name = await token.name(); assert.equal(name, 'XYZ Coin'); }); it('has a symbol', async function () { const symbol = await token.symbol(); assert.equal(symbol, 'XYZ'); }); it('has 18 decimals', async function () { const decimals = await token.decimals(); assert.equal(decimals.toNumber(), 18); }); it('has a cap of 100,000,000 tokens', async function () { const cap = await token.cap(); assert.equal(cap.toString(), '100000000000000000000000000'); // cap is 100 million }); it("Should set owner to account[0]", async () => { const owner = await token.owner.call(); assert.equal(owner, accounts[0]); }); it("Should set minter to account[1]", async () => { const minter = await token.minter.call(); assert.equal(minter, accounts[1]); }); });
Запуск автотестов
Следующей командой вы можете осуществить запуск всех автотестов из директории test/
truffle test
Если же вам нужно запустить только определнный автотест, то укажите имя его файла
// запуск JS автотеста truffle test ./test/metacoin.js // запуск Solidity автотеста truffle test ./test/TestMetaCoin.sol
Интерактивное взаимодействие с контрактом
После деплоя контракта, вы можете взаимодействовать с ним через консоль Truffle при помощи JavaScript и фреймвока Web3. Консоль запускается при помощи команды.
truffle console
Но если в вашем конфигурационном файле проекта определено несколько сетей и вы желаете запустить консоль только на определенной, то используйте команду с явным указанием сети блокчейна, вместо <network-name>.
truffle console --network <network-name>
Начиная с Truffle v5, консоль поддерживает функции async/await что упрщает взаимодействие с контрактом.
Инициализация смарт-контракта и получение списка доступных адресов
truffle(development)> let instance = await MetaCoin.deployed() truffle(development)> let accounts = await web3.eth.getAccounts()
Проверка баланса монет нашего контракта на аккаунте
truffle(development)> let balance = await instance.getBalance(accounts[0]) truffle(development)> balance.toNumber()
Проверка баланса Эфира на аккаунте
truffle(development)> let ether = await instance.getBalanceInEth(accounts[0]) truffle(development)> ether.toNumber()
Перевод наших монет с одного аккаунта на другой
truffle(development)> instance.sendCoin(accounts[1], 500)
Проверка количества монет контракта на балансе отправителя
truffle(development)> let received = await instance.getBalance(accounts[1]) truffle(development)> received.toNumber()
Проверка количества монет контракта на балансе получателя
truffle(development)> let newBalance = await instance.getBalance(accounts[0]) truffle(development)> newBalance.toNumber()
Получить ABI интерфейс контракта
JSON.stringify(instance.abi)
Просмотр лога транзакции
truffle(develop)> let result = await instance.sendCoin(accounts[1], 10, {from: accounts[0]})
result.logs[0]
Создать новый экземпляр контракта
truffle(develop)> let newInstance = await MetaCoin.new() truffle(develop)> newInstance.address
Использовать контракт по указанному адресу
let specificInstance = await MetaCoin.at("0x1234...");
Отправка эфира на контракт
instance.send(web3.utils.toWei(1, "ether")).then(function(result) { // Same result object as above. });
Работа с цифрами
web3.toWei(1, 'ether') // out: 1e18 web3.fromWei('500000e18', 'ether') // out: 500000 web3.BigNumber('50000000e18') // 50000000e18
Работа с датами
let startTime = new Date('2017-11-25').getTime() / 1000; startTime = web3.eth.getBlock(web3.eth.blockNumber).timestamp + 1 // one second in the future