はじめに
web3サービスを展開している企業、どんどん増えてますね!
いまいちよく分からない、という方もたくさんいると思いますが、まずは実際に触れてみる、というところからスタートしましょう
この記事では、Dockerを使って、Polygonのテストネット(Mumbai)にトークンを発行してみます。
※2023年5月時点の情報です
この記事のソースコードをGitにプッシュしてあるので、こちらも参考にしてください。
この記事の概要
- Dockerで環境構築をする
- Polygonのテストネット(Mumbai)にトークンをデプロイする
- MetaMaskでトークンを確認する
それでは、やってみましょう!
事前準備
Metamaskの用意
Chromeにインストールする
まずは、トークン発行用のアカウントを用意します。
MetaMaskは仮想通貨のデジタルウォレットで、トークンを受け取ったり、他のウォレットに送信したりすることができます。
Chromeの拡張機能として追加できるので、公式サイトから追加しましょう。
ウォレットの秘密鍵を取得する
追加が完了したら、以下の手順でアカウントを作成して、秘密鍵を控えておいてください。
- テスト用に、新規アカウントを作成
- 設定から秘密鍵をコピーして控えておく
秘密鍵は、アカウントの詳細からコピーできます。
※秘密鍵は、自分以外の人に知られないようにしてください。


- Mumbaiネットワークの追加
デフォルトではMumbaiネットワークが選択できないので、手動で追加します。
Polygonの公式サイトで案内しているので、Add the Polygon network manually
のMumbai-Testnet
を選択し、ネットワークを追加しましょう。
MetaMaskでネットワークを追加
をクリックして、ネットワーク名、RPC URLなど、案内に従って設定してください。



Faucetの取得
トークンをデプロイする際には、ガス代(ネットワークの利用料のようなもの)がかかります。
テストネットでは、少額のトークンをもらうことができ、これはFaucetと呼ばれています。
MumbaiのFaucetを自分のウォレットで受け取る
以下の手順で、Faucetを受け取りましょう。
- PolygonのFaucetサイトにアクセス
- Networkは
Mumbai
を選択 - Select Tokenは
MATIC Token
を選択 - Wallet Addressに自分のウォレットのパブリックアドレスを入力
- Submitをクリック
- 確認画面が表示されるので、
Confirm
をクリック - Request Submittedが表示されたらOK
- 1〜2分後にウォレットに届くので、確認しましょう




正常に受け取れていれば、MATICが増えています。
このMATICを使って、Mumbaiへのデプロイを行います。

infuraでAPI Keyを取得
infuraは、ブロックチェーンのネットワーク(例:Ethereum)にアクセスして、その機能を利用できるサービスを提供しています。これにより、開発者は簡単にブロックチェーン技術を使ったアプリケーションを開発することができます。
- infraでアカウントを作成する
- 「API Keys」で「CREATE NEW API KEY」をクリック
a. NETWORKは「Web3 API」を選択する
b. NAMEを入力 - 「API Keys」で作成したAPIをクリック。API Keyをコピーして、控えておく
- EndpointsでPolygonが有効になってない場合は「ACTIVATE ADD ON」をクリック。フリープランを設定する。

