はじめに

初めまして。 『DApps開発入門』という本や色々記事を書いているかるでねです。

以下でも情報発信しているので、興味ある記事があればぜひ読んでみてください!

今回は『ERC20』についてまとめていきます。

こちらの2022年12月に書いていた記事です。 2025年11月にリライトしました。

ERC20とは

統一されたトークン規格

ERC20とは、「Ethereumブロックチェーンで動作する統一されたトークン規格の1つ」です。

「統一されたトークンの規格」というのは、「共通のルールを持っているトークン」という事です。 共通のルールを持っていないと、トークンごとにウォレットが必要になります。 新しいトークンを触るごとにウォレットを作っていては、だいぶめんどくさいですよね。

そこでERC20というトークン規格に沿って設計することで1つのウォレットで管理できるようになります。

また、ERC20は「代替性トークン」とも呼ばれています。 「代替性トークン」とは、あるトークンと同じ価値を持つ他のトークンと交換できるということです。 反対に交換できないのでNFTを代表する「非代替性トークン」です。

誰でも作成可能

ERC20トークンは誰でも作ることができます。 そのため現在存在するERC20トークンの種類はめちゃくちゃ多いです。

上記から現在のERC20トークンの種類を確認できるのですが、現在(2025年11月17日)では177万9821種類のERC20トークンがあります。

追加機能を実装可能

この章の前半で説明したように、ERC20は統一された規格ですが、あくまで最低限の機能は統一された規格で設計されています。 そのため、トークンごとに追加機能を実装することが可能です。

新規発行するERC20トークンごとに以下のように役割が異なってくるため、役割に応じて追加機能を実装することが可能になります。

ステーブルコイン

ドルや日本円などの法定通貨や市場で取引されるコモディティ(金やプラチナなど)などの価格に連動するように設計された暗号通貨。

DeFiトークン

分散型金融(DeFi)プロトコルを支援するトークン。

スマートコントラクトで管理されているため中央管理者が存在しない。

仮想通貨を預け入れて利息を得たり、流動性を提供して独自トークンを得る、仮想通貨を貸し出して利回りを得るなどして稼ぐことができる。

ユーティリティトークン

特定のコミュニティやサービスなどを利用するにあたり実用性があるトークンのこと。 具体的には以下のような用途が想定される。

  • サービス内で物を購入したり利用料を支払う
  • 利用者の行動に対してインセンティブを支払う
  • 所有することでコミュニティの意思決定に関われる
  • 保有している量や期間に応じて報酬が発生する

代表的なERC20トークン

この章では代表的なERC20トークンについて一覧にしていきます。

EIP20

EIPとは

前章までERC20といってきましたが、EIP20とは何でしょうか?

EIPとは「Ethereum Improvement Proposals」の略で、「Ethereumの新しい機能やプロセスに関する提案を規定する標準規格」のことです。

EIPの細かい説明は以下に書かれています。

簡単に言うと以下になります。

EIPは、Ethereum Improvement Proposalsの略でEthereumをより良いものにするために議論される改善提案のこと。 Ethereumは、特定の誰かによって管理されるものではないため、世界中の誰もがEIPを提出することで、Ethereumの発展に貢献することができる。 20という数字は20番目の提案ということです。

ERCは、EIPの中の1カテゴリです。 そのため、ERC20とEIP20は同じものを指しています。

ERC20の関数

ERC20のオプション関数

ERC20には必須の関数とオプション関数の2つがあります。 まずは実装してもしなくても良い、オプション機能について紹介していきます。

name

トークンの名前を返す関数です。

例)Tether

js
function name() public view returns (string)
symbol

トークンのシンボルを返す関数。

例)USDT

js
function symbol() public view returns (string)
decimals

トークンが使用する小数点以下の桁数を返す関数。

例えば8を指定すると、トークンの金額を100000000で割って表示し、ユーザーに対してより読みやすい方法でトークン数を表示することができる。

js
function decimals() public view returns (uint8)

ERC20の必須関数

では次にERC20の必須関数について確認していきます。

totalSupply

トークンの総供給量を返す関数。

js
function totalSupply() public view returns (uint256)
balanceOf

特定アドレスが保持しているトークン残高を返す関数。

js
function balanceOf(address _owner) public view returns (uint256 balance)
transfer

