Статьи

Ethereum Hello World Пример использования Solc и Web3

Я пытался найти пример 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
let provider = new Web3.providers.HttpProvider("http://localhost:8545");
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, являются их собственными.