MetaMaskなしでSmartContractを実行する


概要

スマホのブラウザでは、お馴染みの拡張機能MetaMaskが使えません。
(DAppsブラウザ機能を搭載するウォレットアプリは各社から出ていますが…)
そこで、web3.jsを使ってMetaMaskなしでスマートコントラクトのメソッドを呼んでみたいと思います。
web3のバージョンは1.2.1、ノードはInfuraのものを使います。

手順

web3とmyContractは適当に準備します。また、awaitを使うのでasync function内で実行する必要があります。

// privateKeyをインポート
let account = web3.eth.accounts.privateKeyToAccount(privateKey);
// メソッドのABIをエンコード
let encodedABI = myContract.methods.myMethod(param).encodeABI();
// gas量を適当に計算
let gasAmount = await myContract.methods.myMethod(param).estimateGas({from:account.address}) + 5000;
// 宛先にコントラクトのアドレス、データにエンコードしたABIをセットしたトランザクションを作成
let tx = { to: myContract.options.address, data: encodedABI, gas: gasAmount };
// トランザクションに署名して、そのままnodeに投げる
let signedTx = await account.signTransaction(tx);
let re = await web3.eth.sendSignedTransaction(signedTx.rawTransaction);

最初に秘密鍵をインポートしてますが、インポートせずに署名のところで以下のようにしても問題ないです。

let signedTx = await web3.eth.accounts.signTransaction(tx, privateKey)

web3.eth.personal.signTransaction()

上記コードではweb3.eth.accounts.signTransaction()を使いましたが、ドキュメントにはweb3.eth.personal.signTransaction()も存在します。
ネーミングが逆な気がしてしまうのですが、accountsはローカルPC上で署名を行い、personalはノード上のアカウントで署名を行うという違いがあります。
ちなみに、今回使用しているInfuraのノードはpersonalをサポートしていません。