読了時間:8分
このガイドには、現在は積極的にメンテナンスが行われていないKovanテストネットに関する記述が含まれています。このチェーンに関連する具体的な手順は適用できない場合がありますが、全体的なプロセスは他のチェーンでも有効である可能性があります。実装にあたっては、現在の代替案を検討することをお勧めします。このガイドの最新版をご覧になりたい場合は、ぜひお知らせください!
概要
ネットワークの混雑や、自分の取引よりも高いガス料金を提示している保留中の取引が多すぎるなどの理由で、イーサリアム上で十分なガス料金を設定せずに取引を送信してしまうことがあります。優先度の高い取引であってもガス料金が低すぎると、取引が決済されるまで数時間、あるいは数日待たなければならない可能性があります。このような場合、できるだけ早くマイニングされるようにするためには、より高いガス料金と、同じノンセを指定して取引を再送信する必要があります。
このガイドでは、イーサリアムのテストネットワークの1つで、Ethers.js を使用してトランザクションを送信したり、同じトランザクションを再送信したりする際の用語や情報をすべて解説します。
イーサリアムにおけるトランザクションとは何ですか?
イーサリアムネットワーク上で何かを追加、更新、または変更したいときは、トランザクションを実行します。基本的に、トランザクションとは、現実世界がイーサリアムブロックチェーンネットワークとやり取りするための手段です。イーサリアムネットワーク上でトランザクションを実行するたびに、「ガス」と呼ばれる手数料を支払う必要があります。ガスは、wei(ETHの最小単位)またはgweiで表されます。
イーサリアムにおけるトランザクションの種類
イーサリアムネットワークでは、主に3種類のトランザクションがあります:
- あるアカウントから別のアカウントへETH(イーサ)が送金される、ごく一般的な取引です。
- 契約を作成するトランザクションとは、イーサリアム・ブロックチェーン・ネットワーク上にスマートコントラクトがデプロイされる種類のトランザクションのことです。
- 契約を呼び出すトランザクション。このトランザクションにはデータが添付されて送信され、以前にデプロイされたスマートコントラクトへのクエリややり取りに使用されます。
一般的なイーサリアム取引のパラメータ
- from: 送信者アドレス。取引を開始したアカウントを表す20バイトのアドレス。
- to: 受信者のアドレス。受信者のアカウント、またはコントラクトアカウントを表す20バイトのアドレス。
- value:これは、あるアカウントから別のアカウントへ、トランザクションで送金されたETHの金額です。
- data:このフィールドには、コントラクトのデプロイ取引用のバイトコードが含まれます。コントラクト関数の実行の場合、このフィールドには関数のシグネチャとエンコードされた引数が含まれます。資金移動取引では、このフィールドは不要であるか、空のままになります。
- gasLimit: これは、トランザクションがガスとして使用できる最大量(wei単位)です。
- gasPrice:これは、送信者がそのトランザクションに対して支払う意思のあるwei単位の金額です。
- chainId: これは、お使いのイーサリアムノードのネットワークIDです(メインネット:1、Rinkeby:4、Kovan:42など)。
- ノンセ:特定のアドレスが送信するトランザクションの回数です。そのアドレスがトランザクションを送信するたびに、ノンセは1ずつ増加します。
イーサリアムにおけるトランザクションの流れ
- トランザクションオブジェクトを作成し、必要なすべてのパラメータを指定する。
- 送信者の秘密鍵を使用して取引に署名する。
- イーサリアムノードを使用して、トランザクションをイーサリアムブロックチェーンネットワークに送信します。
取引の署名
トランザクションの署名とは、送信者の秘密鍵を使用してトランザクションオブジェクトに署名を生成することを意味します。イーサリアムにおける署名と検証についてさらに詳しく知りたい場合は、以下の優れた記事をご覧ください:Yos著『Signing and Verifying Ethereum Signatures』およびAngello Pozo著『Ethereum: Signing and Validating』。
さて、イーサリアムにおけるトランザクションについて理解が深まったところで、実際に自分たちでトランザクションを送信してみましょう。
前提条件
- お使いのシステムにNode.jsがインストールされています
- テキストエディタ
- ターミナル(別名:コマンドライン)
必要なツールのインストール。
ライブラリパッケージの管理やJavaScriptファイルの操作には、Node.jsを使用します。お使いのシステムにNode.jsがインストールされているかどうかを確認するには、ターミナルを開いて次のコマンドを実行してください:
$ node -v
インストールされていない場合は、Node.jsのLTS版を公式サイトからダウンロードできます。
トランザクションを送信するには、短いJavaScriptコードを使用し、ethers.jsライブラリ(バージョン5.7であることを確認してください)を利用します。コマンドラインまたはターミナルからnpmを使ってインストールできます:
$ npm install --save ethers@5.7
このステップで最もよく発生する問題は、`node-gyp` の内部的な不具合です。node-gyp のインストール手順については、こちらをご覧ください。
もう1つよくある問題として、キャッシュが古くなっていることが挙げられます。ターミナルで以下のコマンドを入力するだけで、npmのキャッシュをクリアできます:
$ npm cache clean
ethers.jsライブラリについて詳しく知りたい場合は、当社のethers.js ガイドをご覧ください。
ウォレットを作成し、テスト用のETHを入手する
それでは、自分用のウォレットを作成してみましょう。そのためには、まず「index.js」というファイル、あるいは任意の名前をつけたJavaScriptファイルを作成します。以下のコードをコピーして、コードエディタに貼り付けてください:
var ethers = require('ethers');
var privateKey = "0x0111111111111111111122222222222222222223333333333333333333344445";
var wallet = new ethers.ウォレット(秘密鍵);
コンソール.log("アドレス: " + wallet.address);
ここで何が起こるのか見てみましょう。先ほどインストールしたethers.jsライブラリをインポートします(1行目)。 ウォレット専用の秘密鍵を作成します。ご自身で作成する必要がありますが、数字は任意で構いません。ただし、上記と同じ桁数であることを確認してください(2行目)、その秘密鍵を使用してethersでウォレットインスタンスを作成します(3行目)、コンソールに「Address」というテキストと共にウォレットアドレスを出力します(4行目)。
それでは、次のコマンドでファイルを実行してください:
$ node index.js
すべてが順調に進めば、ターミナルウィンドウに表示される出力は次のようになります:
アドレス:0x3f5D3070Fc7924479B5e367a83EC2b284E9c4e04
すべてのトランザクションには手数料としてガスが必要であり、トランザクションを送信するためにもガスが必要となるため、ウォレットにテスト用のETHを入手しておきましょう。このため、Kovanノードを使用します。こちらのKovanファウセットにアクセスしてテスト用のETHを入手し、上記のコードを実行して取得したウォレットアドレスを貼り付け、「send me KETH!」をクリックしてください。
注:これはテスト用のETHであり、市場価値はありません。
Quicknodeのイーサリアムエンドポイントを設定する
今日の目的では、Geth や OpenEthereum(旧称 Parity)など、ほぼどのイーサリアムクライアントでも使用できます。イーサリアムノードを自分で起動するには、まずクライアントを選択して設定する必要があります。イーサリアムノードの同期や維持管理は困難な作業であり、イーサリアムのフルノードを同期させるには数日かかることもあります。
たった1つのトランザクションを送信するだけにしては、この手順は少々複雑すぎるため、Quicknodeの無料エンドポイントを利用して簡単に済ませましょう。無料のイーサリアムエンドポイントを作成したら、HTTPプロバイダーのエンドポイントをコピーしてください:
このガイドでは、Kovanテストネットノードを使用しています。