Dockerのインストール
Docker環境が無い場合は、Dockerからインストールしてください。
Mumbaiネットワークでトークン発行
環境構築
プロジェクトディレクトリの作成
mkdir polygon-based-token-docker
cd polygon-based-token-docker
以降、このディレクトリ配下で作業を行います。
package.jsonの作成
package.jsonは、システムの依存関係を設定するファイルです。
バージョンを明確にしておくことで、同じ環境を構築することができます。
{
"dependencies": {
"@truffle/hdwallet-provider": "^1.7.0",
"@openzeppelin/contracts": "^4.8.3",
"truffle": "^5.4.21"
},
"scripts": {
"develop": "truffle develop --host 0.0.0.0 --port 8545",
"deploy-mumbai": "truffle migrate --network mumbai"
}
}
Truffleは、ブロックチェーン上で動作するプログラム(スマートコントラクト)を作るためのツールです。これを使うことで、開発者は簡単にスマートコントラクトを書いたり、テストしたり、デプロイ(公開)したりすることができます。
Dockerfileの作成
すでに用意されたDockerイメージもあるのですが、せっかくなので、Dockerfileから作成しましょう。
プロジェクトディレクトリにDockerfile
を作成し、以下の内容を記述します。
FROM node:14
# 作業用のディレクトリを作成する
RUN mkdir -p /app
WORKDIR /app
# ローカルのファイルを全てコンテナの/appにコピーする
COPY . /app
# package.jsonの設定に従って、依存関係をインストールする
RUN npm install
# package.jsonの"script"に書かれたコマンドを、Mumbaiネットワークで実行する
# デプロイテスト用(トークンが仮想ネットワーク上にデプロイされる)
# CMD ["npm", "run", "develop"]
# Mumbaiへのデプロイ用(トークンがMumbaiネットワークにデプロイされる)
CMD ["npm", "run", "deploy-mumbai"]
.envの作成
プロジェクトディレクトリに.env
を作成します。
WALLET_PRIVATE_KEY
には事前準備で作成したMetamask送信用アカウントの秘密鍵を設定します。API_KEY
には、事前準備で作成したinfuraのAPI Keyを設定します。
WALLET_PRIVATE_KEY=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
API_KEY=xxxxxxxxxxxxxxxxxxxxx
truffle-config.jsの作成
Truffleの設定ファイルを作成します。
const HDWalletProvider = require("@truffle/hdwallet-provider");
// 環境変数からウォレットの秘密鍵を取得
const privateKey = process.env.WALLET_PRIVATE_KEY;
// 環境変数からAPIキーを取得
const API_KEY = process.env.API_KEY;
module.exports = {
networks: {
develop: {
host: "127.0.0.1",
port: 8545,
network_id: "*",
},
mumbai: {
provider: () => new HDWalletProvider(privateKey, "https://rpc-mumbai.maticvigil.com"),
network_id: 80001,
confirmations: 2,
timeoutBlocks: 200,
skipDryRun: true,
},
},
compilers: {
solc: {
version: "0.8.0",
},
}
};
トークンのスマートコントラクト用ファイル
トークンのスマートコントラクト用ファイルを作成します。contracts
ディレクトリを作成し、contracts/MyToken.sol
ファイルを実装します。今回は、ERC20トークンのサンプルコードを使用してコントラクトを作成します。
pragma solidity ^0.8.0;
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
contract MyToken is ERC20 {
constructor(uint256 initialSupply) ERC20("MyToken", "MTK") {
_mint(msg.sender, initialSupply);
}
}
コントラクトのデプロイ用ファイル
migrations
ディレクトリを作成し、migrations/2_deploy_contracts.js
ファイルを実装します。
const MyToken = artifacts.require("MyToken");
module.exports = function (deployer) {
deployer.deploy(MyToken, "1000000000000000000000000"); // 1,000,000 tokens with 18 decimal places
};
イメージのビルド
プロジェクトディレクトリで、以下のコマンドを実行してDockerイメージをビルドします。(ビルドに2分くらいかかります)
何度かやりなおすこともあるので、念のため、コンテナを削除してからビルドします。コンテナが無ければエラーメッセージが表示されますが、気にしなくて大丈夫です。
docker rm polygon-based-token-container
docker build -t polygon-based-token-deploy .
docker images
コマンドで以下のようにイメージができていたら成功です。
$ docker images | grep polygon-based-token-deploy
polygon-based-token-deploy latest c0760a3a75d9 4 minutes ago 1.37GB
Dockerコンテナの実行
ビルドが完了したら、以下のコマンドでDockerコンテナを実行します。
docker run -it --env-file .env --name polygon-based-token-deploy-container polygon-based-token-deploy
このコマンドでDockerコンテナ内でTruffleが起動し、Mumbaiネットワーク(Polygonのテストネット)へトークンのデプロイが行われます。
デプロイが成功すると、以下のような内容が出力されると思います。
解説をコメントで記載しているので、若干読みにくいかもしれません。ご容赦ください
$ docker run -it --env-file .env --name polygon-based-token-deploy-container polygon-based-token-deploy
# deploy-mumbaiの設定を使って
# Mumbaiネットワークへのデプロイコマンドを実行
> @ deploy-mumbai /app
> truffle migrate --network mumbai
# Truffleがソースコードをコンパイルしている
Compiling your contracts...
===========================
> Compiling ./contracts/MyToken.sololc-bin. Attempt #1
> Compiling @openzeppelin/contracts/token/ERC20/ERC20.sol
> Compiling @openzeppelin/contracts/token/ERC20/IERC20.sol
> Compiling @openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol
> Compiling @openzeppelin/contracts/utils/Context.sol
> Compilation warnings encountered:
# コンパイル中に警告が検出された
# この場合、SPDXライセンス識別子がソースファイルに含まれていないという警告です。
# この警告は、コントラクトの機能に影響を与えませんが、公開前には修正を検討してください。
Warning: SPDX license identifier not provided in source file. Before publishing, consider adding a comment containing "SPDX-License-Identifier: <SPDX-License>" to each source file. Use "SPDX-License-Identifier: UNLICENSED" for non-open-source code. Please see https://spdx.org for more information.
--> project:/contracts/MyToken.sol
# スマートコントラクトをコンパイルして、Mumbaiネットワークに
# デプロイするプロセスが始まっていることを示しています
> Artifacts written to /app/build/contracts
> Compiled successfully using:
- solc: 0.8.0+commit.c7dfd78e.Emscripten.clang
⠸ Fetching solc version list from solc-bin. Attempt #1
⠴ Fetching solc version list from solc-bin. Attempt #1
Starting migrations.... Attempt #1.
======================
> Network name: 'mumbai'
> Network id: 80001
> Block gas limit: 20000000 (0x1312d00)
# 2_deploy_contracts.jsの実行
2_deploy_contracts.js
=====================
⠦ Fetching solc version list from solc-bin. Attempt #1
Deploying 'MyToken'. Attempt #1.
-------------------
# この処理が行われたトランザクションのハッシュ値
> transaction hash: 0x42a97704f8efaef194de6ecddfd4903e8b7b7cbd31dd533d12c9b06af63336ec
# トランザクションが含まれるブロック数と
# トランザクションが完了するまでにかかった時間
> Blocks: 2 Seconds: 4lc-bin. Attempt #1
# Mumbaiにデプロイしたコントラクトのアドレス
> contract address: 0x367d5FA9c8F9875bF4221CA0E25A7362211Ad997
# ブロックチェーン上でのブロックの位置
> block number: 35257753 4
# ブロックが生成された日時のUNIXタイムスタンプ
> block timestamp: 1683377580
# トランザクションを送信したアカウントのアドレス
> account: 0xe6b1af45f7cF652aC02d819228e622EFB1b3Df10
# アカウントの残高
> balance: 0.189641197915978606
# トランザクション実行に使用されたガス量
> gas used: 1150978 (0x119002)
# ガスの単価(gwei単位)
> gas price: 2.500000016 gwei
# トランザクションで送信されたETHの量
> value sent: 0 ETH
# トランザクションの総コスト(ETH)
> total cost: 0.002877445018415648 ETH
Pausing for 2 confirmations...
-------------------------------
# 確認回数(ブロック承認の数)と確認されたブロックの番号
> confirmation number: 2 (block: 35257755)ttempt #1
# デプロイメント関連のデータを保存
> Saving artifactsr. Attempt #1.
-------------------------------------
# トランザクションの総コスト(ETH)
> Total cost: 0.002877445018415648 ETH
これで、MumbaiにMyTokenコントラクトがデプロイされました。
MetaMaskで確認
では最後に、MetaMaskでトークンを確認してみましょう。
トークンをインポート
MetaMaskを起動すると、下部に「トークンをインポート」というリンクがあるので、クリックしてください。
以下の画面が表示されます。
トークンコントラクトアドレス
に、先ほどの実行結果から、contract address
の値をコピーして入力します。
コントラクトアドレスを入力すると、トークンシンボルとトークンの少数桁数が自動で入力されます。
カスタムトークンを追加
をクリックすると、以下の画面になります。
トークンをインポート
をクリックすると、以下のような画面が表示されます。
トークンが発行されて、自分のウォレットに追加されたことを確認できましたね!
このトークンは、MetaMaskで他のウォレットに送信することができます。
他のウォレットに送信したものを確認する場合は、受け取り側のウォレットで今回と同様に、Mumbaiネットワークの追加とトークンのインポートを行ってください。
PolygonScanで確認
PolygonScanでコントラクトアドレスを検索し、実際にデプロイされていることを確認できます。
以下は、私が発行したトークンの結果です。
まとめ
Dockerを使って、Mumbai(Polygonのテストネット)に独自トークンをデプロイする方法を解説しました。
今回はERC20をそのまま利用しましたが、本来、スマートコントラクトは様々なカスタマイズを行うのが醍醐味です。特定のNFT保有者だけが受け取れるようにすることもできるので、用途に応じて「MyToken.sol」をカスタマイズしてみましょう。そうすることにより、web3をより深く理解できると思います。
私もカスタマイズしてみようと思うので、いい感じのカスタマイズができたら、また共有しようと思います!