MetaMaskを使わずに署名する方法
javascriptでMetaMaskを使ってトランザクションに署名する事は良くあると思いますが、開発の際はMetaMask以外から署名したいという時もあるのではないでしょうか。
たとえば、バックエンドで定期的にコントラクトを叩きたい時とか、いちいちMetaMaskの認証をするのは面倒なので勝手にやってほしい。そんな時に使えるやり方を紹介します。 単純にイーサを送信するケースとコントラクトを叩くケースの二つを紹介します。
ライブラリのバージョンは以下です。
ethereumjs-tx: ^2.1.2
ethers: ^5.6.2
秘密鍵やAPIKEYはdotenvに置いてあります。
イーサをsendTransactionする
単純にイーサを特定のアドレスに送りたい時に使うコードです。ethereumjs-txを使う事でできます。 ここではetherscanのAPIKEYをProviderに設定していますが、何も設定しなくても問題ないです。
const Tx = require("ethereumjs-tx").Transaction; const ethers = require("ethers"); require("dotenv").config(); let to = '送り先アドレス'; let from = '送り元アドレス'; // etherscanのapikeyは必須ではないです。 let provider = ethers.getDefaultProvider('rinkeby',{'etherscan': process.env.apiKey}); const sendEths = async ( to, from, fromPrivateKey, value, gasPrice, gasLimit = ethers.utils.hexlify(21000), ) => { const txCount = await provider.getTransactionCount(from); const txData = { nonce: ethers.utils.hexlify(txCount), to, value: ethers.utils.parseEther(value).toHexString(), gasLimit, gasPrice, } const tx = new Tx(txData, { chain: 'rinkeby', hardfork: 'petersburg' }); // 署名 tx.sign(Buffer.from(fromPrivateKey, "hex")); console.log('signed.') // トランザクションを送る const { hash } = await provider.sendTransaction( "0x" + tx.serialize().toString("hex") ); console.log('send transaction.'); // マイニングされるまで待機 await provider.waitForTransaction(hash); console.log('did it.') }; sendEths(to, from, process.env.PRIVATE_KEY, '0.01', ethers.utils.hexlify(2000000000), ethers.utils.hexlify(21000) );
コントラクトを叩く
コントラクトを叩くには以下のような感じ。 ethers.Walletを使って署名します。
import { ethers } from 'ethers'; // スマートコントラクトのJSONファイルをインポート import contract from './contract/Contract.json'; const abi = contract.abi; const serverProvider = ethers.getDefaultProvider('rinkeby',{'etherscan': process.env.API_KEY}); const txCount = await serverProvider.getTransactionCount(from); // イーサリアムアドレスの秘密鍵を設定 const wallet = new ethers.Wallet(process.env.PRIVATE_KEY, serverProvider); // コントラクトを設定 const anyContract = new ethers.Contract(contractAddress, abi, wallet); const overrides = { nonce: ethers.utils.hexlify(txCount), gasLimit: ethers.utils.hexlify(gasLimit), gasPrice: ethers.utils.hexlify(gasPrice), } // コントラクトの好きな関数を実行 const tx = await anyContract.function(args, overrides); tx.wait();