ゼロから始めるERC-20トークン開発~Ethereumで自分だけのデジタル資産を創造する~

本記事では、Ethereumのトークン規格「ERC-20」を使って、Ethereumのテストネットである「Sepolia」でオリジナルのトークンを発行する手順を解説します。

 こんにちは。ホールセール基幹システム部の柴田です。普段は、債券の約定管理等を行う証券会社向けシステムの設計・開発を行っています。過去にはセキュリティ・トークンを扱うためのウォレット(注1)と呼ばれるシステムの開発・保守も担当していました。
 プロダクトソリューション部の石塚です。普段は、データマネジメントやAI領域の技術を活用した自社プロダクトの企画・開発に加え、機関投資家向けのデータ基盤構築の支援や金融事業会社向けのプリセールスを行っています。

 大和総研ではEthereumなどのパブリックブロックチェーンを活用したWeb3の広がりを見据え、Web3分野の研究開発を行う専門のプロジェクト「Web3 Lab」を発足しました。社内のさまざまな部署から公募で選ばれたメンバーがWeb3 Labに参加しており、私たちもその一員として日々の業務と兼務しながら研究開発に取り組んでいます。

 Web3 Labではスマートコントラクトを使った開発も行っており、今回はEthereumのトークン規格「ERC-20」を使ってオリジナルのトークンを発行する手順について解説します。
本記事が、スマートコントラクトを使った開発を検討している皆さまの参考になれば幸いです。

1 ERC-20とは

 ERC-20のERCとはEthereum Request for Commentの略で、Ethereumの機能やプロセスの改善に関する提案が書かれたドキュメントであるEIP(Ethereum Improvement Proposal)において、スマートコントラクトなどのアプリケーションに関する提案がまとめられたカテゴリの名称です。
 ERC-20はEthereum上でファンジブルトークン(Fungible Token)を実装するためのスマートコントラクトに関する規格で、Fabian Vogelsteller氏とVitalik Buterin氏によって提案されました(注2)。ERC-20には、ファンジブルトークンのスマートコントラクトを開発する際に実装すべきメソッドやその引数、戻り値などが定義されています。20という数字はGitHubのissue番号が20だったことが由来となっています。

2 ファンジブルトークンとは

 ファンジブルトークンという用語は、ファンジブル(Fungible)とトークン(Token)に分解できます。
 まず、ファンジブルについてです。ファンジブルの意味は「代替可能であること」で、その対義語として「代替不可能であること」を意味するノンファンジブル(Non-Fungible)があります。この世に同じ価値を持つものが複数存在するのであればファンジブル、唯一無二で複製ができないものであればノンファンジブルです。例えば、現金の1万円札はどの1枚でも同じ価値を持ち、1万円札同士を交換したとしても価値は同じであるため、ファンジブルであるといえます。一方、直筆のサイン色紙のように唯一無二で代替できないものはノンファンジブルといえます。
 次に、トークンです。トークンという言葉は、一般的には「しるし、証書」などを指しますが、ブロックチェーンの文脈ではBitcoin(略称BTC、以降BTCと表記)やEther (略称ETH、以降ETHと表記)などの「ブロックチェーン上で何らかの価値や権利を表すデジタル資産」を指します。Bitcoinというブロックチェーンで発行されているBTCや、Ethereumというブロックチェーンで発行されているETHなどの暗号資産は、例えば、自分の所有するBTCと他人が所有するBTCの同数だけ交換しても価値は同じなのでファンジブルであるといえます。

図 1 ファンジブルとノンファンジブルの違いと例

出所:大和総研作成

 まとめると、ファンジブルトークンは「ブロックチェーン上で何らかの価値や権利を表す代替可能なデジタル資産」という意味になります。

3 ファンジブルトークンを発行するためのERC-20

 Ethereumでは、ファンジブルトークンであるETHが発行・流通しています。ETHのようにブロックチェーンの機能として元から備わっているトークンは、ネイティブトークンと呼ばれます。
 一方、スマートコントラクトの仕組みを利用することで、ネイティブトークン以外の独自のファンジブルトークンをEthereumで発行することもできます。その際最も利用されているのがERC-20という規格です。その規格を満たすスマートコントラクトを開発すれば、さまざまなウォレットやブロックチェーン関連のサービス間で互換性のあるファンジブルトークンを誰でも自由に発行できます。このようにして発行されたファンジブルトークンをERC-20トークンと呼ぶこともあります。Ethereumで暗号資産として発行・流通している暗号資産のほとんどがERC-20の規格に準拠しています。

図 2 EthereumブロックチェーンとEther(ETH)、ERC-20規格の関係