_toに送り先のアドレス、_valueに送りたいトークンの量を指定して送付し、送付結果が成功か失敗か返す関数。

条件

  • _toに0アドレスを指定できない
  • transfer関数の実行アドレスは_value以上のトークンを保有している必要がある
js
function transfer(address _to, uint256 _value) public returns (bool success)
transferFrom

_fromに送り元アドレス、_toに送り先のアドレス、_valueに送りたいトークンの量を指定して送付し、送付結果が成功か失敗か返す関数。 transferFrom関数の用途としては、コントラクトがトークン保有者に代わってトークンを送付する。 コントラクトを実行するアドレスは_value以上のトークンの送付権限が必要。

条件

  • _fromと_toに0アドレスを指定できない
  • _fromで指定したアドレスは_value以上のトークンを保有している必要がある
  • コントラクトを実行するアドレスは_value以上のトークンの送付権限が必要
js
function transferFrom(address _from, address _to, uint256 _value) public returns (bool success)
approve

_spenderに資金引き出し許可を与えるアドレス、_valueに引き出せるトークンを指定して、指定したアドレスに資金の引き出し許可を与える関数。 _spenderに指定されたアドレスは、_valueに指定されたトークン量の範囲内であれば何度でも送付できる。

条件

  • _spenderには0アドレスを指定できない
js
function approve(address _spender, uint256 _value) public returns (bool success)
allowance

_ownerに送付許可を与えたアドレス、_spenderに送付許可を与えられたアドレスを格納し、transferFrom関数を通じて、_spenderが_ownerから引き出すことができるトークン量を返す関数。

js
function allowance(address _owner, address _spender) public view returns (uint256 remaining)

ERC20のコード確認

ではこの章から実際にERC20の実装コードを見ていきましょう! 今回はERC20を実装する上でほとんどの人が使用している「OpenZeppelin」を使用していきます。

「OpenZeppelin」とは、Solidityで安全なスマートコントラクトを構築できるオープンフレームワークです。

分散型アプリケーションの構築や自動化、運用のためのセキュリティ製品を主に提供している企業です。

今回は以下のページを使用しながらコードの確認をしていきます。

IERC20

IERC20とは、ERC20を実装する上で必要な関数やイベントが定義されているinterfaceです。

Solidityにおけるイベントとは、簡単にいうと「スマートコントラクトでの動作結果をフロントに伝える」役割を持った機能です。

詳しくは以下の公式ドキュメントを参考にしてください。

interface

interfaceとは、コントラクトに似ていますが実行することはできません。 interfaceには関数名やひきすうなどのみ定義されていて中身は一切定義されていません。 そのため、interfaceを継承したコントラクト内で関数を再度定義して中身を記述する必要があります。

「interfaceいらなくね?」こう思う方もいると思います。

interfaceを使用するメリットは、実装で必要な関数を確認できることにあります。 最初で述べたように、interfaceには実装する上で必要な関数が定義されているので、開発者やコントラクトを実行するユーザーからどんな機能があるのかを簡単に確認できます。 有名なプロジェクトでもinterfaceはよく使用されているので、この機会に理解しておくと後々役に立ちます。

公式ドキュメントは以下になります。

関数

ではまずはIERC20に定義されている関数から確認していきましょう。

関数一覧:

  • totalSupply()
  • balanceOf(account)
  • transfer(to, amount)
  • allowance(owner, spender)
  • approve(spender, amount)
  • transferFrom(from, to, amount)

上記の6つ関数が定義されています。 EIP20の解説部分で取り上げた関数と同じなため詳細はそちらを参照してください!

イベント

IERC20には2つのイベントが定義されています。

Transfer(from, to, value)

value分のトークンを保有している、fromに指定されたアドレスからtoに指定されたアドレスへトークンが送付されたときに発行される。 値は0であっても良い。

Approval(owner, spender, value)

approve関数が呼び出され、ownerに指定されたアドレスからspenderに指定されたアドレスへvalue分のトークンの送付許可が設定されたときに発行される。

IERC20Metadata

次にIERC20メタデータについて確認していきます。 こちらもIERC20同様interfaceが定義されています。 以下の関数もERC20で解説している関数です。

関数一覧

  • name()
  • symbol()
  • decimals()

上記の3つの関数はオプション関数のため必須の機能ではありません。

