1
0

More than 1 year has passed since last update.

イーサリアム開発環境(Geth)を構築して送金処理を行うまで

Last updated at Posted at 2022-12-05

ブロックチェーンを自分でも動かしてみたかったので、イーサリアムの環境を構築して、送金処理まで実施してみました。
コマンドラインベースで実行してみたかったので、今回はGethを利用します。

環境

MacBook Air M1 2020
メモリ16GB
macOS 13.0

Gethインストール

事前にHomebrewをセットアップしてください。
Gethをインストールする為に以下コマンドを実行してください。

$ brew tap ethereum/ethereum
$ brew install ethereum

準備

任意の場所に作業用フォルダを作成します。私は以下の通り作成しました。

$ mkdir ~/projects/ethereum/
$ mkdir ~/projects/ethereum/node1
$ cd ~/projects/ethereum/

ブロックチェーンのGenesisブロック(最初のブロック)を作成します。
genesis.jsonを以下の通り作成します。

{
  "config": {
    "chainId": 100,
    "homesteadBlock": 0,
    "eip150Block": 0,
    "eip155Block": 0,
    "eip158Block": 0,
    "byzantiumBlock": 0,
    "constantinopleBlock": 0,
    "petersburgBlock": 0,
    "istanbulBlock": 0,
    "berlinBlock": 0,
    "londonBlock": 0
  },
  "alloc": {},
  "coinbase": "0x0000000000000000000000000000000000000000",
  "difficulty": "0x20000",
  "extraData": "",
  "gasLimit": "0x2fefd8",
  "nonce": "0x0000000000000042",
  "mixhash": "0x0000000000000000000000000000000000000000000000000000000000000000",
  "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
  "timestamp": "0x00"
}

chainIdには任意のIDを指定することができますが、以下は予約されているため避けた方が良いと思います。今回は100を指定しました。
1, 2, 3, 4, 5, 42, 1337
allocにユーザ(アドレス)を指定すると、最初にETHを割り当てできるようです。今回はGenesisブロックを作成した後にユーザを作成するので指定していません。

Geth初期化

イーサリアムノードを作成します。
以下コマンドを実行します。

$ geth --datadir ~/projects/ethereum/node1 init ~/projects/ethereum/genesis.json
INFO [12-04|18:18:51.854] Maximum peer count                       ETH=50 LES=0 total=50
(省略)
INFO [11-09|19:24:48.796] Successfully wrote genesis state         database=lightchaindata hash=d118bd..7a409f

node1フォルダが生成され、その下にはgethとkeystoreフォルダが生成されます。

Geth起動

Gethを起動します。
以下コマンドを実行します。

$ geth --networkid 100 --nodiscover --maxpeers 0 --datadir ~/projects/ethereum/node1 console 2>> ~/projects/ethereum/node1/geth.log
Welcome to the Geth JavaScript console!
(省略)
To exit, press ctrl-d or type exit
>

Genesisブロックが生成されているか確認します。
以下コマンドを実行します。

> eth.getBlock(0)
{
  baseFeePerGas: 1000000000,
  difficulty: 131072,
  extraData: "0x",
  gasLimit: 3141592,
  gasUsed: 0,
  hash: "0xd118bd9c6cdf4be6844c7af2b5d86e0d23e91cbe46955c0c23a61dfa577a409f",
  logsBloom: "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
  miner: "0x0000000000000000000000000000000000000000",
  mixHash: "0x0000000000000000000000000000000000000000000000000000000000000000",
  nonce: "0x0000000000000042",
  number: 0,
  parentHash: "0x0000000000000000000000000000000000000000000000000000000000000000",
  receiptsRoot: "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
  sha3Uncles: "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
  size: 512,
  stateRoot: "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
  timestamp: 0,
  totalDifficulty: 131072,
  transactions: [],
  transactionsRoot: "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
  uncles: []
}

アカウントの作成

Etherの採掘や送金処理を行うにはアカウントの作成が必要になります。
今回は2つアカウントを作成します。
以下コマンドを実行します。引数はパスワードになります。

