Viemを使用したトランザクションの送信
これは、Viem (新しいタブで開きます)ライブラリを使用してイーサリアムのトランザクションを送信するための初心者向けガイドです。イーサリアムのブロックチェーンにトランザクションを送信するには、作成、署名、ブロードキャストの3つの主要なステップがあります。これら3つすべてについて説明し、皆さんの疑問にお答えします!このチュートリアルでは、Alchemy (新しいタブで開きます)を使用してイーサリアムのチェーンにトランザクションを送信します。こちらから無料のAlchemyアカウントを作成 (新しいタブで開きます)できます。
注: このガイドは、アプリのバックエンドでトランザクションに署名するためのものです。フロントエンドでトランザクションの署名を統合したい場合は、メタマスクのプロバイダーAPI (新しいタブで開きます)を確認してください。
基本事項
初めてブロックチェーン開発を始めた多くの開発者と同様に、トランザクションの送信方法(本来は非常にシンプルなはずのこと)について調べた結果、それぞれ異なることを言っている大量のガイドに遭遇し、少し圧倒されて混乱したかもしれません。もしそうなら、心配しないでください。誰もが一度は通る道です!それでは、始める前にいくつか明確にしておきましょう。
1. Alchemyは秘密鍵を保存しません
- これは、Alchemyがあなたに代わってトランザクションに署名し、送信することはできないことを意味します。その理由はセキュリティのためです。Alchemyが秘密鍵の共有を求めることは決してありませんし、ホストされたノード(または他の誰か)と秘密鍵を共有するべきではありません。
- AlchemyのコアAPIを使用してブロックチェーンから読み取ることはできますが、書き込むには、Alchemyを通じて送信する前に、別のものを使用してトランザクションに署名する必要があります(これは他のノードサービスでも同じです)。
2. 「署名者(Signer)」とは何ですか?
- 署名者は、秘密鍵を使用してあなたに代わってトランザクションに署名します。このチュートリアルでは、トランザクションの署名にViem (新しいタブで開きます)を使用しますが、他のWeb3ライブラリを使用することもできます。
- フロントエンドにおける署名者の良い例はメタマスク (新しいタブで開きます)です。これは、あなたに代わってトランザクションに署名し、送信します。
3. なぜトランザクションに署名する必要があるのですか?
- イーサリアムのネットワークでトランザクションを送信したいすべてのユーザーは、トランザクションの送信元が主張する本人であることを検証するために、(秘密鍵を使用して)トランザクションに署名する必要があります。
- 秘密鍵にアクセスできると、イーサリアムのアカウントを完全に制御できるようになり、あなた(またはアクセスできる人)に代わってトランザクションを実行できるようになるため、この秘密鍵を保護することは非常に重要です。
4. 秘密鍵を保護するにはどうすればよいですか?
- 秘密鍵を保護し、それを使用してトランザクションを送信する方法はたくさんあります。このチュートリアルでは、
.envファイルを使用します。ただし、秘密鍵を保存する別のプロバイダーを使用したり、キーストアファイルを使用したり、その他のオプションを使用することもできます。
5. eth_sendTransactionとeth_sendRawTransactionの違いは何ですか?
eth_sendTransactionとeth_sendRawTransactionはどちらも、将来のブロックに追加されるようにイーサリアムのネットワークにトランザクションをブロードキャストするイーサリアムのAPI関数です。これらは、トランザクションの署名の処理方法が異なります。
eth_sendTransactionは未署名のトランザクションを送信するために使用されます。つまり、送信先のノードが秘密鍵を管理し、チェーンにブロードキャストする前にトランザクションに署名できる必要があります。Alchemyはユーザーの秘密鍵を保持しないため、このメソッドをサポートしていません。eth_sendRawTransaction(新しいタブで開きます)は、すでに署名されているトランザクションをブロードキャストするために使用されます。つまり、最初に秘密鍵を使用してトランザクションに署名し(Viemでは、ローカルアカウント (新しいタブで開きます)でsignTransaction(新しいタブで開きます)を使用します)、その結果をeth_sendRawTransactionに渡す必要があります。
Viemを使用する場合、eth_sendRawTransactionにはsendRawTransaction (新しいタブで開きます)関数を呼び出すことでアクセスします。
このチュートリアルではこれを使用します。
6. Web3ライブラリとは何ですか?
- Web3ライブラリは、イーサリアム開発で非常に一般的に使用される標準的なJSON-RPC呼び出しのラッパーです。
- さまざまな言語向けに多くのWeb3ライブラリがあります。このチュートリアルでは、TypeScriptで記述され、任意のJavaScriptプロジェクトで動作するViem (新しいタブで開きます)を使用します。Ethers.js (新しいタブで開きます)などの他のオプションはこちらで確認できます。
さて、いくつかの疑問が解消されたところで、チュートリアルに進みましょう。質問があれば、いつでもAlchemyのディスコード (新しいタブで開きます)で気軽に聞いてください!
7. 安全でガスが最適化されたプライベートなトランザクションを送信するにはどうすればよいですか?
- Alchemyにはトランザクションに関する一連のリソースがあります (新しいタブで開きます)。これらを使用して、トランザクションの送信、実行前のトランザクションのシミュレーション、プライベートなトランザクションの送信、およびガスが最適化されたトランザクションの送信を行うことができます。
- また、AlchemyのWebhook (新しいタブで開きます)を使用すると、トランザクションがメンプールから取り出されてチェーンに追加されたときにアラートを受け取ることができます。
注: このガイドでは、Alchemyアカウント、イーサリアムのアドレスまたはメタマスクのウォレット、Node.js、およびnpmがインストールされている必要があります。インストールされていない場合は、次の手順に従ってください。
- 無料のAlchemyアカウントを作成する (新しいタブで開きます)
- メタマスクのアカウントを作成する (新しいタブで開きます)(またはイーサリアムのアドレスを取得する)
- Node.jsとnpmをインストールする (新しいタブで開きます)
トランザクションを送信する手順
1. SepoliaテストネットでAlchemyアプリを作成する
Alchemyダッシュボード (新しいタブで開きます)に移動し、ネットワークとしてSepolia(または他のテストネット)を選択して新しいアプリを作成します。
2. SepoliaフォーセットからETHをリクエストする
AlchemyのSepoliaフォーセット (新しいタブで開きます)の指示に従ってETHを受け取るか、他のSepoliaフォーセットのいずれかを使用します。フォーセットは少額(Alchemyのフォーセットは1日あたり0.1 ETH)を提供しますが、このチュートリアルには十分です。他のネットワークではなく、必ずSepoliaのイーサリアムのアドレス(メタマスクから)を含めるようにしてください。指示に従った後、ウォレットにETHを受け取ったことを再確認してください。
3. 新しいプロジェクトディレクトリを作成し、そこにcdする
コマンドライン(Macの場合はターミナル)から新しいプロジェクトディレクトリを作成し、そこに移動します。
mkdir sendtx-example
cd sendtx-example
4. Viem(または任意のWeb3ライブラリ)をインストールする
プロジェクトディレクトリで次のコマンドを実行して、Viem (新しいタブで開きます)をインストールします。
Ethers.jsライブラリを使用したい場合は、こちらの指示に従ってください (新しいタブで開きます)。
npm init -y
npm install viem
5. dotenvをインストールする
APIキーと秘密鍵を安全に保存するために、.envファイルを使用します。
npm install dotenv
6. .envファイルを作成する
プロジェクトディレクトリに.envファイルを作成し、次を追加します(「your-api-url」と「your-private-key」を置き換えます)。
- AlchemyのAPI URLを見つけるには、ダッシュボードで作成したばかりのアプリの詳細ページに移動し、右上隅の「View Key」をクリックして、HTTP URLを取得します。
- メタマスクを使用して秘密鍵を見つけるには、このガイド (新しいタブで開きます)を確認してください。テストネットのETHのみを保持するアカウントを使用してください。
API_URL="your-api-url"
PRIVATE_KEY="your-private-key"
.envをコミットしないでください!.envファイルを誰かと共有したり公開したりすると、シークレットが漏洩することになるため、絶対にしないでください。バージョン管理を使用している場合は、.envをgitignoreファイルに追加してください。7. sendTx.jsファイルを作成する
素晴らしいです。機密データが.envファイルで保護されたので、コーディングを始めましょう。トランザクション送信の例として、メタマスクの2つ目のアカウントなど、あなたが管理する別のアドレスに0.001 ETHを送金します。
sendTx.jsファイルを作成します。ここでサンプルトランザクションを設定して送信します。次のコード行を追加してください。
require("dotenv").config({ quiet: true })
const { createPublicClient, createWalletClient, http, parseEther } = require("viem")
const { privateKeyToAccount } = require("viem/accounts")
const { sepolia } = require("viem/chains")
async function main() {
const { API_URL, PRIVATE_KEY } = process.env
const account = privateKeyToAccount(
PRIVATE_KEY.startsWith("0x") ? PRIVATE_KEY : `0x${PRIVATE_KEY}`
)
const publicClient = createPublicClient({
chain: sepolia,
transport: http(API_URL),
})
const walletClient = createWalletClient({
account,
chain: sepolia,
transport: http(API_URL),
})
const nonce = await publicClient.getTransactionCount({
address: account.address,
blockTag: "pending",
}) // ナンスは0からカウントされます
const transaction = await walletClient.prepareTransactionRequest({
to: "0xYourSecondAddress", // TODO: ETHを送金したいアドレスに置き換えてください
value: parseEther("0.001"), // 0.001 ETH
gas: 21000n,
nonce,
// メッセージを送信したりスマート・コントラクトを実行するための任意のデータフィールド
})
const signedTx = await walletClient.signTransaction(transaction)
try {
const hash = await walletClient.sendRawTransaction({
serializedTransaction: signedTx,
})
console.log("🎉 The hash of your transaction is:", hash)
const receipt = await publicClient.waitForTransactionReceipt({ hash })
console.log(`Transaction ${receipt.status} in block ${receipt.blockNumber}`)
} catch (error) {
console.log(
"❗Something went wrong while submitting your transaction:",
error.details ?? error.message
)
}
}
main()
0xYourSecondAddressを、ETHを送金したいアドレスに必ず置き換えてください。スクリプトはPRIVATE_KEYからあなた自身の(送信元の)アドレスを導出するため、入力する必要はありません。
さて、このコードを実行する前に、ここにあるいくつかのコンポーネントについて説明しましょう。
account:privateKeyToAccount(新しいタブで開きます)を使用して秘密鍵から作成されたローカルアカウントです。署名はあなたのマシン上で行われ、秘密鍵がAlchemyに送信されることは決してありません。publicClientとwalletClient: AlchemyのURLにJSON-RPCリクエストを送信するViemクライアントです。パブリッククライアントはチェーンから読み取りを行い、ウォレットクライアントはアカウントのトランザクションを準備して署名します。nonce: ナンスの指定は、あなたのアドレスから送信されたトランザクションの数を追跡するために使用されます。これはセキュリティ上の目的と、リプレイ攻撃を防ぐために必要です。あなたのアドレスから送信されたトランザクションの数を取得するには、getTransactionCount (新しいタブで開きます)を使用します。Viemもこれを自動的に入力してくれますが、ここではそれがどこから来るのかを示すために明示的に取得しています。transaction: トランザクションオブジェクトには、指定する必要があるいくつかの側面があります。prepareTransactionRequest(新しいタブで開きます)は、現在のネットワーク状況に基づいて、chainIdやEIP-1559の手数料フィールドであるmaxFeePerGasおよびmaxPriorityFeePerGasなど、残りの部分を自動的に入力してくれます。to: これはETHを送金したいアドレスです。value: これは送金したい金額で、10^18 Wei = 1 ETHとなるWeiで指定します。parseEther(新しいタブで開きます)は、ETHの金額をWeiに変換してくれます。アカウントはガスの支払いも行うため、これより少し多くの残高が必要です。gas: トランザクションに含める適切なガス量を決定する方法はたくさんあります。Alchemyは、オンチェーンのアクティビティについて通知できるWebhook (新しいタブで開きます)をサポートしています。メインネットのトランザクションの場合、現在のガス状況を確認して、含める適切なガス量を決定することをお勧めします。通常のアドレスへの単純なETHの送金は常に正確に21000ガスを使用し、これがすべてのトランザクションの最小値であるため、ここでは21000を指定します。gasを省略すると、Viemが自動的に見積もってくれます。nonce: 上記のナンスの定義を参照してください。ナンスはゼロからカウントを開始します。- [オプション] data: 送金とともに追加情報を送信したり、スマート・コントラクトを呼び出したりするために使用されます。残高の送金には必須ではありません。以下の注記を確認してください。
signedTx: トランザクションオブジェクトに署名するには、signTransactionメソッドを使用します。これは、PRIVATE_KEYから作成されたアカウントを使用してローカルで署名します。sendRawTransaction: 署名されたトランザクションができたら、eth_sendRawTransactionを呼び出すsendRawTransactionを使用して、後続のブロックに含めるために送信できます。waitForTransactionReceipt: トランザクションがブロックに含まれるまで待機し、そのレシートを返します。
データに関する注記 イーサリアムで送信できるトランザクションには、主に2つのタイプがあります。
- 残高の送金: あるアドレスから別のアドレスへETHを送金します。データフィールドは必要ありませんが、トランザクションとともに追加情報を送信したい場合は、このフィールドにHEX形式でその情報を含めることができます。
- たとえば、イミュータブルなタイムスタンプを付与するために、IPFSドキュメントのハッシュをイーサリアムのチェーンに書き込みたいとします。その場合、データフィールドはViemの
toHex(新しいタブで開きます)を使用して、data: toHex("IPFS hash")のようになります。これにより、誰でもチェーンをクエリして、そのドキュメントがいつ追加されたかを確認できるようになります。
- たとえば、イミュータブルなタイムスタンプを付与するために、IPFSドキュメントのハッシュをイーサリアムのチェーンに書き込みたいとします。その場合、データフィールドはViemの
- スマート・コントラクトのトランザクション: チェーン上でスマート・コントラクトのコードを実行します。この場合、データフィールドには、実行したいスマート関数とパラメータを含める必要があります。
- 実践的な例については、Hello Worldスマート・コントラクトのチュートリアルを確認してください。
8. node sendTx.jsを使用してコードを実行する
ターミナルまたはコマンドラインに戻り、次を実行します。
node sendTx.js
9. ブロック・エクスプローラーでトランザクションを確認する
スクリプトは、ノードがトランザクションを受け入れるとすぐにトランザクション・ハッシュを出力し、ブロックに含まれるまで(通常は数秒以内)待機して結果を出力します。詳細を確認するには、Sepolia Etherscan (新しいタブで開きます)やBlockscout (新しいタブで開きます)などのSepoliaのブロック・エクスプローラーにハッシュを貼り付けます。そこで、トランザクションが保留中から含まれるまでの過程を観察し、金額、手数料、およびそれが着地したブロックを確認できます。
代わりにinsufficient fundsエラーが表示された場合、アカウントには送金額とガスをカバーするのに十分なSepoliaのETHがありません。ステップ2に戻り、フォーセットからさらにリクエストしてください。
やったー!Alchemyを使用して初めてのイーサリアムのトランザクションを送信しました 🎉
このガイドに関するフィードバックや提案については、Alchemyのディスコード (新しいタブで開きます)でElanにメッセージを送ってください!
元々はAlchemyによって公開されました。