0. Ethereum Private Blockchain

Raspberry Pi 4でEthereumのプライベートネットワークを構築

分散コンピューティングプロジェクトのひとつ、EthereumをRaspberry Pi 4に構築してプライベート取引を学ぶ
https://github.com/ethereum/go-ethereum


1. 検証環境

シングルボードコンピュータ メモリ ストレージ
Raspberry Pi 4 Model B Rev 1.4 8GB microSDHC 32GB CLASS10

2. OS

raspios-buster-arm64-lite
https://downloads.raspberrypi.org/raspios_lite_arm64/images/raspios_lite_arm64-2021-05-28/2021-05-07-raspios-buster-arm64-lite.zip


3. 操作環境

macOS, SSH


4. 書き込み

差し込んだmicroSDHCカードを diskutil list でマウント確認をmacOSのターミナルで行う

$ diskutil list
/dev/disk0 (internal, physical):
   #:                       TYPE  NAME                     SIZE       IDENTIFIER
   0:      GUID_partition_scheme                          *121.3 GB   disk0
   1:                        EFI  EFI                      314.6 MB   disk0s1
   2:                 Apple_APFS  Container disk1          121.0 GB   disk0s2
   
/dev/disk1 (synthesized):
   #:                       TYPE  NAME                     SIZE       IDENTIFIER
   0:      APFS Container Scheme -                        +121.0 GB   disk1
                                  Physical Store disk0s2
   1:                APFS Volume  Macintosh HD - Data      37.7 GB    disk1s1
   2:                APFS Volume  Preboot                  487.3 MB   disk1s2
   3:                APFS Volume  Recovery                 622.9 MB   disk1s3
   4:                APFS Volume  VM                       1.1 GB     disk1s4
   5:                APFS Volume  Macintosh HD             15.3 GB    disk1s5
   6:              APFS Snapshot  com.apple.os.update-...  15.3 GB    disk1s5s1
   
/dev/disk2 (external, physical):
   #:                       TYPE  NAME                     SIZE       IDENTIFIER
   0:     FDisk_partition_scheme                          *31.9 GB    disk2
   1:                 DOS_FAT_32  BOOT                     268.4 MB   disk2s1
   2:                      Linux                           31.6 GB    disk2s2

結果 disk2 と判明

$ diskutil umountDisk /dev/disk2
Unmount of all volumes on disk2 was successful

書き込むイメージファイルが格納されている階層へ移動

$ cd desktop

書き込み

$ sudo dd bs=1m if=2021-05-07-raspios-buster-arm64-lite.img of=/dev/disk2

書き込んだイメージに空の ssh ファイル配置

bcm2710-rpi-2-b.dtb
bcm2710-rpi-3-b-plus.dtb
bcm2710-rpi-3-b.dtb
bcm2710-rpi-cm3.dtb
bcm2711-rpi-4-b.dtb
bcm2711-rpi-400.dtb
bcm2711-rpi-cm4.dtb
bootcode.bin
cmdline.txt
config.txt
COPYING.linux
fixup_cd.dat
fixup_db.dat
fixup_x.dat
fixup.dat
fixup4.dat
fixup4cd.dat
fixup4db.dat
fixup4x.dat
issue.txt
kernel8.img
LICENCE.broadcom
overlays
ssh
start_cd.elf
start_db.elf
start_x.elf
start.elf
start4.elf
start4cd.elf
start4db.elf
start4x.elf

5. SSH接続

Raspberry Pi へ microSDHCカード を差し込みLANケーブルを接続後、電源投入 Raspberry Pi 本体には電源スイッチが無いため、電源コードを接続する事で起動

Raspberry Pi のSSHリモート操作環境は Termius を利用
https://apps.apple.com/jp/app/termius-ssh-client/id1176074088

ホスト名 raspberrypi.local
ユーザー名 pi
パスワード raspberry

6. 古いパッケージ削除

$ sudo su -
# apt-get remove golang autoremove

7. 各種アップデート、必要パッケージインストール、再起動

# apt-get update && apt-get -y upgrade && apt-get -y install git golang libgmp3-dev htop && reboot

SSH接続

ホスト名 raspberrypi.local
ユーザー名 pi
パスワード raspberry

8. golangインストール

$ sudo su -
# wget https://dl.google.com/go/go1.9.2.linux-armv6l.tar.gz
# tar -C /usr/local -xzf go1.9.2.linux-armv6l.tar.gz

9. 環境パス編集

# vi ~/.profile

10行目に export PATH=$PATH:/usr/local/go/bin を追記

# ~/.profile: executed by Bourne-compatible login shells.

if [ "$BASH" ]; then
if [ -f ~/.bashrc ]; then
. ~/.bashrc
fi
fi