ERC20

ではここから念願のERC20について確認していきます! IERC20でも述べているように、このERC20はIERC20とIERC20Metadataを継承しています。 そのためIERC20の6つの関数とIERC20Metadataの3つの関数が定義されています。

そして、もちろんそれ以外の関数もたくさん定義されているので、簡単な説明も添えていきます。

関数一覧:

  • constructor(name_, symbol_)
  • name()
  • symbol()
  • decimals()
  • totalSupply()
  • balanceOf(account)
  • transfer(to, amount)
  • allowance(owner, spender)
  • approve(spender, amount)
  • transferFrom(from, to, amount)
  • increaseAllowance(spender, addedValue)
  • decreaseAllowance(spender, subtractedValue)
  • _transfer(from, to, amount)
  • _mint(account, amount)
  • _burn(account, amount)
  • _approve(owner, spender, amount)
  • _spendAllowance(owner, spender, amount)
  • _beforeTokenTransfer(from, to, amount)
  • _afterTokenTransfer(from, to, amount)

説明も合わせて書くとだいぶ長くなってしまうので分割して説明していきます。

constructor

トークンの名前(name)とシンボル(symbol)をデプロイ時に渡し、デプロイ後は変更できない。 小数値(decimals)のデフォルト値は18になっているため、別の値に設定したいときは上書きする必要がある。

js
string private _name;
string private _symbol;

constructor(string memory name_, string memory symbol_) {
    _name = name_;
    _symbol = symbol_;
}
name

_name変数の値を返す関数。

js
function name() public view virtual override returns (string memory) {
    return _name;
}
symbol

_symbol変数の値を返す関数。

js
function symbol() public view virtual override returns (string memory) {
    return _symbol;
}
decimals

decimals に指定した値(デフォルトは18)を返す関数。

js
function decimals() public view virtual override returns (uint8) {
    return 18;
}
totalSupply

トークンの総供給量を返す関数。

js
uint256 private _totalSupply;

function totalSupply() public view virtual override returns (uint256) {
    return _totalSupply;
}
balanceOf

accountで指定したアドレスが保有するトークンの量を返す関数。

js
function balanceOf(address account) public view virtual override returns (uint256) {
    return _balances[account];
}
transfer

_msgSender関数はmsg.senderの結果を返す関数です。

js
function transfer(address to, uint256 amount) public virtual override returns (bool) {
    address owner = _msgSender();
    _transfer(owner, to, amount);
    return true;
}

_msgSender関数の定義は以下です。

js
function _msgSender() internal view virtual returns (address) {
    return msg.sender;
}

_transfer関数は後述しています。

allowance

_allowancesマッピングにて保管されている、ownerに指定されたアドレスがspenderで指定されたアドレスにどれくらいの量のトークンの送付許可を与えているかを確認できる関数。

js
mapping(address => mapping(address => uint256)) private _allowances;

function allowance(address owner, address spender) public view virtual override returns (uint256) {
    return _allowances[owner][spender];
}
approve

_spenderに資金引き出し許可を与えるアドレス、_valueに引き出せるトークンを指定して、指定したアドレスに資金の引き出し許可を与える関数。

_approve関数については後述しています。

js
function approve(address spender, uint256 amount) public virtual override returns (bool) {
    address owner = _msgSender();
    _approve(owner, spender, amount);
    return true;
}
transferFrom

fromで指定したアドレスからtoで指定したアドレスへamount分のトークンを送る関数。

_spendAllowance関数と_transfer関数は後述しています。

js
function transferFrom(
    address from,
    address to,
    uint256 amount
) public virtual override returns (bool) {
    address spender = _msgSender();
    _spendAllowance(from, spender, amount);
    _transfer(from, to, amount);
    return true;
}
increaseAllowance

spenderに指定したアドレスが送付できるトークン量を増やす関数。

条件

  • spenderは0アドレスにできない

_approve関数は後述しています。

js
function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {
    address owner = _msgSender();
    _approve(owner, spender, allowance(owner, spender) + addedValue);
    return true;
}
decreaseAllowance

spenderに指定したアドレスが送付できるトークン量を減らす関数。

条件

  • spenderは0アドレスにすることはできない
  • spenderはsubtractedValueよりも多くのトークン量を送付許可されている必要がある

