イーサリアムブロックチェーンネットワークの導入と検証実験
記事ディレクトリ
2023年秋学期に行われた国立科学技術大学のコンピュータネットワーク実験。実験の過程を簡単に記録します。
1 Go1.19のインストール
Ubuntu に Go 1.19 バージョンをインストールするには、次の手順を実行します。
1.1 Go 1.19 をダウンロードする
まず、ターミナルを開きます。Go 言語の公式 Web サイトから最新バージョンをダウンロードします。wget
またはコマンドを使用してcurl
、Go 1.19 tarball をダウンロードします。
wget https://dl.google.com/go/go1.19.linux-amd64.tar.gz
ダウンロード リンクが最新であることを確認してください。正しいリンクは、Go 言語の公式ダウンロード ページにあります。
1.2 ファイルを解凍する
ダウンロードが完了したら、ファイルを/usr/local
ディレクトリに解凍します。このディレクトリは通常、ユーザーレベルのソフトウェア インストールを保存するために使用されます。次のコマンドを使用します。
sudo tar -C /usr/local -xzf go1.19.linux-amd64.tar.gz
これにより、 にディレクトリが/usr/local
作成されますgo
。
1.3 環境変数を設定する
Go を使用するには、Go の bin ディレクトリを PATH 環境変数に追加する必要があります。この変数をまたは.profile
ファイルに設定します。ファイルに設定されているコマンドの例.bashrc
は次のとおりです。.profile
echo "export PATH=\$PATH:/usr/local/go/bin" >> ~/.profile
次に、変更を有効にします。
source ~/.profile
または、bash シェルを使用している場合は、.bashrc
ファイルを変更します。
echo "export PATH=\$PATH:/usr/local/go/bin" >> ~/.bashrc
source ~/.bashrc
1.4 インストールの確認
インストールが完了したら、ターミナルを再起動するか、source コマンドを使用して現在のセッションを更新します。次に、次のコマンドを使用して、Go が正しくインストールされていることを確認します。
go version
すべてが正常であれば、次のように Go のバージョン情報が表示されますgo version go1.19 linux/amd64
。
予防:
- 以前に古いバージョンの Go がインストールされている場合は、最初に古いバージョンをアンインストールするか、新しいバージョンへのパスが PATH に正しく追加されていることを確認する必要がある場合があります。
- ダウンロードした Go のバージョンがシステム アーキテクチャ (amd64、arm64 など) と一致していることを確認してください。
インストールが完了したら:
2 geth1.10.25のインストール
Geth バージョン 1.10.25 を Ubuntu にインストールするには、バージョン固有のバイナリをダウンロードするか、ソースからコンパイルします。具体的な手順は次のとおりです。
2.1 方法 1: バイナリ ファイルをダウンロードする
- Geth GitHub リポジトリにアクセスします。
- Go-Ethereum のリリースページを開きます。
- 特定のバージョンをダウンロードします。
- 「リリース」ページで、
1.10.25
「リリース」を見つけます。
- 「リリース」ページで、
- Linux 用のファイルをダウンロードします。通常は
geth-linux-amd64-1.10.25-xxxxxx.tar.gz
という名前の圧縮ファイルです。
-
ファイルを解凍します:
-
コマンドラインを使用して、ダウンロードしたファイルを解凍します。例えば:
tar -xvzf geth-linux-amd64-1.10.25-xxxxxx.tar.gz
-
-
Geth を実行可能ディレクトリに移動します。
-
解凍した
geth
実行可能ファイルを、PATH 環境変数内のディレクトリ ( など) に移動します/usr/local/bin
。sudo mv geth-linux-amd64-1.10.25-xxxxxx/geth /usr/local/bin/
-
-
インストールを確認します。
-
ターミナルで次のコマンドを実行して、インストールを確認します。
geth version
-
2.2 方法 2: ソース コードからコンパイルする
Geth をソースからコンパイルする場合は、次の手順に従います。
-
コンパイルの依存関係をインストールします。
-
build-essential
、git
、およびその他の必要なツールをインストールしますgolang
。sudo apt-get update sudo apt-get install -y build-essential git golang
-
-
ソース コード リポジトリのクローンを作成します。
-
Go-Ethereum リポジトリのクローンを作成します。
git clone https://github.com/ethereum/go-ethereum.git
-
-
特定のバージョンに切り替えます。
-
リポジトリ ディレクトリに入り、
1.10.25
バージョンに切り替えます。cd go-ethereum git checkout v1.10.25
-
-
Geth をコンパイルします。
-
ウェアハウスのルート ディレクトリでコンパイル コマンドを実行します。
make geth
-
-
Geth をインストールします。
-
コンパイルされた
geth
実行可能ファイルを次の場所にコピーします/usr/local/bin
。sudo cp build/bin/geth /usr/local/bin/
-
-
インストールを確認します。
- 実行し
geth version
てインストールを確認します。
- 実行し
予防:
- システムの機能によっては、ソースからコンパイルするのに時間がかかる場合があります。
注: 上記の 2 つの方法では、外部ネットワークへのアクセスが必要です。
(実際には、calsh はライブラリを削除して逃げました。Linux 版の calsh が見つからなかった科学上网
ので、方法 3 を思いつきました)
2.3 方法 3: コンパイル済みバージョンを直接ダウンロードする
コンパイルされたバージョンをオンラインで見つけます。
ダウンロード: https://download.csdn.net/download/yezhijing/86811420
ファイルを解凍します。
tar -xvzf geth-linux-amd64-1.10.25-xxxxxx.tar.gz
以降は方法1
4、5と同様です。
効果:
3 イーサリアムブロックチェーンプライベートネットワークを展開する
3.1 プライベートチェーンの開始
ジェネシスブロック情報ファイルを作成します:genesis.json
{
"config": {
"chainId": 1001,//据说666没法进行多节点交互,不知道为啥,迷之操作
"homesteadBlock": 0,
"eip150Block": 0,
"eip155Block": 0,
"eip158Block": 0
},
"coinbase" : "0x0000000000000000000000000000000000000000",
"difficulty" : "0x1111111",
"extraData" : "",
"gasLimit" : "0x2fefd8",
"nonce" : "0x0000000000000042",
"mixhash" : "0x0000000000000000000000000000000000000000000000000000000000000000",
"parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000",
"timestamp" : "0x00",
"alloc" : {}
}
Ethereum ノードのデータ ディレクトリを初期化する
# 当前目录/home/network/ethdata
geth --datadir ./ init genesis.json
#node1
geth --datadir ./node2 init ./genesis.json
#node2
geth --datadir ./node3 init ./genesis.json
#node3
geth --datadir ./node3 init ./genesis.json
このコマンドは、Ethereum ノードの Geth クライアントを初期化するために使用され、ノードのデータ ストレージ ディレクトリを構成し、ブロックチェーンの初期状態 (ジェネシス ブロック) を設定します。コマンドの各部分には特定の意味があります。
-
geth
: Ethereumノードを実行するためのコマンドラインツール(クライアント)です。 -
--datadir ./ethdata
: このパラメーターは、すべてのブロックチェーン データを現在のディレクトリの下のethdata
フォルダーに保存するようにGeth に指示します。フォルダーが存在しない場合は、Geth が自動的に作成します。 -
init
: このサブコマンドは、新しいブロックチェーンを初期化するか、既存のブロックチェーンのステータスをリセットするために使用されます。 -
genesis.json
: このファイルはジェネシスブロックの構成を定義するJSON形式のファイルです。このファイルには、事前設定されたアカウント残高、コンセンサス ルール、ネットワーク ID など、ブロックチェーンの初期状態に関する情報が含まれています。
このコマンドを実行すると、Geth はgenesis.json
ファイル内の情報に基づいてジェネシス ブロックを作成し、指定されたデータ ディレクトリに保存します。これは、新しいプライベート イーサリアム ネットワークを構築するための最初のステップです。
効果は次の図に示すとおりです。
イーサリアムノードを開始する
geth --datadir ./ --networkid 1001 --identity "node1" --port 30303 --http --nodiscover --verbosity 4 console 2 > node1.log
geth --datadir ./node2 --networkid 1001 --identity "node2" --port 30304 --http --http.port 8546 --authrpc.port 8547 --nodiscover --verbosity 4 console 2 > node2.log
geth --datadir ./node3 --networkid 1001 --identity "node3" --port 30305 --http --http.port 8548 --authrpc.port 8549 --nodiscover --verbosity 4 console 2 > node3.log
#==================================================================================
geth --datadir ./ --networkid 1001 --identity "node1" --port 30303 --http --http.port 8545 --http.corsdomain "https://remix.ethereum.org" --http.api "web3,eth,debug,personal,net" --vmdebug --nodiscover --verbosity 4 console 2 > node1.log
# 节点2
geth --datadir ./node2 --networkid 1001 --identity "node2" --port 30304 --http --http.port 8546 --http.corsdomain "https://remix.ethereum.org" --http.api "web3,eth,debug,personal,net" --authrpc.port 8547 --nodiscover --verbosity 4 console 2 > node2.log
# 节点3
geth --datadir ./node3 --networkid 1001 --identity "node3" --port 30305 --http --http.port 8548 --http.corsdomain "https://remix.ethereum.org" --http.api "web3,eth,debug,personal,net" --authrpc.port 8549 --nodiscover --verbosity 4 console 2 > node3.log
# 节点4
geth --datadir ./node4 --networkid 1001 --identity "node3" --port 30306 --http --http.port 8550 --http.corsdomain "https://remix.ethereum.org" --http.api "web3,eth,debug,personal,net" --authrpc.port 8549 --nodiscover --verbosity 4 console 2 > node4.log
geth --datadir /ethdata --networkid 1001 --identity "node1" --port 30303 --http --nodiscover --verbosity 4 console 2 > node1.log
次の構成で Geth ノードを起動するために使用されます。
-
--datadir /ethdata
:
Geth がブロックチェーン データを保存するディレクトリを指定します/ethdata
。このディレクトリが存在し、書き込み可能であることを確認してください。 -
--networkid 1001
:
プライベートネットワークのネットワークIDを1001に設定します。この値は、プライベート ネットワークで異なる Ethereum ネットワークを区別するために必要です。 -
--identity "node1"
:
ノードの識別名「node1」を設定します。 -
--port 30303
:
ノード間の通信ポートを、デフォルトの Ethereum P2P ポートである 30303 に設定します。 -
--http
:
HTTP RPC サービスを有効にして、HTTP リクエストを通じてノードと対話できるようにします。 -
--nodiscover
:
ノード検出を無効にします。これは、ノードが他のノードを積極的に検出しないことを意味し、プライベート ネットワークに適しています。 -
--verbosity 4
:
ログの詳細レベルを 4 に設定します。これにより、より詳細なログ出力が提供されます。 -
console
:
Geth の JavaScript コンソールを開き、ノードの対話を可能にします。 -
2 > node1.log
:
標準エラー (stderr) 出力をファイルにリダイレクトしますnode1.log
。これは、エラーと一部のログ情報がこのファイルに書き込まれることを意味します。
アクセスログファイル
このコマンドを使用するとtail -f node1.log
、ファイルの内容をリアルタイムで表示できますnode1.log
。これは、ノードのステータスのデバッグや監視に役立ちます。
チェーン内にアカウントを作成するpersonal.newAccount()
-
新しいターミナルを開き、Ethereum ノードが実行されていることを確認します (コマンドで開始)。
-
ノードの JavaScript コンソールに接続します。次のコマンドを実行します。
geth attach geth attach ipc:./geth.ipc
-
JavaScript コンソールで、次のコマンドを使用して新しいアカウントを作成します。
personal.newAccount()
の結果
Personal.newAccount()
パスフレーズ:
パスフレーズを繰り返します:
「0x6b754c28176d8146dabddf3a3b3f310802761135」
新しいアカウントを保護し、新しいイーサリアム アドレスを生成するためのパスワードの入力を求められます。
マイニングを開始するminer.start()
JavaScript コンソールで次のコマンドを実行してマイニングを開始します (マイニングはプライベート ネットワークでも可能ですが、パブリック ネットワークに強力なコンピューティング能力がない場合は不可能です)。
miner.start()
これにより、マイニング操作が開始され、作成されたアカウントにマイニング報酬が送信されます。
3.2 マルチノードインタラクション
複数のフォルダーとノードを作成する
-
複数のディレクトリを作成します。各ディレクトリは個別のノード
node2
、node3
、に使用されますnode4
。 -
./node2
各ノード ディレクトリ内に、ノード データ、./node3
、を保存するための新しいデータ ディレクトリを作成します./node4
。 -
各ノード ディレクトリでジェネシス ブロック情報ファイルを使用し、
genesis.json
すべてのノードが同じジェネシス ブロックを使用するようにします。 -
異なる ID、ポート、データ ディレクトリを使用して異なるノードを起動します。たとえば、2 番目のノードの場合は次のようになります。
geth --datadir ./node2 --networkid 1001 --identity "node2" --port 30304 --http --http.port 8546 --http.corsdomain "https://remix.ethereum.org" --http.api "web3,eth,debug,personal,net" --authrpc.port 8547 --nodiscover --verbosity 4 console 2 > node2.log
3 番目のノードの場合:
geth --datadir ./node3 --networkid 1001 --identity "node3" --port 30305 --http --http.port 8548 --http.corsdomain "https://remix.ethereum.org" --http.api "web3,eth,debug,personal,net" --authrpc.port 8549 --nodiscover --verbosity 4 console 2 > node3.log
等々。
ノード間の接続を確立する
を使用してadmin.addPeer()
ノードを追加します
各ノードの JavaScript コンソールで、追加のノードを追加するために使用できますadmin.addPeer()
。たとえば、ノード 2 の場合は、次のコマンドを実行できます。
admin.addPeer("enode://enode-info")
その中にはenode-info
他のノードの情報も含まれますenode
。
使用admin.addPeer()
1. 以下に示すように、最初のノードで admin.nodeInfo.enode コマンドを使用して、e ノード情報を表示します。
admin.nodeInfo.enode
"enode://2c4eb7a267b1c00a8550e0237277234ca4bf8076b48268693e689f0657d6eb40eb88ee3f4d619b2361471c72881918a300a0de2943f6a29bd2a7c78e7a820d85@127.0.0.1:30303?discport=0"
2. 次に示すように、新しいノードで admin.addPeer コマンドを使用して連絡先を追加します。
admin.addPeer("enode://2c4eb7a267b1c00a8550e0237277234ca4bf8076b48268693e689f0657d6eb40eb88ee3f4d619b2361471c72881918a300a0de2943f6a29bd2a7c78e7a820d85@127.0.0.1:30303?discport=0")
true
3. 追加が完了すると、図のように表示されます。
現在の Ethereum ノードが接続されているピアに関する情報を表示します
admin.peers
ディレクトリにファイル--datadir
を追加するstatic-nodes.json
ノードのディレクトリ--datadir
にファイルを作成して、static-nodes.json
ノードに他のノードの連絡先情報を知らせます。このファイルには、他のノードに関する情報が含まれていますenode
。
次を使用して--bootnodes
ノードを起動します
ノードを開始するとき、--bootnodes
パラメーターを使用してブートストラップ ノードを指定できます。これらのノードは通常、ネットワーク上の既知のノードであり、新しいノードをネットワークに参加させるために使用されます。
たとえば、ノード 2 をノード 1 に接続する場合は、次のコマンドを使用できます。
geth --datadir ./node2 --networkid 1001 --identity "node2" --port 30304 --http --nodiscover --verbosity 4 --bootnodes "enode://enode-info-of-node1" console 2 > node2.log
enode-info-of-node1
実際のノード1の情報に置き換えてくださいenode
。
これらの手順により複数のノードが作成され、それらが相互に接続し、イーサリアム プライベート チェーンと対話できるようになります。実際のネットワークとニーズに合わせて構成を変更してください。
enode-info-of-node1
enode
ノード 1 の実際の情報を表すプレースホルダーです。各 Ethereum ノードには、enode
ネットワーク内の他のノードを識別して接続するために使用される一意の識別子があります。ノード 1 のノード 1 情報を取得するにはenode
、次の手順に従います。
- ノード 1 の JavaScript コンソールを開き、次のようにノード 1 に接続します。
geth attach
-
ノード 1 の JavaScript コンソールで次のコマンドを実行して、ノード 1 の
enode
情報を取得します。admin.nodeInfo.enode
enode
これにより、ノード 1 に関する次のような情報が返されます(サンプル データ。実際のデータは異なります)。"enode://5a5f7d1a3f2b9c39e5e31c1e15da40a9b9853d15a8a746799d9aa8505b0912f2d22c52f9971d144f3c9d2ba1ea2bf6cb75371ccf4f93cbcd10b2f8cd8@192.168.1.100:30303"
この情報をコピーして置換し
enode-info-of-node1
、このコマンドを使用して他のノードを起動し、ノード 1 に接続できるようにします。
3.3 リミックスプラットフォーム
https://remix.ethereum.org/
Remix は、イーサリアム スマート コントラクト開発用のオンライン統合開発環境 (IDE) であり、開発者がイーサリアム スマート コントラクトを簡単に作成、テスト、展開できるフレンドリーなインターフェイスを提供します。Remix プラットフォームに関する情報は次のとおりです。
-
オンライン IDE : Remix は、ソフトウェアのダウンロードやインストールを必要としない Web ベースのオンライン IDE です。ブラウザからRemix 公式 Web サイトにアクセスして開始してください。
-
スマート コントラクトの開発: Remix は Solidity スマート コントラクト言語をサポートし、開発者がスマート コントラクトを作成およびテストできるようにするコード エディター、コンパイラー、およびデバッグ ツールを提供します。
-
組み込みコンパイラー: Remix には、Solidity コントラクトを Ethereum 仮想マシン上で実行するバイトコードにコンパイルできる組み込み Solidity コンパイラーが含まれています。
-
導入とテスト: Remix を使用すると、スマート コントラクトをさまざまなイーサリアム ネットワークに導入できるようになり、コントラクト テスト用のシミュレータとテスト ツールが提供されます。
-
インタラクティブなデバッグ: Remix はインタラクティブなデバッグ機能を提供し、コントラクトの実行中にコードをステップ実行して変数のステータスを表示できるようにします。
-
プラグインのサポート: Remix はプラグインをサポートしており、プラグインをインストールしてハードウェア ウォレットとの統合、コードの静的分析などの機能を拡張できます。
-
マルチネットワークのサポート: Remix は、ローカル開発ネットワーク、テスト ネットワーク、メイン ネットワークなどを含む、さまざまな Ethereum ネットワークへの接続をサポートします。
-
自動保存: Remix はプロジェクトとコードを自動的に保存し、進行状況が失われないようにします。
-
オープン ソース: Remix はオープン ソース プロジェクトであり、そのソース コードは GitHub で見つけて投稿できます。
「デプロイ」をクリックしてマイニングを開始します
契約コード
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.4.16 <0.9.0;
contract SimpleStorage {
uint storedData;
function set(uint x) public {
storedData = x;
}
function get() public view returns (uint) {
return storedData;
}
}
abi文件
{
"accounts": {
"account{0}": "0x5B38Da6a701c568545dCfcB03FcB875f56beddC4"
},
"linkReferences": {},
"transactions": [
{
"timestamp": 1702920383750,
"record": {
"value": "0",
"inputs": "()",
"parameters": [],
"name": "",
"type": "constructor",
"abi": "0x87ffd8ade60e42979d05c9f20c82da7bc3b83edd90b5e21b99f1c7fc22b3f4c4",
"contractName": "SimpleStorage",
"bytecode": "608060405234801561001057600080fd5b5060df8061001f6000396000f3006080604052600436106049576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806360fe47b114604e5780636d4ce63c146078575b600080fd5b348015605957600080fd5b5060766004803603810190808035906020019092919050505060a0565b005b348015608357600080fd5b50608a60aa565b6040518082815260200191505060405180910390f35b8060008190555050565b600080549050905600a165627a7a72305820e88ab6cf60239ef75ac75ee4f05782c5ba81fe8d68165ed5320bd223b26e8fb90029",
"linkReferences": {},
"from": "account{0}"
}
}
],
"abis": {
"0x87ffd8ade60e42979d05c9f20c82da7bc3b83edd90b5e21b99f1c7fc22b3f4c4": [
{
"constant": false,
"inputs": [
{
"name": "x",
"type": "uint256"
}
],
"name": "set",
"outputs": [],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
},
{
"constant": true,
"inputs": [],
"name": "get",
"outputs": [
{
"name": "",
"type": "uint256"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
}
]
}
}
4つのノードのノード情報
ノード1:
{
enode: "enode://1cfeb52d4b3f16dad23bc33b26b4fd1de172ca1887449be5067edb3c2f07e362ddd174141efdccfb73f7bc4ba26de8aedd8b11c6e1b9d0689cc5084cdf798335@127.0.0.1:30303?discport=0",
enr: "enr:-Jy4QJGbI7JRI5myR2Pxqg7Xt5vao0bFSWJ1e8tYuKGndq0VIC1VYQWYUN_NPtcFoNIe5vCBe4OP3L6g7asgmF51Uu2GAYx9rlrsg2V0aMfGhJ0r3hCAgmlkgnY0gmlwhH8AAAGJc2VjcDI1NmsxoQMc_rUtSz8W2tI7wzsmtP0d4XLKGIdEm-UGfts8LwfjYoRzbmFwwIN0Y3CCdl8",
id: "af1588b49ceded64e6ffea5ff8975e5feb411566c2d083eb3e6efd2ed37e5dfa",
ip: "127.0.0.1",
listenAddr: "[::]:30303",
name: "Geth/node1/v1.10.25-stable-69568c55/linux-amd64/go1.18.5",
ports: {
discovery: 0,
listener: 30303
},
protocols: {
eth: {
config: {
chainId: 1001,
eip150Block: 0,
eip150Hash: "0x0000000000000000000000000000000000000000000000000000000000000000",
eip155Block: 0,
eip158Block: 0,
homesteadBlock: 0
},
difficulty: 17895697,
genesis: "0xcc97a15707e1a3cf64433ce47735b831073c2995ad8b0618169abb8dac9c57c9",
head: "0xcc97a15707e1a3cf64433ce47735b831073c2995ad8b0618169abb8dac9c57c9",
network: 1001
},
snap: {}
}
}
ノード2:
{
enode: "enode://c79420eadd69edbaa4c4d53e9039d6a063c0376be2bfb5551fd2b69b3505c1c7521efa4c25e9b3929e1bd2ac0bbbb5fbc7bf1a70e9f89744459add2869e259e7@127.0.0.1:30304?discport=0",
enr: "enr:-Jy4QAFVZFNhaOj91TF5_yBRhLWwbYd-Bq_R8X9GL9hQ6n-xddNTu-vUQpfJrvqGjWO55nWhIWleMySrJUyXsl2CKe6GAYx9tJSlg2V0aMfGhJ0r3hCAgmlkgnY0gmlwhH8AAAGJc2VjcDI1NmsxoQPHlCDq3WntuqTE1T6QOdagY8A3a-K_tVUf0rabNQXBx4RzbmFwwIN0Y3CCdmA",
id: "83f9dcf2e1885cbede6e86bd098381732e678fe5b8e995c6009323b8b68cc33d",
ip: "127.0.0.1",
listenAddr: "[::]:30304",
name: "Geth/node2/v1.10.25-stable-69568c55/linux-amd64/go1.18.5",
ports: {
discovery: 0,
listener: 30304
},
protocols: {
eth: {
config: {
chainId: 1001,
eip150Block: 0,
eip150Hash: "0x0000000000000000000000000000000000000000000000000000000000000000",
eip155Block: 0,
eip158Block: 0,
homesteadBlock: 0
},
difficulty: 17895697,
genesis: "0xcc97a15707e1a3cf64433ce47735b831073c2995ad8b0618169abb8dac9c57c9",
head: "0xcc97a15707e1a3cf64433ce47735b831073c2995ad8b0618169abb8dac9c57c9",
network: 1001
},
snap: {}
}
}
ノード3:
{
enode: "enode://c8acdec78e2920e68526c577eb474dd6579af767ec8a00fc14a0047d8e5577794b6abba15d3deffb321983a2c81f2ca0547398248005efb8c2cccac27b875a2c@127.0.0.1:30305?discport=0",
enr: "enr:-Jy4QFVKitcbQ5k0mfigmp5AoLINiCHWq95n7-Fw0yeHPB67RgmkDclHixlEqHixQD08sEcvJHmrX3R1ENjmD4xZhfGGAYx91NwEg2V0aMfGhJ0r3hCAgmlkgnY0gmlwhH8AAAGJc2VjcDI1NmsxoQLIrN7Hjikg5oUmxXfrR03WV5r3Z-yKAPwUoAR9jlV3eYRzbmFwwIN0Y3CCdmE",
id: "d4f0afc790c004126c95bdd71e120c3d3814c2d519446b26609ab6941699d130",
ip: "127.0.0.1",
listenAddr: "[::]:30305",
name: "Geth/node3/v1.10.25-stable-69568c55/linux-amd64/go1.18.5",
ports: {
discovery: 0,
listener: 30305
},
protocols: {
eth: {
config: {
chainId: 1001,
eip150Block: 0,
eip150Hash: "0x0000000000000000000000000000000000000000000000000000000000000000",
eip155Block: 0,
eip158Block: 0,
homesteadBlock: 0
},
difficulty: 17895697,
genesis: "0xcc97a15707e1a3cf64433ce47735b831073c2995ad8b0618169abb8dac9c57c9",
head: "0xcc97a15707e1a3cf64433ce47735b831073c2995ad8b0618169abb8dac9c57c9",
network: 1001
},
snap: {}
}
}
ノード4:
{
enode:
"enode://5a5f7d1a3f2b9c39e5e31c1e15da40a9b9853d15a8a746799d9aa8505b0912f2d22c52f9971d144f3c9d2ba1ea2bf6cb75371ccf4f93cbcd10b2f8cd8@192.168.1.100:30303",
enr: "enr:-Jy4QAFVZFNhaOj91TF5_yBRhLWwbYd-Bq_R8X9GL9hQ6n-xddNTu-vUQpfJrvqGjWO55nWhIWleMySrJUyXsl2CKe6GAYx9tJSlg2V0aMfGhJ0r3hCAgmlkgnY0gmlwhH8AAAGJc2VjcDI1NmsxoQPHlCDq3WntuqTE1T6QOdagY8A3a-K_tVUf0rabNQXBx4RzbmFwwIN0Y3CCdmA",
id: "83f9dcf2e1885cbede6e86bd098381732e678fe5b8e995c6009323b8b68cc33d",
ip: "127.0.0.1",
listenAddr: "[::]:30304",
name: "Geth/node2/v1.10.25-stable-69568c55/linux-amd64/go1.18.5",
ports: {
discovery: 0,
listener: 30304
},
protocols: {
eth: {
config: {
chainId: 1001,
eip150Block: 0,
eip150Hash: "0x0000000000000000000000000000000000000000000000000000000000000000",
eip155Block: 0,
eip158Block: 0,
homesteadBlock: 0
},
difficulty: 17895697,
genesis: "0xcc97a15707e1a3cf64433ce47735b831073c2995ad8b0618169abb8dac9c57c9",
head: "0xcc97a15707e1a3cf64433ce47735b831073c2995ad8b0618169abb8dac9c57c9",
network: 1001
},
snap: {}
}
}
3.4 ストレージ操作用のコマンド
const Web3 = require('web3');
const web3 = new Web3('https://127.0.0.1:8854');
const contractABI = [0x5B38Da6a701c568545dCfcB03FcB875f56beddC4]; // 合约的ABI
const contractAddress = '0x87ffd8ade60e42979d05c9f20c82da7bc3b83edd90b5e21b99f1c7fc22b3f4c4'; // 合约地址
const privateKey = '0xbcea812a244c0ac6ce96d877a023747c20c55c91'; // 发送交易的私钥
const contract = new web3.eth.Contract(contractABI, contractAddress);
const key = '123456';
const value = '10';
const data = contract.methods.store(key, value).encodeABI();
web3.eth.accounts.signTransaction({
to: contractAddress,
data: data,
gas: '5000000', // 适当设置gas
}, privateKey).then(signedTx => {
web3.eth.sendSignedTransaction(signedTx.rawTransaction)
.on('receipt', receipt => {
console.log('Transaction receipt:', receipt);
});
});
3.5 キーに基づいて値の操作を問い合わせるコマンド
const Web3 = require('web3');
const web3 = new Web3('https://127.0.0.1:8854');
const contractABI = [0x5B38Da6a701c568545dCfcB03FcB875f56beddC4]; // 合约的ABI
const contractAddress = '0x87ffd8ade60e42979d05c9f20c82da7bc3b83edd90b5e21b99f1c7fc22b3f4c4'; // 合约地址
const contract = new web3.eth.Contract(contractABI, contractAddress);
const key = '123456';
contract.methods.getValue(key).call()
.then(result => {
console.log('Value for key', key, 'is', result);
});