LoginSignup
8
5

More than 1 year has passed since last update.

【ERC20】自作トークン備忘録~メインネットで管理できるまで

Last updated at Posted at 2021-07-19

Ⅰ. はじめに

ERC20規格の自作トークンを作成した際の手順を残した備忘録です。流れに沿えば、初めてのかたでも手軽にオリジナルトークンを作成できる内容となっています。詳細な説明等は今回省いた点も多いので、適宜他記事やブログご参考いただければと思います。なお、Truffleを利用しての関連記事は比較的多いので、この度は主にhardhatのフレームワーク利用しています。

Ⅱ. 環境

更新日:2021/07/
OS:Windows10
開発環境:Visual Studio

Ⅲ. 作業概要

1. 準備編

(1)npmインストール

(2)プロジェクトディレクトリ作成

(3)OpenZepplinインストール

(4)hardhatインストール

(5)metamask設定とsecretファイル作成

(6)INFURAアカウント取得

(7)secretファイル作成

(8)開発用EHTを無料で入手

2. ファイル作成編

(1)contractsファイル作成

(2)contractsファイル(.sol)コンパイル

(3)hardhat.config.jsファイル作成

(4)scriptsファイル作成

(5)テスト用ファイル作成

3. テスト&デプロイ編

(1)Hardhatネットワークに接続

(2)hardhat.config.jsにネットワーク情報追加

(3)テスト

(4)デプロイ

(5)metamaskアセット表示

4. 仕上編

(1)Solidityソースコードの登録

(2)etherscanでの所有権表明

(3)トークン詳細登録

参考公式サイト

Ⅳ. 作業詳細

1. 準備編

(1)インストール

公式:https://nodejs.org/en/
JavaScript用のパッケージ。推奨版でおそらく良い。

(インストール先例)
C:\Users\mydir\AppData\Roaming\npm
バージョンの確認
$ node --version
v14.17.2

(2)プロジェクトディレクトリ作成

// (例)Cドライブの下などに「h_tokens」などの名前でディレクトリを作成
$ mkdir h_tokens
// (例)あらかじめOSのコマンドラインで作成および当該ディレクトリに移動しておく
$ cd h_tokens

(3)OpenZepplinインストール

// token/package.jsonが作成される
$ npm init -f

$ npm install openzeppelin-solidity

// OpenZeppelinのContractsライブラリ最新更新分インストール
$ npm install --save-dev @openzeppelin/contracts

以下のディレクトリやファイルができる。
token/node_modules/…
token/package-lock.json

(4)hardhatインストール

$ npm install --save-dev hardhat

// ethersプラグイン&chaiインストール
$ npm install --save-dev @nomiclabs/hardhat-ethers ethers @nomiclabs/hardhat-waffle ethereum-waffle chai
// ガスレポーターインストール
$ npm install hardhat-gas-reporter --save-dev
// etherscanインストール
$ npm install --save-dev @nomiclabs/hardhat-etherscan
// ディレクトリとファイルを自動作成
$ npx hardhat

hardat.png
① 矢印キー上下↑↓で「Create a sample project」選択
② インストール先に新規作成したディレクトリ指定「Hardhat project root: » C:\Users\micro\h_tokens」
→'y'入力
以下のディレクトリやファイルができる。
contracts/Greeter.sol
scripts/sample-script.js
test/sample-test.js
.gitignore
hardhat.config.js

(5)metamaskアカウント取得

まずは検証用のmetamaskアカウントを新規作成する。

// ニーモニック(12語のセット・要保存!)発行
$ npx mnemonics
drama film snack motion …

metamaskをブラウザより起動し、「シークレット リカバリー フレーズでアカウントを復元する」より上記ニーモニックでアカウント設定。

※ニーモニックは安全かつ機密性をもって保管すること。

(6)INFURAアカウント取得

https://infura.io/
アカウント取得後「CREATE NEW PROJECT」して詳細を開く。
infura.png

(7)secretファイル作成

① 以下の形式のsecrets.jsonファイルを作成。

secrets.json
{
  "mnemonic": "drama film snack motion ...",
  "infuraApiKey": "JPV2..."
}

"mnemonic":取得したニーモニックをペースト。
"infuraApiKey":取得したProjectIDをペースト。

② 'hardhat.config.js'と同じディレクトリに置く。

なお、secretファイル安全かつ機密性をもって保管維持すること。
また、のちの工程でもinfura画面は参照するので見られるようにしておくこと。

(8)開発用EHTを無料で入手

以下のサイトでできる限り送付してもらう。Ropstenネットにはぜひ送ってほしい。
https://gitter.im/kovan-testnet/faucet
https://faucet.rinkeby.io/
https://blog.fukuball.com/dapp/faucet/
https://faucet.ropsten.be/
https://faucet.metamask.io/
https://goerli-faucet.slock.it/
※時間がかかったり、怪しいところもあるので自己責任で。

2. ファイル作成編

(1)contractsファイル作成

トークンの仕様を決めるメインファイル。

contracts/Greeter.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";