出所:大和総研作成

4 ERC-20を用いたトークンの事例

 それでは、EthereumでERC-20規格を用いて発行されたトークンの例を見ていきます。数多くのトークンが発行されていますが、その中から「USDT(Tether)」「UNI(Uniswap)」の二つを紹介します。

4.1 USDT

 まずはUSDTです。USDTはTether Limited(以降、Tether社)が開発したステーブルコインです。ステーブルコインとは、価格の安定化を目的に法定通貨などの担保を裏付けとして発行されている暗号資産のことです。USDTは米ドルを裏付け資産として発行されており、トークンの価格が米ドルに連動する設計になっています。これにより、暗号資産特有の価格変動リスクを回避し、安定した価格で取引を行える点が特徴です。
 USDT以外にもさまざまなステーブルコインが発行されていますが、USDTは2025年9月9日時点で時価総額が約24兆円(1ドル=147円で円換算)で、ステーブルコインの中で最大の時価総額です。USDTはDeFi(分散型金融:Decentralized Finance)や暗号資産取引所、企業間における決済通貨として幅広く利用されています。
 USDTはファンジブルトークンとしてさまざまブロックチェーンで発行されており、EthereumではERC-20の規格に沿って発行されています。

図 3 USDTについて
出所:大和総研作成

4.2 UNI

 次にUNIです。UNIの発行元である「Uniswap」は、Ethereumなどのブロックチェーン上で動作する分散型取引所(DEX:Decentralized Exchange)です(注3)。Uniswapは取引に「自動マーケットメイカー(AMM:Automated Market Maker)」と呼ばれる仕組みを採用しています。この仕組みは「流動性プール(LP:Liquidity Pool)」と呼ばれるスマートコントラクトを介して取引が行われるのが特徴です。LPには2種類以上の暗号資産が預け入れられ、その数量に応じ交換レートが自動計算されます。投資家はLPを介して暗号資産を交換(Swap)することができます。
 LPに暗号資産を預け入れて流動性提供者になると、Swapで発生する取引手数料の一部を受け取ることができます。また、インセンティブとしてUNIトークンが付与される場合もあります。このようにDEXに流動性を提供し、取引手数料収入や追加のトークン(UNIなど)を得る仕組みは、「イールドファーミング」や「流動性マイニング」と呼ばれます。
 UNIの保有者は、Uniswapの運営方針(手数料の分配方法や新機能導入など)に関する議論や議案への投票に参加できます。このようにUniswapは、特定の管理者がおらず、インターネットを通じて世界中の人々が協力し運営する「DAO(分散型自律組織)」という形態をとっています。UNIは、Uniswapの意思決定や報酬分配などに使われるファンジブルトークンであり、このようなトークンは「ガバナンストークン」と呼ばれます。

図 4 Uniswapの仕組み
出所:大和総研作成

5 ERC-20の仕組み

 ここからは、ERC-20の具体的な仕組みについてご紹介します。ERC-20で定義されているメソッドのうち主なものは以下の通りです。

  • totalSupply:トークンの総発行量を取得するメソッド。
    function totalSupply() public view returns (uint256)
  • balanceOf:指定したアドレスが所有するトークンの数を取得するメソッド。
    function balanceOf(address _owner) public view returns (uint256 balance)
  • transfer:トークンを別のアドレス宛てに移転するメソッド。
    function transfer(address _to, uint256 _value) public returns (bool success)
  • approve:ある所有者(アドレス)が所有するトークンを、指定した第三者が指定した量を所有者に代わって移転することを許可するメソッド。
    function approve(address _spender, uint256 _value) public returns (bool success)
  • transferFrom:approveと一緒に使われるメソッド。approveで移転を許可された第三者が指定したアドレスに指定した量のトークンを移転するメソッド。
    function transferFrom(address _from, address _to, uint256 _value) public returns (bool success)
  • allowance:approveと一緒に使われるメソッド。指定したアドレスが移転できるトークンの量を取得するメソッド。
    function allowance(address _owner, address _spender) public view returns (uint256 remaining)

また、オプションとして以下の情報をトークンに付与することも可能です。

  • name:トークンの名前。
  • symbol:トークンの識別子。そのトークンの単位としてよく使用される。(例:UNI、USDTなど)
  • decimals:トークンの数量を表す際の小数点以下の桁数を定義するもの。18桁(つまり、最小単位が0.000000000000000001)の場合が多い。

6 テストネットでオリジナルコインを発行してみる

 それでは、実際にEthereumのテストネットである「Sepolia」でERC-20を使用してファンジブルトークンを発行していきます。

