Web3.jsを使ってみる

#はじめに
EthereumのDapp開発をしているとよくweb3.jsに遭遇します。
今回はweb3.jsのインストールからよく使うメソッドの実行方法までを備忘録として残しておこうと思います。


#環境構築
まずNode.jsとnpmをインストールし、その後npmを使用しweb3をインストールします。

```bash
$ apt list --upgradable && apt install -y nodejs npm
$ npm init -f && npm install web3
```
無事インストール出来たか確認してみます。

```bash
$ node --version
> v10.19.0
$ npm --version
> 6.14.4
```
バージョン情報が返ってきたのでインストール出来ているようです。
ubuntuだとnpmが入らない場合があるようですが、僕の環境ではこれで大丈夫でした。



#jsファイルを作成する。
それでは早速jsファイルを作成し実行してみます。(ここではtest_web3.jsを作成)
予めgethを起動しHTTP-RPCを有効にしておくのをお忘れなく。

``` test_web3.js
// web3パッケージをインポートし、web3インスタンスを作成する。
const Web3 = require('web3');
const web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545"));
```
これでweb3.jsを扱えるようになります。

nodeコマンドを使えばターミナルでNode.jsを実行することができます。

```bash
$ node test_web3.js
```

#基本的な使い方
[公式Document](https://web3js.readthedocs.io/en/v1.4.0/)を参考によく使うコマンドを試してみます。

* アカウントのアドレスを取得してみる。

``` test_web3.js
// アカウントアドレスを取得する
web3.eth.getAccounts((error, result) => {
    console.log('result: ', result);
});
> result:  [ '0x6Ec9EBcCbF29b2F76F31bfe66f68DFe8Ef21460B',
  '0x11AB501bFf327830937343E5Ed0B7C6A7A097DAe' ]

// これでも可
web3.eth.getAccounts().then(console.log);
```


* ブロック数を取得してみる。

``` test_web3.js
// ブロック数を取得する
web3.eth.getBlockNumber((error, result) => {
    console.log(result);
});
> result:  65
```

* アカウントの保持しているether残高を取得してみる。

``` test_web3.js
// アカウントの残高を取得する(アドレスを直接入力)
web3.eth.getBalance("0x6Ec9EBcCbF29b2F76F31bfe66f68DFe8Ef21460B").then(console.log);
> 130000000000000000000

// アドレスを取得して残高を取得する
web3.eth.getAccounts((error, result) => {
    console.log('result: ', result);
    web3.eth.getBalance(result[1], 'latest', (error, response) => {
        console.log('response: ', response);
    });
});
> result:  [ '0x6Ec9EBcCbF29b2F76F31bfe66f68DFe8Ef21460B',
      '0x11AB501bFf327830937343E5Ed0B7C6A7A097DAe' ]
  response:  0
```

* 別アカウントへetherを送金してみる。

``` test_web3.js
// 別のアカウントへetherを送る
web3.eth.getAccounts((error, result) => {
    console.log('result: ', result);
    web3.eth.sendTransaction({
        'from': result[0],
        'to': result[1],
        'value': '4000000000000000000'
    }, (error, response) => {
        console.log('response: ', response);
        console.log('error: ', error);
   });
});
> result:  [ '0x6Ec9EBcCbF29b2F76F31bfe66f68DFe8Ef21460B',
      '0x11AB501bFf327830937343E5Ed0B7C6A7A097DAe' ]
  response: 0x462e556f3baeed8e316c09fe473056c19aa7e8e4d82cce0c440163b3f2bf7f90
  error:  null
```
トランザクションハッシュの値が返ってきています。

* トランザクション情報を取得してみる。

```test_web3.js
// トランザクション情報を取得する
web3.eth.getTransaction("0x462e556f3baeed8e316c09fe473056c19aa7e8e4d82cce0c440163b3f2bf7f90").
	then(console.log);
> { blockHash:'0x2415380700007105fd0c8bb7bd36b280ce54081ab3ccb35d0bc901aa0435e3dd',
    blockNumber: 81,
    from: '0x6Ec9EBcCbF29b2F76F31bfe66f68DFe8Ef21460B',
    gas: 21000,
    gasPrice: '1000000000',
    hash:'0x462e556f3baeed8e316c09fe473056c19aa7e8e4d82cce0c440163b3f2bf7f90',
    input: '0x',
    nonce: 2,
    to: '0x11AB501bFf327830937343E5Ed0B7C6A7A097DAe',
    transactionIndex: 0,
    value: '4000000000000000000',
    type: 0,
    v: '0x4c',
    r:'0x49fef050cbe91cf8fc2322c362fa0b362cbb745535bcbad80981166866cf0b82',
    s:'0x50c71396934d06c8fad49f9e9a78b1dc6a7982198d8241523edcf6fa4734a93b' }
```
ちゃんとvalueに値が入っています。

* gethを起動しminer.start()でマイニングを実行し、マイニング実行中か確認してみる。

``` test_web3.js
// マイニングを実行中か確認する
web3.eth.isMining().then(console.log);
> true
```

#おわりに
今まであまりNode.jsを使用する機会が無かったのですが使ってみると便利ですね。
今回ethereumでweb3.jsライブラリを使用する際に非同期処理が多いことが分かったので、Promiseやasync,awaitの使い方も勉強していこうと思います。


#参考サイト
[web3.js - Ethereum JavaScript API](https://web3js.readthedocs.io/en/v1.4.0/)