Отправка ethereum транзакции через консоль
В данной статье я расскажу как настроить окружение для изучения библиотеки web3.js Статья рассчитана на тех, кто интересуется blockchain и хочет научиться взаимодействовать с сетью Ethereum, она же EVM (Ethereum Virtual Machine), через библиотеку web3.js
После настройки окружения, мы отправим нашу первую транзакцию - перевод криптовалюты с одного аккаунта на другой посредством библиотеки web3, а так же изучим некоторые другие команды. После данного руководства не составит труда поэкспериментировать и с остальными методами библиотеки, ознакомившись с документацией web3 API.
Что нам понадобится?
- Ganache
- Node.js
- JS библиотека truffle
Согласно официальной документации, web3.js это Ethereum JavaScript API, содержащий коллекцию библиотек, позволяющих взаимодействовать с локальными или удалёнными ethereum нодами, посредством HTTP, IPC или WebSocket. В нашем случае мы будем взаимодействовать только с локальной нодой, а все наши транзакции будут происходить внутри нашего компьютера.
Что такое Ganache?
Ganache - это локальная Ethereum блокчейн сеть, состоящая всего из одной ноды. По сравнению с боевыми нодами реальных блокчейн сетей, Ganache занимает очень мало места, так как при старте она не содержит никаких данных, кроме самого первого Genesis блока и 10 тестовых акаунтов, имеющих на своём балансе по 100 ETH. Ganache прекрасно подходит для тестирования Dapp приложений, смарт-контрактов и изучения блокчейн сети Ethereum.
Что такое truffle?
Это библиотека, позволяющая взаимодействовать с EVM - Ethereum Virtual Machine, разрабатывать смарт-контракты, компилировать и деплоить их в EVM, отлаживать их, а так же взаимодействовать с ними через консоль. Библиотека включает в себя библиотеку web3.js.
Итак, приступим.
Установка Ganache
Скачиваем дистрибутив, устанавливаем, запускаем приложение и нажимаем Quickstart
Экран после первого запуска Ganache
После инициализации нашего локального ethereum блокчейна, видим 10 тестовых аккаунтов. Каждый аккаунт имеет баланс по 100 ETHРабочее пространство Ganache с 10-ю аккаунтами
Всё, ethereum блокчейн установлен, теперь настроим консоль при помощи которой мы будем отправлять сообщения нашему блокчейну.Устанавливаем библиотеку truffle через npm
Для этого нам понадобится установленная Node.js v14 - v18. Скачать nodejs можно тут. Затем устанавливаем truffle:
Код:
$ npm install -g truffle
$ truffle version
Вывод:
Если возникли проблемы, то можно посмотреть официальное руководство по установке.Truffle v5.8.1 (core: 5.8.1)
Ganache v7.7.7
Solidity - 0.8.19 (solc-js)
Node v18.12.1
Web3.js v1.8.2
Заходим в truffle console
Теперь пробуем зайти в консоль:
$ truffle console
Мы видим следующее сообщение:
Так произошло, потому что truffle не нашёл файла конфигурации. Но к счастью ничего настраивать нам не нужно, а достаточно создать пустой файл truffle-config.js и truffle применит настройки по-умолчанию.Could not find suitable configuration file.
Truffle v5.8.1 (core: 5.8.1)
Node v18.12.1
Создадим произвольную папку, в ней создадим наш пустой файл настроек и запустим truffle консоль:
Код:
$ mkdir web3-demo
$ cd web3-demo
$ touch truffle-config.js
$ truffle console
$ truffle(ganache)>
Примечание: вместо создания вручную пустого файла truffle-config.js мы могли бы использовать команду
$ truffle init
и тогда truffle создал бы для нас пустой проект с файлом конфигурации и пустыми каталогами:
Окружение после выполнения команды $ truffle init
Данная структура проекта предназначена для разработки smart-контрактов и деплоя их в тестовую сеть Ganache, что не является темой данного топика, поэтому я использовал минимально необходимые настройки.Тестируем доступ к блокчейн сети через консоль
Набираем в открытой ранее truffle консоли:
web3.eth.getAccounts()
Если мы видим вывод представленный ниже, то всё отлично, мы подключились к нашей тестовой локальной блокчейн EVM. В данном случае мы запросили сеть выдать нам все аккаунты, и они идентичны тем, что мы видели в нашем GUI Ganache. Сами аккаунты могут отличаться, так как Ganache при каждом запуске генерирует новые аккаунты.
Код:
[
'0x4DfcE7Fb36c1C95Fd72dE02DB865EfC5c4E72dE8',
'0x968a34AC105aca298209c2dce23A8De721fB3C19',
'0x9a978DaeecA6cdD141c9aDEc7A0AE5F86e48F10d',
'0x2FcF93F05067445886afF6d832d68b8b4E31b0A3',
'0x777C7A81C70B3978a2D2574E2D4939D882f0AA13',
'0xc1a204D8E7e5550C6Cd1c9d2f142F7C3306b0774',
'0x432D3e48DA7FdeAf41933E85C04a401b96bAeefe',
'0x4a47F93Dfe15bA9165C8E6735ffD8D142d238F5c',
'0xA1B19BA4fcC38A86927f4C76e5cEC5Bd027940aC',
'0x47fc50170A8E68D7C6d2855c2d9F1F0412CB5B77'
]
Отправка криптовалюты с одного аккаунта на другой
Для отправки мы воспользуемся следующей командой:
Код:
web3.eth.sendTransaction({
from: "0x4DfcE7Fb36c1C95Fd72dE02DB865EfC5c4E72dE8",
to: "0x968a34AC105aca298209c2dce23A8De721fB3C19",
value: web3.utils.toWei("0.01", "ether")
})
Значения для полей from и to я взял из предыдущего вызова getAccounts(), это соответствует первому и второму адресу в массиве. Вы можете использовать любые другие адреса.
В поле value мы помещаем сумму, которую хотим отправить. В данном случае я поместил вызов функции, которая сконвертирует значение, выраженное в Ether в значение, выраженное в Wei. Дело в том, что EVM оперирует только значениями выраженными в Wei - это минимальная единица измерения криптовалюты Ethereum. 1 Ether = 10^18 Wei.
Можно прямо сейчас проверить в консоли, какое число бы нам пришлось писать в value, без этой функции:
web3.utils.toWei("0.01", "ether")
Вывод:
Как видим, можно легко запутаться в нулях. Здесь представлены все единицы измерения криптовалюты в Ethereum.'10000000000000000'
Перед запуском транзакции, проверим состояние балансов наших аккаунтов:
Первый аккаунт:
web3.eth.getBalance("0x4DfcE7Fb36c1C95Fd72dE02DB865EfC5c4E72dE8")
Вывод:
Второй аккаунт:'100000000000000000000'
web3.eth.getBalance("0x968a34AC105aca298209c2dce23A8De721fB3C19")
Вывод:
Напомню, что здесь мы видим значение баланса, выраженного в Wei. Можно так же заглянуть в GUI Ganache и убедиться, что всё верно. В GUI баланс отражён в Ether.'100000000000000000000'
Ganache отображает баланс в ETH
Итак, у нас всё готово для запуска транзакции. Запускаем саму транзакцию:web3.eth.sendTransaction({from: "0x4DfcE7Fb36c1C95Fd72dE02DB865EfC5c4E72dE8", to: "0x968a34AC105aca298209c2dce23A8De721fB3C19", value: web3.utils.toWei("0.01", "ether")})
Если всё прошло успешно, то на выходе получаем js-объект. Это так называемый Receipt, или квитанция о совершённой транзакции. В ней содержится такая информация, как хэш транзакции (по нему мы можем найти транзакцию в блокчейне), номер блока в который была записана наша транзакция, хэш блока и другая полезная информация.
Код:
{
transactionHash: '0x0bf4bd25ab2de3b44e6a60ae7187748f85349eb88f7df1d90a6ce1041ebc827d',
transactionIndex: 0,
blockNumber: 1,
blockHash: '0xa54a964d5db58d84b21d9d29ee1972ffd74501d67fd4432c7cbce0dddc01fe83',
from: '0x4dfce7fb36c1c95fd72de02db865efc5c4e72de8',
to: '0x968a34ac105aca298209c2dce23a8de721fb3c19',
cumulativeGasUsed: 21000,
gasUsed: 21000,
contractAddress: null,
logs: [],
logsBloom: '0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000',
status: true,
effectiveGasPrice: 3375000000,
type: '0x2'
}
Аккаунт-отправитель:
web3.eth.getBalance("0x4DfcE7Fb36c1C95Fd72dE02DB865EfC5c4E72dE8")
Вывод:
Аккаунт-получатель:'99989929125000000000'
web3.eth.getBalance("0x968a34AC105aca298209c2dce23A8De721fB3C19")
Вывод:
Как видим, балансы изменились: у получателя прибавилось 0.01 Ether, а у отправителя списалась сумма, чуть большая, чем 0.01 Ether. Дело в том, что с отправителя списалась ещё и комиссия за транзакцию, которая выражается в Gas. Gas это топливо сети Ethereum, или оплата за пользование вычислительными ресурсами.'100010000000000000000'
Данная комиссия вычисляется путём умножения текущей стоимости 1 единицы Gas на то количество единиц Gas, которое потребуется для выполнения нашей транзакции. В реальной сети Ethereum стоимость 1 единицы Gas постоянно меняется. Здесь можно провести параллель с ценами на бензин на АЗС, и стоимостью поездки из пункта А в пункт Б на личном автомобиле. Общая стоимость проезда в данном случае будет складываться из цены за литр бензина и объёма израсходованного топлива.
Проверяем баланс в GUI Ganache:
Изменения балансов после проведения транзакции
Напоследок можно зайти на вкладку Transactions в Ganache, и там увидеть нашу транзакцию.Вкладка транзакций. Транзакции кликабельны
Зайдём внутрь транзакции, кликнув на неё:Информация по конкретной транзакции
Так же можно зайти на вкладку Blocks и увидеть два блока: нулевой был записан при запуске самой сети Ethereum, это так называемый Genesis Block, следующий блок - это и есть тот блок, куда попала наша транзакция:Вкладка блоков. Каждый блок кликабельный
Зайдём внутрь первого блока, куда попала наша транзакция:Информация о первом блоке с нашей транзакцией
Если сравнить квитанцию, которая была получена в консоли, с тем что отражено в GUI, то можно убедиться что информация идентична.На этом всё. Мы настроили окружение и научились отправлять транзакцию через консоль. Для дальнейшего изучения Ethereum, можно воспользоваться официальной документацией к Web3 API.
Например описание получение баланса находится тут. Получить текущую цену на Gas можно этой командой:
web3.eth.getGasPrice()
Вывод:
При дальнейшем изучении, в данной среде можно деплоить и тестировать smart-контракты.'20000000000'
Спасибо за внимание, всем успехов в освоении web3 :)
Благодарность все так же выражаю - wakarimasen