こんにちは、たいきです(@taiki_16_k)
Solidityを勉強しています。
今回は、「Ethers.js」というライブラリを使ってコントラクトをデプロイする方法について書きます。
前までは「Web3.js」というライブラリが多く使われており、僕も始めはこっちを使っていました。
しかし、最近だとEthers.jsを使う人が増えており、実際使ってみてもこちらの方がコードがシンプルで使いやすいです。
そこで今回は、実際にEthers.jsを使ってスマートにコントラクトをデプロイする方法を解説します。
なお、今回はこちらの動画を参考にさせて頂きましたm(_ _)m
※開始位置もあわせてあります。
Ether.jsとは?
公式ドキュメントからの引用です。
The ethers.js library aims to be a complete and compact library for interacting with the Ethereum Blockchain and its ecosystem. It was originally designed for use with ethers.io and has since expanded into a more general-purpose library.
ethers.jsライブラリは、Ethereum Blockchainとそのエコシステムと対話するための完全でコンパクトなライブラリであることを目的としています。元々はethers.ioで使用するために設計されましたが、その後、より汎用的なライブラリに拡張されています。
つまり、開発者がEthereumブロックチェーンとやりとりをすることができるようになるJavascriptのライブラリです。
コントラクトをデプロイするまでの流れ
デプロイまでの流れは以下の通り。
- Solidityでコントラクトを書く
- ethers.js, solc-jsをインストール
- solcでコンパイルする
- deployファイルを作る
- デプロイ!
それぞれ順番に解説していきます。
①コントラクトを書く
まずはSolidityでコンラクトを書いていきましょう。
今回はデプロイのやり方の記事で、コントラクトの内容は関係ないので以下のような簡単なコントラクトをデプロイしてみます。
//SPDX-License-Identifier: MIT
pragma solidity ^0.8.15;
contract Example {
uint256 public favoriteNumber;
function setFravoriteNumber(uint256 _favoriteNumber) public {
favoriteNumber = _favoriteNumber;
}
}
②ethers.js, solc-jsをインストール
次に、ethers.jsとsolc-jsをインストールしていきましょう。
なお、solc-jsとはSolidityのためのコンパイラのことです。
ちなみにコンパイラとは、プログラムをコンピュータが読めるように変換してくれるものです。
この場合、Solidityで書いたプログラムは人間に読めますが、EVM(Ethereum Virtual Machine)は読めません。なのでコンパイルして読めるようにしてあげる必要があります。
今回はインストールにyarnを使っています(もちろんnpmでもOK)
yarnを使ったことのない人は下記コマンドで使えるようになります。
corepack enable
プロジェクトディレクトリに移動して、
yarn init
このコマンドでpackage.jsonとyarn.lockファイルの2つができます。
package.jsonにインストールしたもののバージョンが一覧で表示されています。
続いて、Eathers.jsとsolcをインストールします。
なお、ついでにnode
yarn add ethers
yarn add solc
また、今回はブロックチェーンのローカル開発環境としてGanacheを使うのでそちらも準備してください。
Ganacheについてはまた別記事をUPする予定。
③solcでコンパイルする
solcをインストールしたら、早速コンパイルしましょう!
コンパイルをして、ABIとバイナリーを書き出すのは下記コマンドでできます。
yarn solcjs --bin --abi --include-path node_modules/ --base-path . -o . Example.sol //最後はコントラクトのファイル名
長いのでpackage.jsonファイルのスクリプトに追加しておくと楽に実行できます。
{
"name": "example",
"version": "1.0.0",
"main": "index.js",
"license": "MIT",
"dependencies": {
//インストールしたライブラリ
},
"scripts": {
//コマンドを追加
"compile": "yarn solcjs --bin --abi --include-path node_modules/ --base-path . -o . Example.sol"
}
}
このようにscripts以下に書いてあげると、yarn compile
と入力するだけで次から先ほどのコマンドが実行できます。
先ほどのコマンドを実行すると、”Example-sol-Example.abi”と、”Example-sol-Example.bin”という2つのファイルが生成されます。
“Example-sol-Example.abi”はABIが書かれたファイルです。
“Example-sol-Example.bin”はバイナリーが書かれたファイルです。
どちらもethers.jsでコントラクトを取り込むときに使います。
.abiファイルのABIが見づらい場合は、VSCodeなら一度ファイルの拡張子を.jsonにしてあげて、Viewタブ<Command Pallet<Format Document with… からコードを整形してくれるextentionを選んであげてください。
僕はPrettierを使っています。その後拡張子を.abiに戻すのを忘れずに。
これでデプロイに必要な準備が整いました!
次は早速deployのためのファイルを書いていきます。
④デプロイファイルを作る
プロジェクトディレクトリ直下にdeploy.jsファイルを作成。
ファイルの中身は下記の通り。
const ethers = require("ethers");
const fs = require("fs-extra");
async function main() {
// GanacheのRPCサーバーURL => http://0.0.0.0:8545 or 7545
const provider = new ethers.providers.JsonRpcProvider("http://0.0.0.0:8545");//RPC_URLも本当は.envに書くべき
const wallet = new ethers.Wallet(
"PRIVATE_KEY", //デプロイするウォレットのプライベートキー(本当は.envファイルなどにまとめておくべき)
provider
);
const abi = fs.readFileSync("./Example_sol_Example.abi", "utf8");
const binary = fs.readFileSync(
"./Example_sol_Example.bin",
"utf8"
);
//ContractFactoryにABI, バイナリー, ウォレットを渡してあげる
const contractFactory = new ethers.ContractFactory(abi, binary, wallet);
console.log("Deploying, please wait...");
//コントラクトをデプロイ!
const contract = await contractFactory.deploy();
}
main()
.then(() => {
process.exit(0);
})
.catch((error) => {
console.log(error);
process.exit(1);
});
プライベートキーに関してはGanacheのウォレットからコピーしてきてください。
※なお、通常プライベートキーはデプロイファイルに直接書いたりしません。
普通はdotenvなどを用いて.envファイルに記述します。さらにいうと、暗号化しておくともっと安全ですが、今回はデプロイが目的なので簡便化のためここは省きます。
本番環境で、実際にETHなどが入っているウォレットでやる場合は絶対にプライベートキーをGithubなどにUPしないように注意しましょう。
Ethers.jsにはContractFactoryという便利な関数があり、ここにABI, Binary, ウォレットを渡してあげればOKです。
ABI, Binaryに関しては先ほどsolc-jsで作成しましたね。
ContractFactoryに関する公式ドキュメント >>
⑤デプロイ!
nodeコマンドで実行してみるとコントラクトをデプロイできます。
node deploy.js
おまけ:transactionの中身を見る
下記のようにdeployTransactionや、transactionReceiptを使ってあげるとトランザクションの中身を見ることができます。
なお、deployTransactionは、ブロックが承認されている間のステータスであるのに対し、transactionReceiptはブロック承認後のレシートであるといった違いがあります。
const ethers = require("ethers");
const fs = require("fs-extra");
async function main() {
const provider = new ethers.providers.JsonRpcProvider("http://0.0.0.0:8545");
const wallet = new ethers.Wallet(
"PRIVATE_KEY",
provider
);
const abi = fs.readFileSync("./Example_sol_Example.abi", "utf8");
const binary = fs.readFileSync(
"./Example_sol_Example.bin",
"utf8"
);
const contractFactory = new ethers.ContractFactory(abi, binary, wallet);
console.log("Deploying, please wait...");
const contract = await contractFactory.deploy();
//ここから
const transactionReceipt = await contract.deployTransaction.wait(1);
console.log("Here is the deployment transaction: ");
console.log(contract.deployTransaction);
console.log("Here is the transaction receipt: ");
console.log(transactionReceipt);
}
main()
.then(() => {
process.exit(0);
})
.catch((error) => {
console.log(error);
process.exit(1);
});
終わりに
いかがでしたでしょうか。
ethers.jsとsolc-jsを使うと、とてもシンプルにコントラクトがデプロイできて非常に便利だと思います。
個人的には、web3.jsよりもわかりやすくていいなぁと思います。
今回はここまでです。