6.1 スマートコントラクトを作成する

 今回は開発環境としてHardhat (Ver 2.25.0) (注4)と、スマートコントラクトのライブラリであるOpenZeppelin(Ver5.3.0)(注5)を利用して、ERC-20トークンのスマートコントラクトを実際に作成します。両者とも、Ethereum(および互換性のあるブロックチェーン)のスマートコントラクト開発においてよく利用されるツールとライブラリです。

 Hardhatはスマートコントラクトの開発ツールであり、Ethereum上でコントラクトを記述するためのプログラミング言語です。Solidityで記載されたスマートコントラクトに対して、テスト、コンパイル、デプロイなどが実行できます。

 OpenZeppelinはスマートコントラクトのライブラリであり、ERC-20などのトークン規格に沿ったスマートコントラクトを効率的に開発することができます。その他、セキュリティ機能やアドレス操作機能、数学的な演算を効率よく行う機能など、スマートコントラクト開発で役立つさまざまなユーティリティ機能も提供しています。
具体的な開発方法は以下の通りです。

  1. Hardhat プロジェクトの作成
     npxコマンドでHardhat プロジェクトをセットアップします。
    $ npx hardhat init
  2. OpenZeppelin ライブラリのインストール
     Hardhatをインストールできましたので、次にプロジェクトの依存関係として OpenZeppelin をインストールします。プロジェクト直下でnpm installコマンドを実行し、ライブラリをインストールします。
    $ npm install @openzeppelin/contracts

     node_modules配下に@oppenzeppelin/contractsフォルダが生成され、インストールできました。インストールされた、OpenZeppelin のライブラリの内容は以下のようになっています。

    図 5 OpenZeppelinライブラリの内容
    出所:大和総研作成

 環境が整いましたので、実際にERC20規格のトークンをデプロイするスマートコントラクトを作成していきます。今回は、作成・編集した以下3ファイルごとに解説していきます。

  • プロジェクト直下のhardhat.config.ts
  • contracts配下のerc20.sol
  • ignition/modules配下のerc20.ts

 なお、プロジェクト全体のディレクトリ内の主要なファイルの構成は以下のようになります。

図 6 ディレクトリ構成(主要なファイルのみ抜粋)
出所:大和総研作成

 まず、hardhat.config.tsについて解説します。このファイルでは、以下の設定を行っています。

  • solidityのバージョンの設定
  • デプロイ先のネットワークの設定(EthereumのテストネットであるSepoliaノードの接続先の設定)
  • デプロイの際に使用するアカウントの秘密鍵の設定

 デプロイの際に使用するアカウントの秘密鍵は、今回はMetaMaskで作成したアカウントから秘密鍵をエクスポートして利用します。後ほどEthereumのネットワークにスマートコントラクトをデプロイする際に手数料を支払う必要があり、ここで指定したアカウントがトランザクション手数料を支払うことになります。したがって予めこのアカウントにSepolia用のETHを保有させておく必要があることに注意してください。ソースコードは以下のようになります。

Haddhat.config.ts(大和総研作成)
 import { HardhatUserConfig } from "hardhat/config";
 import "@nomicfoundation/hardhat-toolbox";

 const PRIVATE_KEY= {Metamaskからエクスポートしたアカウントの秘密鍵をここで読み込む環境変数の利用を推奨};

 const config: HardhatUserConfig = {
   solidity: "0.8.28",
   networks: {
     sepolia: {
       url: “Ethereum SepoliaノードのURL”,
       accounts: [PRIVATE_KEY!],
     },
   },
 };

 export default config;

 次に、contracts配下のerc20.solについて解説します。
 コントラクトとしてMyTokenクラスを定義し、ライブラリであるOpenZeppelinのERC20とOwnableを継承しました。また、コンストラクタの引数でトークンの名前、シンボル、初期発行数量を指定できるようにします。ソースコードは以下の通りです。

erc20.sol(大和総研作成)
pragma solidity ^0.8.22;

import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";

