Я пытался найти пример Ethereum Hello World и наткнулся на отличный пост Томаса Конте, который показывает, как скомпилировать и развернуть умный контракт Ethereum с использованием solc и web3 .
В последней версии web3 API изменился и теперь основан на обещаниях, поэтому я решил перевести пример Томаса.
Давайте начнем.
Установите библиотеки npm
Нам нужно установить эти библиотеки, прежде чем мы начнем:
1
2
3
|
npm install web3 npm install abi-decoder npm 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 20000 EthereumJS 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
|
0xefeaE7B180c7Af4Dfd23207422071599c7dfd2f7 0x3a54BaAFDe6747531a28491FDD2F36Cb61c83663 0x367e1ac67b9a85E438C7fab7648964E5ed12061e 0xB34ECD20Be6eC99e8e9fAF641A343BAc826FFFf1 0xE65587a2951873efE3325793D5729Ef91b15d5b5 0xdA232aEe954a31179E2F5b40E6efbEa27bB89c87 0x7119fEbab069d440747589b0f1fCDDBAdBDd105d 0xCacB2b61dE0Ca12Fd6FECe230d2f956c8Cdfed34 0x4F33BF93612D1B89C8C8872D4Af30Fa2A9CbfaAf 0xA1Ebc0D19dB41A96B5278720F47C2B6Ab2506ccF |
Перевод денег между счетами
Теперь, когда у нас есть несколько аккаунтов, давайте переведем немного денег между ними.
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 : 999990 0xEb25dbD0931386eEaB267981626AE3908D598404 : 10 0x7deB2487E6Ac40f85fB8f5A3bC6896391bf2570F : 0 0xA15ad4371B62afECE5a7A70457F82A30530630a3 : 0 0x64644f3B6B95e81A385c8114DF81663C39084C6a : 0 0xBB68FF2935080c807D5A534b1fc481Aa3fafF1C0 : 0 0x38d4A3d635B451Cb006d63ce542950C067D47F58 : 0 0x7878bA9138361A08522418BD1c8376Af7220a506 : 0 0xf400c0e749Fe02E7073E08d713E0A207dc91FBeb : 0 0x7070d1712a25eb7FCf78A549F17705AA66B0aD47 : 0 |
Этот код:
- Развертывает наш умный контракт в блокчейне
- Переводит £ 10 со счета 1 на счет 2
- Декодирует эту транзакцию и показывает результат
- Показать остатки всех фиктивных счетов
Полный пример доступен в моем репозитории GitHub из ethereum-питомника . У Томаса также есть пост, который показывает, как развернуть контракт на удаленном узле, где подписи на стороне клиента становятся необходимыми.
Опубликовано на Java Code Geeks с разрешения Марка Нидхэма, партнера нашей программы JCG . Смотрите оригинальную статью здесь: Ethereum Hello World Пример использования solc и web3
Мнения, высказанные участниками Java Code Geeks, являются их собственными. |