Я пытался найти пример Ethereum Hello World и наткнулся на отличный пост Томаса Конте, который показывает, как скомпилировать и развернуть умный контракт Ethereum с использованием solc и web3 .
В последней версии web3 API изменился и теперь основан на обещаниях, поэтому я решил перевести пример Томаса.
Давайте начнем.
Установите библиотеки npm
Нам нужно установить эти библиотеки, прежде чем мы начнем:
|
1
2
3
|
npm install web3npm install abi-decodernpm install ethereumjs-testrpc |
Что делают эти библиотеки?
- web3 — клиентская библиотека для взаимодействия с блокчейном Ethereum
- abi-decoder используется для декодирования хэша смарт-контракта, чтобы мы могли выяснить, что в нем было.
- ethereum-testrpc позволяет нам раскрутить локальную тестовую версию Ethereum
Умный контракт
Мы по-прежнему будем использовать тот же умный контракт, что и Томас. Token.sol — это умный контракт, написанный на языке Solidity, который описывает перевод денег между адресами:
контракты / Token.sol
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
|
pragma solidity ^0.4.0; contract Token { mapping (address => uint) public balances; function Token() { balances[msg.sender] = 1000000; } function transfer(address _to, uint _amount) { if (balances[msg.sender] < _amount) { throw; } balances[msg.sender] -= _amount; balances[_to] += _amount; }} |
Всякий раз, когда кто-то пытается перевести деньги, мы помещаем 1 000 000 на их счет, а затем переводим соответствующую сумму, предполагая, что на счете достаточно денег.
Запустить локальный узел Ethereum
Давайте начнем локальный узел Ethereum. Мы снизим цену на газ — сумму, которую вы «платите» за выполнение транзакции, — чтобы мы не закончили.
|
1
2
3
4
|
$ ./node_modules/.bin/testrpc --gasPrice 20000EthereumJS TestRPC v6.0.3 (ganache-core: 2.0.2) Listening on localhost:8545 |
Предварительные условия
Нам нужно загрузить несколько модулей Node.js:
|
1
2
3
4
|
const fs = require("fs"), abiDecoder = require('abi-decoder'), Web3 = require('web3'), solc = require('solc'); |
Составить умный договор
Далее мы составим наш умный контракт:
|
1
2
3
4
|
const input = fs.readFileSync('contracts/Token.sol');const output = solc.compile(input.toString(), 1);const bytecode = output.contracts[':Token'].bytecode;const abi = JSON.parse(output.contracts[':Token'].interface); |
Подключитесь к Ethereum и создайте объект договора
Теперь, когда у нас есть ABI (Application Binary Interface), мы подключимся к нашему локальному узлу Ethereum и создадим объект контракта на основе ABI:
|
1
2
3
|
const web3 = new Web3(provider);let Voting = new web3.eth.Contract(abi); |
Добавить ABI в декодер
Прежде чем мы будем взаимодействовать с блокчейном, мы сначала добавим ABI в наш ABI-декодер для использования позже:
|
1
|
abiDecoder.addABI(abi); |
Найти (фиктивные) учетные записи Ethereum
Теперь мы готовы создать несколько транзакций! Нам понадобятся некоторые учетные записи Ethereum, и если мы вызовем web3.eth.getAccounts, мы сможем получить коллекцию учетных записей, которыми управляет узел. Поскольку наш узел является тестовым, это все фиктивные учетные записи.
|
1
2
3
4
5
|
web3.eth.getAccounts().then(accounts => { accounts.forEach(account => { console.log(account) })}); |
|
01
02
03
04
05
06
07
08
09
10
|
0xefeaE7B180c7Af4Dfd23207422071599c7dfd2f70x3a54BaAFDe6747531a28491FDD2F36Cb61c836630x367e1ac67b9a85E438C7fab7648964E5ed12061e0xB34ECD20Be6eC99e8e9fAF641A343BAc826FFFf10xE65587a2951873efE3325793D5729Ef91b15d5b50xdA232aEe954a31179E2F5b40E6efbEa27bB89c870x7119fEbab069d440747589b0f1fCDDBAdBDd105d0xCacB2b61dE0Ca12Fd6FECe230d2f956c8Cdfed340x4F33BF93612D1B89C8C8872D4Af30Fa2A9CbfaAf0xA1Ebc0D19dB41A96B5278720F47C2B6Ab2506ccF |
Перевод денег между счетами
Теперь, когда у нас есть несколько аккаунтов, давайте переведем немного денег между ними.
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
var allAccounts;web3.eth.getAccounts().then(accounts => { allAccounts = accounts; Voting.deploy({data: bytecode}).send({ from: accounts[0], gas: 1500000, gasPrice: '30000000000000' }).on('receipt', receipt => { Voting.options.address = receipt.contractAddress; Voting.methods.transfer(accounts[1], 10).send({from: accounts[0]}).then(transaction => { console.log("Transfer lodged. Transaction ID: " + transaction.transactionHash); let blockHash = transaction.blockHash return web3.eth.getBlock(blockHash, true); }).then(block => { block.transactions.forEach(transaction => { console.log(abiDecoder.decodeMethod(transaction.input)); }); allAccounts.forEach(account => { Voting.methods.balances(account).call({from: allAccounts[0]}).then(amount => { console.log(account + ": " + amount); }); }); }); });}); |
Давайте запустим:
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
|
Transfer lodged. Transaction ID: 0x699cbe40121d6c2da7b36a107cd5f28b35a71aff2a0d584f8e734b10f4c49de4 { name: 'transfer', params: [ { name: '_to', value: '0xeb25dbd0931386eeab267981626ae3908d598404', type: 'address' }, { name: '_amount', value: '10', type: 'uint256' } ] } 0x084181d6fDe8bA802Ee85396aB1d25Ddf1d7D061: 9999900xEb25dbD0931386eEaB267981626AE3908D598404: 100x7deB2487E6Ac40f85fB8f5A3bC6896391bf2570F: 00xA15ad4371B62afECE5a7A70457F82A30530630a3: 00x64644f3B6B95e81A385c8114DF81663C39084C6a: 00xBB68FF2935080c807D5A534b1fc481Aa3fafF1C0: 00x38d4A3d635B451Cb006d63ce542950C067D47F58: 00x7878bA9138361A08522418BD1c8376Af7220a506: 00xf400c0e749Fe02E7073E08d713E0A207dc91FBeb: 00x7070d1712a25eb7FCf78A549F17705AA66B0aD47: 0 |
Этот код:
- Развертывает наш умный контракт в блокчейне
- Переводит £ 10 со счета 1 на счет 2
- Декодирует эту транзакцию и показывает результат
- Показать остатки всех фиктивных счетов
Полный пример доступен в моем репозитории GitHub из ethereum-питомника . У Томаса также есть пост, который показывает, как развернуть контракт на удаленном узле, где подписи на стороне клиента становятся необходимыми.
| Опубликовано на Java Code Geeks с разрешения Марка Нидхэма, партнера нашей программы JCG . Смотрите оригинальную статью здесь: Ethereum Hello World Пример использования solc и web3
Мнения, высказанные участниками Java Code Geeks, являются их собственными. |