contract MyToken is ERC20, Ownable {
  // コンストラクタ関数
  // コントラクトがデプロイされる際に一度だけ実行される
  constructor(
    string memory name,                 // トークンの名前 (例: "My Awesome Token")
    string memory symbol,               // トークンのシンボル (例: "MAT")
    uint256 initialSupply               // トークンも初期発行数量
  )
  ERC20(name, symbol)                   // 親コントラクトERC20のコンストラクタを呼び出し、トークン名とシンボルを設定
  Ownable(msg.sender)                   // 親コントラクトOwnableのコンストラクタを呼び出し、デプロイ時に利用したアカウントをトークンの所有者(管理者、owner)に設定
  {
    // 初期供給量として設定した数量分を、コントラクトをデプロイしたアカウント (msg.sender) に発行する
    _mint(msg.sender, initialSupply);
  }

  // トークンを新たに発行する関数
  // この関数はコントラクトの所有者 (管理者、owner) のみが実行できる
  function mint(address to, uint256 amount) public onlyowner {
    _mint(to, amount);                  // 指定されたアドレス 'to' に指定された量 'amount' のトークンを発行する
  }
}

 最後に、ignition/module配下のerc20.tsです。
 先ほどerc20.solのMytokenクラスのコンストラクタを使ってトークンの名前(name)、シンボル(symbol)、初期供給量(initSupply)の引数に値を設定し、Hardhat Ignitionを使用したデプロイができるようにします。ソースコードは以下の通りです。

erc20.ts(大和総研作成)
import { buildModule } from "@nomicfoundation/hardhat-ignition/modules";

const name = "erc201030"; // デプロイするトークンの名前を定義
const symbol = "erc201030"; // デプロイするトークンのシンボルを定義
const initSupply = 10000000n * 10n**18n; // 初期発行数量を定義 (小数点以下の桁数がデフォルトでは18桁なので、1000万トークン発行するには1000万×10の18乗となる)

// buildModuleを使ってデプロイ
export default buildModule("erc20", (m) => {
  // MyTokenコントラクトをデプロイ
  // m.contract("コントラクト名", [コンストラクタ引数])
  const erc20 = m.contract("MyToken", [name, symbol, initSupply]);

  // デプロイされたコントラクトのインスタンスを返却
  // これにより、他のモジュールやテストからこのコントラクトにアクセスできるようになる
  return { erc20 };
});

 ソースコードが完成したので、npx コマンドを使ってhardhatでコンパイルを実行します。コンパイルが通ればデプロイの準備は完了です。
$ npx hardhat compile

6.2 スマートコントラクトのデプロイしオリジナルコインを発行する

 作成したスマートコントラクトをデプロイします。デプロイはnpxコマンドでネットワークにsepoliaを指定することで実行できます。
$ npx hardhat ignition deploy ignition/modules/erc20.ts --network sepolia

 コマンドを実行し、デプロイが成功すると以下のようなメッセージが表示され、「erc20#MyToken - 0x7CEc48E1735ce99e88eF0E173f15D28FC030A97」 のようにデプロイしたトークンのアドレスが表示されます。このアドレス(0x7CEc48E…)は、後述するMetaMaskで扱えるようにする際に使用するため、控えておきます。

トークンデプロイ結果の確認(大和総研作成)
$ npx hardhat ignition deploy ignition/modules/erc20.ts --network sepolia
✓ Confirm deploy to network sepolia (11155111)? ... yes
Hardhat Ignition 🚀

Deploying [ erc20 ]

Batch #1
Executed erc20#MyToken

[ erc20 ] successfully deployed 🚀

Deployed Addresses

erc20#MyToken - 0x7CEc48E1735ce99e88eF0E173f15D28FC030A97

6.3 デプロイしたトークンをMetaMaskで扱えるようにする

 ここでは、デプロイしたトークンをhardhat.config.tsに記載した秘密鍵のエクスポート元であるMetaMask上のアカウントで扱えるようにしていきます。MetaMaskのアカウントがトークンの所有者となるようにトークンがデプロイされているため、所有者であるMetaMaskのアカウント内で残高の確認や送金(移転)が行えるようになります。
 まずはMetaMaskを起動し、「トークン」タブの3点リーダーをクリックし、「トークンをインポート」を選択します(図7、8)。

図 7 MetaMaskにログイン後の表示画面

出所:Consensys Software Inc.のアプリMetaMaskより引用(2025年9月9日閲覧)

図 8 「トークンをインポート」をクリック後の画面
出所:Consensys Software Inc.のアプリMetaMaskより引用(2025年9月9日閲覧)

 ネットワークの選択を求められるため、「Sepolia」を選択します(図9)。

図 9 トークンのネットワークを選択
出所:Consensys Software Inc.のアプリMetaMaskより引用(2025年9月9日閲覧)

 画面の表示に従って進むと、トークンコントラクトアドレスの入力画面が表示されます。この時、デプロイ時に表示されたコントラクトアドレス(0x7CEc48E…)を入力すると、トークンシンボルや小数点以下の桁数が取得されます(図10)。

図 10 トークンコントラクトアドレスの入力画面
出所:Consensys Software Inc.のアプリMetaMaskより引用(2025年9月9日閲覧)

 「次へ」をクリックし、トークンをインポートします(図11)。