> personal.newAccount("pass0")
"0xf53ac86545559b81188c48ecfd89183e74a05ba5"
> personal.newAccount("pass1")
"0x3732e0d588244ea6d233e41b0e3facfda0010627"

作成したアカウントを確認します。

> eth.accounts
["0xf53ac86545559b81188c48ecfd89183e74a05ba5", "0x3732e0d588244ea6d233e41b0e3facfda0010627"]

アカウントの残高を確認します。どちらも0のはずです。

> eth.getBalance(eth.accounts[0])
0
> eth.getBalance(eth.accounts[1])
0

マイニングを行う

マイニング成功時に報酬を受け取るアカウントを確認します。
このアカウントはEtherbaseと呼ばれます。
最初に作ったアカウントが表示されるはずです。

> eth.coinbase
"0xf53ac86545559b81188c48ecfd89183e74a05ba5"

マイニングを開始します。

> miner.start(1)
null

少し待ってからブロック数が増えていることを確認します。

> eth.mining
true
> eth.blockNumber
3

ブロック数が増えていたら一旦マイニングを止めます。

> miner.stop()
null

先ほどGenesisブロック(最初のブロック)が作成されていることを確認しました。今度は2番目のブロックを確認してみます。

> eth.getBlock(1)
{
  baseFeePerGas: 875000000,
  difficulty: 131072,
  extraData: "0xd983010a1a846765746888676f312e31392e338664617277696e",
  gasLimit: 3144658,
  gasUsed: 0,
  hash: "0x5e52e90aedaf2aae18a13952aa574f3005b3e523e4c1740f3d1ce2a45f2b59e8",
  logsBloom: "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
  miner: "0xf53ac86545559b81188c48ecfd89183e74a05ba5",
  mixHash: "0x26642ebcc7510e2539394d6f14e7c98609251b7e2da01c4109f1453df389eb27",
  nonce: "0x2b5b574a136d247e",
  number: 1,
  parentHash: "0xd118bd9c6cdf4be6844c7af2b5d86e0d23e91cbe46955c0c23a61dfa577a409f",
  receiptsRoot: "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
  sha3Uncles: "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
  size: 542,
  stateRoot: "0xeab84264a580d4d66d1353c60d39ddbda0a6ef5be87c8f04ed761f4c35e8b964",
  timestamp: 1670146603,
  totalDifficulty: 262144,
  transactions: [],
  transactionsRoot: "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
  uncles: []
}

ブロックチェーンなので、parentHashの値とGenesisブロックのhashの値が同じはずです。

マイニングを行ったのでアカウントの残高を確認します。
Etherbaseがマイニングの報酬を受け取っているはずです。

> eth.getBalance(eth.accounts[0])
12000000000000000000
> eth.getBalance(eth.accounts[1])
0

Etherの送金

受け取った報酬をもう一つのアカウントに送金してみます。
送信元アカウントをアンロックします。(300秒間だけEtherの送金が可能になります)
コマンド実行時にアカウントのパスワードを求められます。

> personal.unlockAccount(eth.accounts[0])
Unlock account 0xf53ac86545559b81188c48ecfd89183e74a05ba5
Passphrase: 
true

accounts[0]からaccounts[1]に10ether送金します。
戻り値はトランザクションのhash値です。

> eth.sendTransaction({from: eth.accounts[0], to: eth.accounts[1], value: web3.toWei(10, "ether")})
"0xb7f3394596a2baab10f279442bdc8eaf4a2f43675665159aa5eb54e56ef9062a"

この時点ではトランザクションはまだ処理されていません。
未処理のトランザクションを確認します。

> eth.pendingTransactions
[{
    accessList: [],
    blockHash: null,
    blockNumber: null,
    chainId: "0x64",
    from: "0xf53ac86545559b81188c48ecfd89183e74a05ba5",
    gas: 21000,
    gasPrice: 1897590638,
    hash: "0xb7f3394596a2baab10f279442bdc8eaf4a2f43675665159aa5eb54e56ef9062a",
    input: "0x",
    maxFeePerGas: 1897590638,
    maxPriorityFeePerGas: 1000000000,
    nonce: 0,
    r: "0xb02fc9f6bd98a3d73e43513b2c55bf9ee2c1d951969c08f56c322f626fd97d65",
    s: "0x638d333999a15494c8d8acffba732641ec4dc1cf15db068feff79368f234a5da",
    to: "0x3732e0d588244ea6d233e41b0e3facfda0010627",
    transactionIndex: null,
    type: "0x2",
    v: "0x0",
    value: 10000000000000000000
}]