contract Greeter is ERC20 {
    constructor() ERC20("Greeter", "MMT2") {
        _mint(msg.sender, 222222222222 * 10 ** decimals());
    }
}

オリジナルのコントラクトを作成する場合、openzeppelinのウィザードを利用する方法が簡単である。
https://docs.openzeppelin.com/contracts/4.x/wizard
sample_wiz.jpg
Name : アセットの名称
Synbol : アセットのシンボル
Premint : 初期発行枚数
Mintable : 管理者の新規発行権限
Burnable : 管理者による発行済アセットの焼却権限
Pausable : 管理者によるシステム停止権限
Snapshots : 管理者による、ある一時点におけるスナップショット取得権限。
Permit : トークン所有者は、ガスを支払うことなく、第三者が自分のアカウントから転送できる。(!要調査不明点あり)
Ownable : すべての管理者が同じ権限を持つ。
Roles : 個々の管理者によって権限の範囲を個別に決めることができる。
Transparent : 調査中
UUPS : 調査中

※注意点
コントラクトの内容を充実させればさせるだけ、mainnetにデプロイする際のガス代が大幅にコスト高になる。(1ETHくらいになることZARA)

(2)contractsファイル(.sol)コンパイル

$ npx hardhat compile

成功すると以下のように表示される。
comp.png
※コントラクトファイルの内容を少しでも変更することあれば、その都度上記作業が必要。

(3)hardhat.config.jsファイル作成

hardhat.config.js
require("@nomiclabs/hardhat-waffle");
require('@nomiclabs/hardhat-ethers');
require("@nomiclabs/hardhat-etherscan");
require('@openzeppelin/hardhat-upgrades');
require("hardhat-gas-reporter");

task("accounts", "Prints the list of accounts", async (taskArgs, hre) => {
  const accounts = await hre.ethers.getSigners();

  for (const account of accounts) {
    console.log(account.address);
  }
});
/**
 * @type import('hardhat/config').HardhatUserConfig
 */
module.exports = {
  solidity: "0.8.4",
};

(4)scriptsファイル作成

コントラクトをネットワークにデプロイするために必要。
https://docs.openzeppelin.com/learn/deploying-and-interacting#deploying-a-smart-contract

scripts/sample-script.js
const hre = require("hardhat");

async function main() {

  const Greeter = await hre.ethers.getContractFactory("Greeter");
  const greeter = await Greeter.deploy(); // 引数は入れないほうがよさそう
  await greeter.deployed();
  // コントラクトアドレス
  console.log("Greeter deployed contracts address to:", greeter.address);
 // TXアドレス
  console.log("Greeter deployed hash to:", greeter.deployTransaction.hash);
}

main()
  .then(() => process.exit(0))
  .catch((error) => {
    console.error(error);
    process.exit(1);
  });

(5)テスト用ファイル作成

test/sample-test.js
const { expect } = require("chai");

describe("Greeter contract", function () {
  it("Deployment should assign the total supply of tokens to the owner", async function () {
    const [owner] = await ethers.getSigners();

    const greeter = await ethers.getContractFactory("Greeter");

    const hardhatToken = await greeter.deploy();

    const ownerBalance = await hardhatToken.balanceOf(owner.address);
    expect(await hardhatToken.totalSupply()).to.equal(ownerBalance);
  });
});

3. テスト&デプロイ編

(1)Hardhatネットワークに接続

// ウォレットまたはDappをHardhatネットワークに接続する
$ npx hardhat node

接続に成功すると以下形式でずらっと表示される。

Accounts
========
Account #n: 0xf39fd6e51aad88f6f………fffb92266 (10000 ETH)
Private Key: 0xac0974bec39a17e36ba4a6b4d238ff94………
・
・
・

作業中継続して起動させておく必要あり。コマンドをもう一つ別に開き作業を続ける。(この時再度作業ディレクトリにcd…で変更)

(2)Ropsten,Rinkeby,Mainnetネットワークに接続

注意!
本番環境であるMainnetにデプロイする前にRopsten,Rinkebyでそれぞれテストをする。(便宜上、この記事ではRopstenから説明する。)
それそれのネットワーク解説はこちら : https://docs.openzeppelin.com/learn/connecting-to-public-test-networks#testnet-list

「2. ファイル作成編-(5)hardhat.config.jsファイル作成」に以下の内容を書き足す。
https://docs.openzeppelin.com/learn/connecting-to-public-test-networks#configuring-the-network
ネットワーク接続先によってネットワーク名および、(infuraキャプチャ画面の緑のアンダーラインURL)の部分を切り替える。

hardhat.config.js(ropsten)の場合
+ const { infuraApiKey, mnemonic } = require('./secrets.json');
...
  module.exports = {
+    networks: {
+     ropsten: {
+       url: `https://(infuraキャプチャ画面の緑のアンダーラインURL)/${infuraApiKey}`,
+       accounts: { mnemonic: mnemonic },
+     },
+   },
...
};

(3)テスト編

ファイルを個別指定しないと、testディレクトリにあるファイルがすべて精査の対象となること注意。

$ npx hardhat test
// 個別指定する場合は $ npx hardhat test test/sample-test.js