mesg n || true
export PATH=$PATH:/usr/local/go/bin

10. myGenesis.json作成

# mkdir private
# cd private
# vi myGenesis.json
{
  "config": {
  "chainId" : 15,
  "homesteadBlock" : 0,
  "eip155Block" : 0,
  "eip158Block" : 0
  },
  "nonce": "0x0000000000000042",
  "timestamp": "0x00",
  "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
  "extraData": "0x00",
  "gasLimit": "0x8000000",
  "difficulty": "0x4000",
  "mixhash": "0x0000000000000000000000000000000000000000000000000000000000000000",
  "coinbase": "0x3333333333333333333333333333333333333333",
  "alloc": {}
}

11. gethのビルドとインストール

# git clone -b release/1.8 https://github.com/ethereum/go-ethereum.git
# cd go-ethereum
# make
# cp build/bin/geth /usr/local/bin/
ブロックチェーン初期化
# geth --datadir /root/private init /root/private/myGenesis.json

12. gethの起動

# geth --networkid "10" --nodiscover --datadir "/root/private" console 2>> /root/private/geth.log
Welcome to the Geth JavaScript console!

instance: Geth/v1.8.27-stable-4bcc0a37/linux-arm64/go1.11.6
modules: admin:1.0 debug:1.0 eth:1.0 ethash:1.0 miner:1.0 net:1.0 personal:1.0 rpc:1.0 txpool:1.0 web3:1.0

> 

13. アカウント作成

> personal.newAccount("qwerty")
"0xc278d7070cd0cfb62c9199dcc988335997e8617e"
> 
> personal.newAccount("ji32k7au4a83")
"0x19e3635b94c457fee194b178d49f246d3c5c417f"

1つ目のアカウントパスワードは qwerty で設定
2つ目のアカウントパスワードは ji32k7au4a83 で設定


14. アカウントアドレス確認

> eth.accounts
["0xc278d7070cd0cfb62c9199dcc988335997e8617e", "0x19e3635b94c457fee194b178d49f246d3c5c417f"]
> 
> eth.accounts[0]
"0xc278d7070cd0cfb62c9199dcc988335997e8617e"
> eth.accounts[1]
"0x19e3635b94c457fee194b178d49f246d3c5c417f"

15. マイニング成功時に報酬を受け取るアカウント確認

> eth.coinbase
"0xc278d7070cd0cfb62c9199dcc988335997e8617e"
補足 報酬を受け取るアカウントを変更するコマンド
> miner.setEtherbase(eth.accounts[1])
true

16. Etherマイニング実行

> miner.start()
null
> eth.mining
true

17. ブロック、ハッシュレート確認

> eth.blockNumber
0
> eth.blockNumber
433
> eth.hashrate
75205
htop htop

18. 残高確認

> eth.getBalance(eth.accounts[0])
2.3e+21
> web3.fromWei(eth.getBalance(eth.accounts[0]), "ether")
2300
> eth.getBalance(eth.accounts[1])
0

19. 送金、トランザクション、残高確認

送金元 eth.accounts[0] のアカウントロック解除
> personal.unlockAccount(eth.accounts[0], "qwerty")
eth.accounts[1] へ 100ETH 送金
> eth.sendTransaction({from: eth.accounts[0], to: eth.accounts[1], value: web3.toWei(100, "ether")})
"0x19e327ab08a759f26094fcc3bc8f6571d8e34336f32dc2655a065ff13e8c2b10"
トランザクション情報確認
> eth.getTransaction("0x19e327ab08a759f26094fcc3bc8f6571d8e34336f32dc2655a065ff13e8c2b10")
{
  blockHash: "0x9956edf75adfa3d4c555be5205d4be0f07ff81a242548ee2764785aafd7cef02",
  blockNumber: 461,
  from: "0xc278d7070cd0cfb62c9199dcc988335997e8617e",
  gas: 90000,
  gasPrice: 1000000000,
  hash: "0x19e327ab08a759f26094fcc3bc8f6571d8e34336f32dc2655a065ff13e8c2b10",
  input: "0x",
  nonce: 0,
  r: "0x474f41a72be303f211ee9196ccb2e444e96165e73f3c1f08273ef4b5dcaa142a",
  s: "0x26307f21924439845e04d05affd51ad0eb88de3f3e2efad5de68163e991b7bf2",
  to: "0x19e3635b94c457fee194b178d49f246d3c5c417f",
  transactionIndex: 0,
  v: "0x42",
  value: 100000000000000000000
}
残高確認
> web3.fromWei(eth.getBalance(eth.accounts[0]), "ether")
2200
> web3.fromWei(eth.getBalance(eth.accounts[1]), "ether")
100
マイニング停止
> miner.stop()
null

戻る