送金実行時の戻り値とhashが同じはずです。

このトランザクションをブロックチェーンに書き込みます。
マイニングを開始して、トランザクションを処理されたら(未処理のトランザクションが無くなる)、マイニングを止めます。

> miner.start(1)
null
> eth.pendingTransactions
[]
> miner.stop()
null

送金結果を確認する為に、アカウントの残高を確認します。

> eth.getBalance(eth.accounts[0])
23999991753385995000
> eth.getBalance(eth.accounts[1])
10000000000000000000

送金処理のトランザクションを確認します。
引数のトランザクションのhashを指定します。

> eth.getTransaction("0xb7f3394596a2baab10f279442bdc8eaf4a2f43675665159aa5eb54e56ef9062a")
{
  accessList: [],
  blockHash: "0x5fb6ce98cfa6aab051de0faf81b4d53ae4e32426a8c0928d4c1a1ce791124cb8",
  blockNumber: 7,
  chainId: "0x64",
  from: "0xf53ac86545559b81188c48ecfd89183e74a05ba5",
  gas: 21000,
  gasPrice: 1392695905,
  hash: "0xb7f3394596a2baab10f279442bdc8eaf4a2f43675665159aa5eb54e56ef9062a",
  input: "0x",
  maxFeePerGas: 1897590638,
  maxPriorityFeePerGas: 1000000000,
  nonce: 0,
  r: "0xb02fc9f6bd98a3d73e43513b2c55bf9ee2c1d951969c08f56c322f626fd97d65",
  s: "0x638d333999a15494c8d8acffba732641ec4dc1cf15db068feff79368f234a5da",
  to: "0x3732e0d588244ea6d233e41b0e3facfda0010627",
  transactionIndex: 0,
  type: "0x2",
  v: "0x0",
  value: 10000000000000000000
}

7番目のブロックにトランザクションが書き込まれました。
念の為、7番目のブロックも確認してみます。

> eth.getBlock(7)
{
  baseFeePerGas: 392695905,
  difficulty: 131072,
  extraData: "0xd983010a1a846765746888676f312e31392e338664617277696e",
  gasLimit: 3163117,
  gasUsed: 21000,
  hash: "0x5fb6ce98cfa6aab051de0faf81b4d53ae4e32426a8c0928d4c1a1ce791124cb8",
  logsBloom: "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
  miner: "0xf53ac86545559b81188c48ecfd89183e74a05ba5",
  mixHash: "0xfce094b0ed426ef4d2a444a6393abc72f6c3d59f65a7e1cea2822f3339081943",
  nonce: "0x2130afc1acf78b8b",
  number: 7,
  parentHash: "0xec7af5f1bcf59844f13f100341135bea3f09d448e86661cbd19c520c275bf9cc",
  receiptsRoot: "0xf78dfb743fbd92ade140711c8bbc542b5e307f0ab7984eff35d751969fe57efa",
  sha3Uncles: "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
  size: 664,
  stateRoot: "0x9e23b2f61c6a9fe7473c13e4f34757d695155e67cd71b28a352de04b969252a9",
  timestamp: 1670147647,
  totalDifficulty: 1049536,
  transactions: ["0xb7f3394596a2baab10f279442bdc8eaf4a2f43675665159aa5eb54e56ef9062a"],
  transactionsRoot: "0x1210d01d8d3e48286c3e6a7f3d4ee8db81222411595e6dae53378109300034cd",
  uncles: []
}

送金トランザクションのblockHashとブロック(7)のhashが同じであることが確認できました。
また、ブロック(7)のtransactionsに送金トランザクションのhashが書き込まれています。

参考サイト

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0