_approve関数は後述しています。

uncheckedは、オーバフローとアンダーフローのチェックを行わないというマークです。 チェックを行わないことでガス代が節約されるため、チェックが不要な箇所では積極的に使用すると良いです。

js
function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {
    address owner = _msgSender();
    uint256 currentAllowance = allowance(owner, spender);
    require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero");
    unchecked {
        _approve(owner, spender, currentAllowance - subtractedValue);
    }

    return true;
}

オーバフローとアンダーフローについては以下を参考にしてください。

_transfer

fromに指定されたアドレスから、toに指定されたアドレスに amount 分のトークンを送付する関数。

条件

  • from を0アドレスにできない
  • to を0アドレスにできない
  • from に指定されたアドレスは、amount 以上のトークンを保有している必要がある
js
function _transfer(
    address from,
    address to,
    uint256 amount
) internal virtual {
    require(from != address(0), "ERC20: transfer from the zero address");
    require(to != address(0), "ERC20: transfer to the zero address");

    _beforeTokenTransfer(from, to, amount);

    uint256 fromBalance = _balances[from];
    require(fromBalance >= amount, "ERC20: transfer amount exceeds balance");
    unchecked {
        _balances[from] = fromBalance - amount;
        // Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by
        // decrementing then incrementing.
        _balances[to] += amount;
    }

    emit Transfer(from, to, amount);

    _afterTokenTransfer(from, to, amount);
}
_mint

amount 分のトークンを生成し、account に指定されたアドレスに送ることでトークンの総供給量を増やす関数。

条件

  • account を0アドレスにできない

_beforeTokenTransfer 関数と _afterTokenTransfer 関数については後述しています。

js
function _mint(address account, uint256 amount) internal virtual {
    require(account != address(0), "ERC20: mint to the zero address");

    _beforeTokenTransfer(address(0), account, amount);

    _totalSupply += amount;
    unchecked {
        // Overflow not possible: balance + amount is at most totalSupply + amount, which is checked above.
        _balances[account] += amount;
    }
    emit Transfer(address(0), account, amount);

    _afterTokenTransfer(address(0), account, amount);
}
_burn

account で指定したアドレスから amount 分のトークンを破棄してトークンの総供給量を減らす関数。

条件

  • 送り先は0アドレスに指定されている
  • account を0アドレスにできない
  • account で指定したアドレスは、amount 分以上のトークンを保有してある必要がある

_beforeTokenTransfer 関数と _afterTokenTransfer 関数については後述しています。

js
function _burn(address account, uint256 amount) internal virtual {
    require(account != address(0), "ERC20: burn from the zero address");

    _beforeTokenTransfer(account, address(0), amount);

    uint256 accountBalance = _balances[account];
    require(accountBalance >= amount, "ERC20: burn amount exceeds balance");
    unchecked {
        _balances[account] = accountBalance - amount;
        // Overflow not possible: amount <= accountBalance <= totalSupply.
        _totalSupply -= amount;
    }

    emit Transfer(account, address(0), amount);

    _afterTokenTransfer(account, address(0), amount);
}
_approve

owner で指定したアドレスから、spender に指定したアドレスに amount 分のトークンの送付許可を与える関数。

条件

  • owner を0アドレスにできない
  • spender を0アドレスにできない
js
function _approve(
    address owner,
    address spender,
    uint256 amount
) internal virtual {
    require(owner != address(0), "ERC20: approve from the zero address");
    require(spender != address(0), "ERC20: approve to the zero address");

    _allowances[owner][spender] = amount;
    emit Approval(owner, spender, amount);
}
_spendAllowance

owner に指定されたアドレスが、spender に指定されたアドレスへ送付許可していたトークンの量を amount に更新する関数。

条件

  • 現在 spender に指定されたアドレスに送付許可されている値が最大値の場合は更新しない
  • owner に指定されたアドレスが、amount で指定した量のトークンを保有していない場合は処理を戻す
js
function _spendAllowance(
    address owner,
    address spender,
    uint256 amount
) internal virtual {
    uint256 currentAllowance = allowance(owner, spender);
    if (currentAllowance != type(uint256).max) {
        require(currentAllowance >= amount, "ERC20: insufficient allowance");
        unchecked {
            _approve(owner, spender, currentAllowance - amount);
        }
    }
}
_beforeTokenTransfer