成功すると、ガス代情報と合わせ以下のように表示される。
testok.png
参考
https://hardhat.org/plugins/hardhat-gas-reporter.html
https://dapps.gamewith.jp/?p=90

(4)デプロイ

① --networkのパラメータを検証対象のネットワーク名に上書き。(例 : Ropsten)
② デプロイ

// デプロイ
$ npx hardhat run scripts/sample-script.js --network ropsten
Greeter deployed contracts address to: 0xEA3B81eDc45726CE6A3314bd3…cA200A……
Greeter deployed hash to: 0xb5cd97870c97934d0765…3f59f4aa6649fbbb6f0…f7fa94c…64dee9………

③ トランザクションが通っているかを確認。
ropsten : https://ropsten.etherscan.io/
デプロイした時の「Greeter deployed hash to: 」右のTXアドレスを検索窓に貼り付けて検索。
su.png
成功していることを確認。

(5)metamaskアセット表示

① 「トークンの追加」を押下。
mts.png
② デプロイした時の「Greeter deployed hash to: 」右のTXアドレスを追加して「次へ」押下。
mts2.png
③ 最終的にアセットのリストに追加される。

他、Rinkebyについても同じテスト、動作確認、作業を実施しておく。

hardhat.config.js(rinkebyの場合)
+ const { infuraApiKey, mnemonic } = require('./secrets.json');
...
  module.exports = {
+    networks: {
+     rinkeby: {
+       url: `https://infuraキャプチャ画面の緑のアンダーラインURL/${infuraApiKey}`,
+       accounts: { mnemonic: mnemonic },
+     },
+   },
...
};

rinkeby : https://rinkeby.etherscan.io/

本番環境ネットワーク(mainnet)も同様につつがなく作業。

hardhat.config.js(mainnet)
+ const { infuraApiKey, mnemonic } = require('./secrets.json');
...
  module.exports = {
+    networks: {
+     mainnet: {
+       url: `https://infuraキャプチャ画面の緑のアンダーラインURL/${infuraApiKey}`,
+       accounts: { mnemonic: mnemonic },
+     },
+   },
...
 };

mainnet : https://etherscan.io/

4. 仕上編

(1)Solidityソースコードの登録

コントラクトをメインネットにデプロイ後、ソースコードの確認をする。(SolidityコードをEtherscanやEtherchainなどのサードパーティに送信)

参考
https://docs.openzeppelin.com/learn/preparing-for-mainnet
https://hardhat.org/plugins/nomiclabs-hardhat-etherscan.html

https://etherscan.io/ アカウント取得
② login後、「API-KEYs」にて新規APIキー発行。
③ 以下のようなファイルを作成。

etherscanapikey.json
{
  "etherscanApiKey": "(APIキー)…YQFH…VVPY3…XMA4K…FWR32…"
}

'hardhat.config.js'と同じディレクトリに置く。
④ 'hardhat.config.js' に以下の記述を足す。

hardhat.config.js
...
const { etherscanApiKey } = require('./etherscanapikey.json');
...
module.exports = {
  networks: {
    mainnet: { ... }
  },
  etherscan: {
    apiKey: etherscanApiKey
  }
};

⑤ verifyする

$ npx hardhat verify --network mainnet --contract contracts/Greeter.sol:Greeter (コントラクトアドレス付加)0x0c…88317e2d7304887…626dcc…c3c34… (引数)1

もしも引数がなければ(不要であれば)以下のような赤字エラーが表示される。

Error in plugin @nomiclabs/hardhat-etherscan: The constructor for contracts/Greeter.sol:Greeter has 0 parameters
but 1 arguments were provided instead.

その時は引数は削除する。成功すると以下のような表示となる。

Compiling 1 file with 0.8.4
Successfully submitted source code for contract
contracts/Greeter.sol:Greeter at 0x0c…88317e2d7304887…626dcc…c3c34…
for verification on Etherscan. Waiting for verification result...

Successfully verified contract Greeter on Etherscan.
https://etherscan.io/address/0x0c…88317e2d7304887…626dcc…c3c34…#code

なお、ブラウザで以下URLにアクセスすると、etherscan画面でも確認できる。
https://etherscan.io/address/0x0c…88317e2d7304887…626dcc…c3c34…#code

(2)etherscanでの所有権表明

ログイン後、以下画面に遷移
https://etherscan.io/myverify_address
「Add」ボタンでコントラクトアドレスを入力し、画面の指示に従いながら先に進む。
参考
https://info.etherscan.com/how-to-verify-address-ownership/

(3)トークン詳細登録

トークン詳細画面に戻り
https://etherscan.io/token/0x0c…88317e2d7304887…626dcc…c3c34…

Profile Summary の [Edit] リンクからプロフィールをなるべく詳細に登録して、etherscan 運営からのお便りを待つ。

一旦ここで今回は終了!

参考公式サイト

https://ethereum.org/ja/developers/
https://www.trufflesuite.com/
https://openzeppelin.com/
https://vittominacori.github.io/erc20-generator/

8
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
5