後で必要になるので、これをコピーして保存しておいてください。
トランザクションの送信と再送信
これで、ウォレットとテスト用のETHが用意できました。それでは、別のアカウントやウォレットにETHを送金するトランザクションを送ってみましょう。そのためには、index.js ファイルにさらにコードを追加します。以下のコードをコピーして、お使いのコードエディタに貼り付けてください:
var ethers = require('ethers');
var url = 'ADD_YOUR_ETHEREUM_NODE_URL';
var customHttpProvider = new ethers.providers.JsonRpcProvider(url);
var privateKey = "0x0111111111111111111122222222222222222223333333333333333333344445";
var wallet = new ethers.Wallet(privateKey);
console.log("Address: " + wallet.address);
tx = {
to: "0x6E0d01A76C3Cf4288372a29124A26D4353EE51BE",
value: ethers.utils.parseEther("0.05"),
chainId: 42,
nonce: 3
}
customHttpProvider.estimateGas(tx).then(function(estimate) {
tx.gasLimit = estimate;
tx.gasPrice = ethers.utils.parseUnits("0.14085197", "gwei");
wallet.signTransaction(tx).then((signedTX)=>{
customHttpProvider.sendTransaction(signedTX).then(console.log);
});
});
それでは、`ADD_YOUR_ETHEREUM_NODE_URL` を、上記のセクションに記載されている HTTP プロバイダーに置き換えてください。
上記のコードについて簡単に説明します。まず、先ほどインストールしたethersライブラリをインポートし(1行目)、EthereumノードのURLを設定し(2行目)、ethersのJsonRpcProviderインスタンスを生成します(3行目)。次に、ウォレット専用の秘密鍵を作成します。ご自身で作成する必要がありますが、数字は任意のものを使用できます。ただし、桁数は同じであるようにしてください(4行目)。 その秘密鍵を使用してethersでウォレットインスタンスを作成します(5行目)。コンソールに「Address」というテキストと共にウォレットアドレスを出力します(6行目)。トランザクションオブジェクトを作成し、受信者のアドレスを指定する'to'フィールドを追加します。`var wallet = Wallet.createRandom();`を使用してランダムなアドレスを生成することもできます。`を使用してランダムなアドレスを生成できます。また、送信するETHの金額を指定する「value」フィールド、Kovanを使用しているため「chainId」フィールドを42に設定し、nonceフィールドを3に設定します(7行目~12行目)。ノードを介してgasLimitを推定し、ガス価格を設定します(13行目~15行目)。 ウォレットの秘密鍵でトランザクションオブジェクトに署名して送信し、コンソールにトランザクションを出力します(16~18行目)。
これを実行してみましょう:
$ node index.js
次のような出力が得られます:

ハッシュフィールドの文字列(「0xe49c8122656c612bf5f1e10b251f56671acf01d831b6876c37c5a52053035642」のようなもの)をコピーし、Kovan Etherscanの検索ボックスに貼り付けて、トランザクションの状態を確認してください。 このトランザクションは、まだブロックチェーン上の新しいブロックに追加されておらず、「保留中」の状態になっていることがわかります。これは、ガス料金を著しく低く設定したためです。
それでは、同じノンセを使用して同じトランザクションを送信してみますが、今回はガス量を増加させてみましょう。コードの15行目にあるgasPriceの値を「0.14085197」から「2.14085197」に変更し、コードを再実行してください:
$ node index.js
新しい出力からハッシュ文字列をコピーし、Kovan Etherscanの検索ボックスに貼り付けて、トランザクションの状態を確認してください。今回は、適切なガス価格(gasPrice)の値を増やして送信したため、トランザクションはブロックに追加され、成功ステータスとなります。
注:「ノンセ」の値は、両方のトランザクションで同じであることに注意してください。前述の通り、ノンセはイーサリアムアドレスが保有するトランザクションの数を指す指標です。より高いガス料金を設定してトランザクションを再送信するには、元のトランザクションと同じノンセを使用する必要があります。もし値の大きいノンセを使用すると、それは新しいトランザクションとして扱われるため、意図した以上にETHを消費することになります。
結論
つまり、上記の例でも見たように、トランザクションが承認されるためには、そのトランザクションのガス料金が競争力のあるものでなければなりません。ブロックチェーンのマイナーは、利用可能なブロックスペースと、そのブロックスペースを確保するために各トランザクションが支払う意思のある金額に基づいてガス料金を設定します。ガス料金が閾値を下回るトランザクションは、承認されません。他のトランザクションに比べてガス料金が高いトランザクションほど、迅速に承認されます。
イーサリアムに関する記事やガイドをもっと読みたい方は、ぜひニュースレターにご登録ください。ご意見やご感想がございましたら、Twitterからお気軽にお寄せください。また、ご質問がある場合は、Discordのコミュニティサーバーでいつでも私たちとチャットできます。そこには、最高にクールな開発者たちが集まっています。ありがとうございます :)