トークン送付前に呼び出される関数。 この関数に任意の追加処理を実装することができる。

  • from と to が0アドレスでないとき from で指定されたアドレスから to に指定したアドレスへ amount 分のトークンが送付される
  • from に0アドレスが指定されると、to で指定されたアドレスに amount 分のトークンが生成されたのち送付される
  • to に0アドレスが指定されると、from で指定されたアドレスから amount 分のトークンがBurnされる
  • from と to の両方が0アドレスになることはない
js
function _beforeTokenTransfer(
    address from,
    address to,
    uint256 amount
) internal virtual {}
_afterTokenTransfer

トークン送付後に呼び出される関数。 この関数に任意の追加処理を実装することができる。

  • from と to が0アドレスでないとき from で指定されたアドレスから to に指定したアドレスへ amount 分のトークンが送付される
  • from に0アドレスが指定されると、to で指定されたアドレスに amount 分のトークンが生成されたのち送付される
  • to に0アドレスが指定されると、from で指定されたアドレスから amount 分のトークンがBurnされる
  • from と to の両方が0アドレスになることはない
js
function _afterTokenTransfer(
    address from,
    address to,
    uint256 amount
) internal virtual {}

Extension

ここまでERC20について確認できました。 ERC20には拡張機能がたくさんあるのですが、ここで紹介するにはあまりにも多すぎるため、今後時間あるときに別記事でまとめていきます。 とりあえずは基本的なERC20を知っておけば問題ありません。

ERC20の実装

前章まででERC20の概要とコードの理解ができました。 この章では実際にERC20の実装をしていきたいと思います。 前章が相当長かったと思うので覚悟して取り掛かってください!

js
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.9;

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

contract Cardene is ERC20 {
    constructor() ERC20("Cardene", "CARD") {
        _mint(msg.sender, 100000 * 10 ** decimals());
    }
}

はい…。 嘘つきました。 このたった7行のコードでERC20の実装は完了です。

「え?さっきの大量の関数はどこに?」と思う方もいると思いますが、先ほどの長い関数たちを定義したコントラクトを継承しています。 4行目でopenzeppelinが提供しているERC20のコントラクトを読み込んでいます。 6行目でCardene is ERC20と4行目で読み込んだコントラクトを継承しています。

継承すると継承元のコントラクトで定義されている関数を全て使用することができるため、先ほど解説した関数を全て使用することができます。 納得していただけたでしょうか?

では次の章で実行していきましょう! ちなみに以下のOpenzeppelinのサイトから簡単にコードを生成できるので、触ってみると理解が深まるかもしれいないです。

ERC20の実行

この章では実際にERC20を実行していきます! remixというブラウザで使用できるエディタを使用していきます!

実装手順を紹介していきます。

ファイルの作成

以下の画面の左側の「contracts」というディレクトリの上で右クリックすると、メニューが出てくるので「New File」をクリックして、「CardeneERC20.sol」と入力してください。

image.png

そうするとファイルが作られるので、「CardeneERC20.sol」をクリックすると右の画面にファイルの中身が表示されます。

まだ何も書かれていないので以下のコードを貼り付けてください。

js
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.9;

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

contract Cardene is ERC20 {
    constructor() ERC20("Cardene", "CARD") {
        _mint(msg.sender, 100000 * 10 ** decimals());
    }
}

コンパイル

では次にコンパイルしていきます。

以下のように一番左の5つのアイコンの真ん中をクリックして、「Compile CardeneERC20.sol」をクリックしてください。

image.png

アイコンに緑のチェックが入ればコンパイル完了です。

デプロイ

一番左の5つのアイコンの下から2つ目のアイコンをクリックして、「Deploy」というボタンをクリックしてください。

image.png

そうするとコントラクトがデプロイされて、左下の方にある「Deployed Contracts」の下に「CARDENEERC20 AT 0XD91...39138」と表示されればデプロイできています!

関数の実行

ではここから早速関数を実行していきましょう!

確認系

まずは確認系の関数から実行していきます。

先ほどデプロイしたコントラクト内の「decimals」、「name」、「symbol」、「totalSupply」を実行していきます。

image.png

それぞれ結果が出力されていますね。