図 11インポートを選択
出所:Consensys Software Inc.のアプリMetaMaskより引用(2025年9月9日閲覧)

 インポートに成功すると、通知表示とともに、トークン一覧にトークンが表示されます(図12、13)。

図 12トークンのインポート通知表示
出所:Consensys Software Inc.のアプリMetaMaskより引用(2025年9月9日閲覧)

図 13 erc201030の表示
出所:Consensys Software Inc.のアプリMetaMaskより引用(2025年9月9日閲覧)

 画面下部に「erc201030」が表示されました。
 追加された「erc201030」をクリックすると、トークンの詳細情報を参照できます(図14)。

図 14トークンの詳細情報
出所:Consensys Software Inc.のアプリMetaMaskより引用(2025年9月9日閲覧)

 インポートしたトークンは他のアカウントに送金することも可能な状態になっています。実際に別のアカウント「0x988DF6443027eFA4f523aB74B9e2A06a1310d5A3」へ送金をしてみます。対象のトークンを選択し、「送金」ボタンを押すと、送金先のアドレスや送金数量を設定できます(図15、16)。

図 15トークンの送金先設定
出所:Consensys Software Inc.のアプリMetaMaskより引用(2025年9月9日閲覧)

図 16 数量の設定
出所:Consensys Software Inc.のアプリMetaMaskより引用(2025年9月9日閲覧)

 数量は「0.00000000002」と入力し、「続行」をクリックします。画面の指示に従って進むと、トークンの送金に関する確認画面が表示されます。ここで、送金時に必要なトランザクション手数料(ネットワーク手数料)の設定を行います(図17)。

図 17トークンの送金先と手数料の確認
出所:Consensys Software Inc.のアプリMetaMaskより引用(2025年9月9日閲覧)

 そのままでも実行できますが、「ネットワーク手数料」の下の編集ボタンを押して、ガス代の設定を変更することもできます(図18)。

図 18 ガス代の編集
出所:Consensys Software Inc.のアプリMetaMaskより引用(2025年9月9日閲覧)

 ガス代を選択して「確認」を押下し、しばらく待つと、送金が実行されます。アクティビティからは送金状況を確認できます(図19)。

図 19アクティビティ画面で送金履歴の確認
出所:Consensys Software Inc.のアプリMetaMaskより引用(2025年9月9日閲覧)

 「確認されました」と表示されているため、送金が完了していることが確認できます。
 「erc2030を送金」をクリックすると、送金履歴の詳細を確認できます。(図20)。

図 20 送金履歴の確認
出所:Consensys Software Inc.のアプリMetaMaskより引用(2025年9月9日閲覧)

 送金先のアカウントでも、MetaMaskにトークンをインポートすることで、残高が反映されていることを確認できます(図21)。

図 21送金先アカウントでのトークン残高反映の確認
出所:Consensys Software Inc.のアプリMetaMaskより引用(2025年9月10日閲覧)

7 おわりに

 本記事では、ERC-20の規格を用いてオリジナルのファンジブルトークンをEthereumのSepoliaで発行しました。ERC-20トークンの発行は今回紹介したHardhatやOpenZeppelinなどのツールやライブラリを用いて、比較的簡単に試すことができます。興味のある方はぜひチャレンジしてみてください。
 また、今後は他トークンの規格についても情報発信してまいりますので、引き続きご注目ください。

(本記事の内容は2025年9月時点のものです)

お問い合わせ先

 大和総研では、ブロックチェーン・Web3分野の研究開発を行う専門のプロジェクトを発足し、ウォレットに関する特許を取得するなど、ブロックチェーン・Web3に関する取り組みを行っています。
 長年にわたるブロックチェーン・Web3関連の取り組みの実績を活かし、お客様のブロックチェーン・Web3ビジネスの検討やシステムの構築をサポートします。ご要望・ご不明点などがありましたら、ITソリューションサービスサイトよりお問い合わせください。

参考文献

(注1)本邦初の PTS(私設取引システム)取扱セキュリティ・トークンの引受及び、 セキュリティ・トークンウォレット「Crossllet」開発のお知らせ
https://ssl4.eir-parts.net/doc/8601/ir_material3/218042/00.pdf
(注2)ethereum.org 「ERC-20: Token Standard」
https://eips.ethereum.org/EIPS/eip-20
(注3)Uniswap Labs
https://app.uniswap.org/
(注4)Nomic Foundation
https://hardhat.org/
(注5)Zeppelin Group Ltd
https://www.openzeppelin.com/