トークンの名前は「Cardene」で、トークンのシンボルは「CARD」、「decimals」はデフォルトの「18」、総供給量は「100000000000000000000000」を膨大な数字になってしまいました。

balanceOf

ではどのユーザーがどれくらいトークンを保持しているか確認できるbalanceOf関数を実行していきましょう。

コントラクトをデプロイした以下のアドレスの右にあるコピーボタンをクリックしてください。

image.png

image.png

アドレスをコピーしたら、balanceOfと書かれている右上の矢印をクリックして、accountの部分に先ほどコピーしたアドレスを貼り付けてください。

貼り付けたらcallと書かれているボタンを押すことで、「100000000000000000000000」と表示されます。

デプロイしたアドレスが全てのトークンを所有していることが確認できました。

transfer

次にトークンを他のアドレスに送付してみます。

ここからは手順が複雑になってくるので動画で紹介していきます。

transferの図

他のアドレスを指定して1000トークンを送れました!

approve

他のアドレスに自分が所有しているトークンをtransferする許可を与えたいと思います。

approveの図

他のアドレスとトークン量を指定して、approve関数を実行してtransferする許可を与えることができました。

allowance

では本当にtransferする許可を与えられているのか確認していきます。

allowance関数を実行することで、transferできるトークンの量を確認できます。

トークン所有者のアドレスと先ほどtransfer許可を与えたアドレスを与えた結果、approve関数を実行したときに指定した10000という数値が表示されました。

allowanceの図

しっかりtransfer許可を与えることができていますね。

transferFrom

ではtransferの許可を与えられたアドレスから、別のアドレスにトークンを送りたいと思います。

transferFrom.gif

トークン所有者のアドレスと3つ目の別のアドレスを指定して、transferの許可を与えられたアドレスからtransferFrom関数を実行して1000トークンを送ることができました。

transfer許可を与えられていないと、トークン所有者以外がtransferFrom関数を実行しても失敗してしまうのでぜひ試してみてください!

decreaseAllowance

次にtransfer許可を与えているトークンの量を減らしていきます。

decreaseAllowance.gif

transfer許可を与えているトークン量の調整は、再度approve関数を実行すれば良いと思うかもしれないです。

しかし、approve 関数はトークン量を更新してしまうため、現在transfer許可を与えているトークン量に対して増減させることはできません。

そこで decreaseAllowance 関数を実行することで、10000という値から5000という値に減らすことができました。

(ちょうど半分の値なので更新したように見えますが、ちゃんと減算されています。)

increaseAllowance

では最後に decreaseAllowance 関数の逆の処理を行う increaseAllowance 関数を実行して、transfer許可を与えているトークン量を増やしていきましょう!

increaceTransfer.gif

10000 トークンを追加したところ、15000 に増えていることが確認できました。

Goerli Testnetにデプロイ

2025年11月現在Goerli Testnetは停止しているので、Sepolia Testnetなどを使用してください。

では次にGoerli Testnetにデプロイしていきます!

Metamask

まだMetamaskを追加していない人は以下から追加してください。

Goerli Testnet ETH

次にGoerli TestnetのETHを取得します。 Faucetと呼ばれところから取得することができます。 いくつか取得する方法があるのですが、以下のAlchemyのFaucetから取得するのがおすすめです。

24時間ごとに0.5Goerli ETHを受け取ることができます。

デプロイ準備

ではここからデプロイの準備をしていきます。

まずはMetamaskをクリックして、Goerli test networkに切り替えてください。 その後Remixに戻って、もし前回デプロイしたデータが残っている場合はゴミ箱マークがあるのでクリックしてください。

次に赤枠の部分を「Injected Provider - Metamask」にしてください。 こうすることで、デプロイ時にMetamaskが起動するようになります。 Goerli Testnetが選択されていると、「Injected Provider - Metamask」の下に「Goerli (5) network」と表示されて、Goerli Testnetと接続されていることが確認できます。

これで準備完了です。

Goerli Testnetにデプロイ

ではGoerli Testnetにデプロイしていきましょう! 上記の手順でEtherscanのサイトが確認できれて以下のように「Success」と表示されていればデプロイ完了です!

以下から「CARDトークン」が作成されているのを確認できます。

最後に

今回は『ERC20』についてまとめてきました。

他でも色々記事を書いているのでぜひよろしければ読んでいってください!

参考