ERC20トークン開発ハンズオン

# はじめに

当記事は[ビットコインとか勉強会#60【ERC20トークン開発ハンズオン】](https://cryptocurrency.connpass.com/event/236343/)の資料です。

アーカイブ動画は↓こちらになります。

https://youtu.be/CKe71Qi7lxo

# Remix

https://remix.ethereum.org/

↑EthereumのIDE「Remix」を使って、早速デプロイしてみましょう。

Google ChromeかBraveで開いてください。他のブラウザは動作できるかわからないです。

![スクリーンショット 2022-01-26 17.31.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/194002/1e0d101f-1c8b-8d9d-c83a-886cd6823d59.png)


`Workspaces`の中で、`contracts`ディレクトリの中に`MyToken.sol
`ファイルを作成します。

# ERC20ソースコード

https://solidity-by-example.org/app/erc20/

「Create your own ERC20 token」の箇所をなぞればすぐにERC20トークンが開発できます。

```MyToken.sol
pragma solidity ^0.8.10;

import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v4.0.0/contracts/token/ERC20/ERC20.sol";

contract MyToken is ERC20 {
    constructor(string memory name, string memory symbol) ERC20(name, symbol) {
        // Mint 100 tokens to msg.sender
        // Similar to how
        // 1 dollar = 100 cents
        // 1 token = 1 * (10 ** decimals)
        _mint(msg.sender, 100 * 10**uint(decimals()));
    }
}
```

上記コードをRemixのerc20.solに貼り付けます。

![スクリーンショット 2022-01-26 17.32.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/194002/f14ca054-b595-9925-81db-3ec563aadd49.png)


![スクリーンショット 2022-01-23 22.13.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/194002/72de9589-e058-fc5f-6242-070585f649c6.png)

左のメニューに、エラーが出てしまいました。

importするファイルが読み込めないとのことです。

↓代わりにこちらを読み込んでみましょう。

https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/ERC20.sol

importするファイルのURLを書き換えてあげて、```MyToken.sol```は以下のようになります。

```MyToken.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.10;

import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/ERC20.sol";

contract MyToken is ERC20 {
    constructor(string memory name, string memory symbol) ERC20(name, symbol) {
        // Mint 100 tokens to msg.sender
        // Similar to how
        // 1 dollar = 100 cents
        // 1 token = 1 * (10 ** decimals)
        _mint(msg.sender, 100 * 10**uint(decimals()));
    }
}
```

![スクリーンショット 2022-01-26 17.34.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/194002/7e6527dc-fd0f-8071-c1e5-0e3b68e83e2d.png)

コンパイルが通るようになりました。

# JavaScript VMを使ったデプロイ

Testnetを使う前に、練習でRemixのVM上にてERC20コントラクトをデプロイしてみます。

左のメニュー下から二つ目のアイコンをクリックして、デプロイしていきます。

`ENVIRONMENT`は初期値の`JavaScript VM(London)`のままにします。

![スクリーンショット 2022-01-26 17.36.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/194002/17a72907-4bb3-a378-7ae7-465fb5d7cba0.png)

![スクリーンショット 2022-01-23 22.29.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/194002/a8b0ef9b-b72d-b690-b7df-5d73c87741eb.png)

`Deploy`ボタンの横の入力欄に

```
"Winecoin, "WIC"
```
というように、コイン名、ティッカー(3-4文字英大文字の略称)をつけてみましょう。

そして、`Deploy`ボタンを押します。

もしくは、`Deploy`ボタンの右側の`v`を押すと、引数ごとに入力しやすくなります。

![スクリーンショット 2022-01-24 21.35.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/194002/8261294a-c28d-bd25-4706-816275d49ca9.png)

⇅引数ごとに入力する場合、`"`(ダブルクォーテーション)は有っても無くてもデプロイできます。

![スクリーンショット 2022-01-24 20.25.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/194002/2cbbe68e-aa7c-3685-9b66-133fdcbf2797.png)

![スクリーンショット 2022-01-26 17.38.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/194002/431e59bd-e8f7-d307-3c02-93449501367c.png)

コンソールで緑のチェックマークが出てきたので、デプロイ成功です。

![スクリーンショット 2022-01-26 17.39.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/194002/cbeec085-f30d-7836-7ec9-f9faa7a4a1d2.png)

`DEPRPY & RUN TRANSACTIONS`の一番下に`MYTOKEN AT 0X...`とあります。

`>`をクリックします。

![スクリーンショット 2022-01-23 22.37.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/194002/3ed732c5-85c9-079b-6c4f-8772c122f252.png)

これらはデプロイしたERC20コントラクトの関数になります。

テキスト入力欄のあるものは引数を取る関数。

橙色のボタンは送金等、状態を変化させる関数。

青色のボタンは状態を変化させない関数でチェーン上のコントラクトの状態を確認するものになります。

## 状態の参照

![スクリーンショット 2022-01-24 21.50.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/194002/3e0e1239-24d0-26e4-0284-3b9344933d21.png)

それぞれ確認してみます。

`decimals'は小数点以下何桁まで分割可能にするか。BTCは8桁ですが、ETHが18桁なのでERC20も18桁のものが多いです。

`name`はデプロイ時に入力した`Winecoin`です。

`symbol`はデプロイ時に入力した`WIC`です。

totalSupplyは`100000000000000000000`です。

これはソースコード`erc20.sol`の

```
_mint(msg.sender, 100 * 10**uint(decimals()));
```

にある通り、`100×10^18`作られています。

100WICあり、補助単位の最小値(10の18乗分の1)を`alc`としたら、100000000000000000000alcあることになります。

![スクリーンショット 2022-01-24 21.57.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/194002/89e3229c-7df1-f63f-7cad-cfe206d5a79a.png)

ACCOUNT欄をコピーして、`balanceOf`に貼り付け実行すると、100000000000000000000あることが確認できます。

![スクリーンショット 2022-01-24 21.58.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/194002/2b9a83e9-4845-837d-769e-32ae4b1570d6.png)


## トークンの送金

Accountのプルダウンから今使っている一番上のアドレス以外を選択しましょう。

![スクリーンショット 2022-01-24 21.48.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/194002/ce8a8d62-be69-f9d8-be5c-86b3c5c8521a.png)

![スクリーンショット 2022-01-24 21.49.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/194002/207aea31-ab70-7f45-f156-f8f9b41a6197.png)

異なるアドレスを選んでコピーボタンを押します。

送金前の送金先の残高を確認してみましょう。

![スクリーンショット 2022-01-24 22.10.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/194002/e3a6b410-2134-d34c-4ae8-eb5c8b404a97.png)

当然0です。

![スクリーンショット 2022-01-24 22.09.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/194002/3b694ac8-04d1-4f73-7639-1ec1641e2cb5.png)

`transfer`の`recipient`の入力欄に貼り付け、｀amount｀には送金元の所有額以下を入力します。

例えば、`5000000000000000000`

ACCOUNTを一番上の最初のアドレスに戻します。

![スクリーンショット 2022-01-24 22.12.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/194002/3e2e373f-9947-486b-07d7-90a7357016e3.png)

実行します。

![スクリーンショット 2022-01-24 22.14.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/194002/5f3d2b74-a539-09ae-9c6f-ec382271c9b4.png)

送金先の残高がちゃんと増えていました。

![スクリーンショット 2022-01-24 22.14.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/194002/86d04154-15f6-a8e2-8ddc-68e8ca8076aa.png)

送金元の残高が`5000000000000000000`減っています。

## その他の関数

`approve`, `allownance`, `transferFrom`については普段使わない機能です。今回は扱わないですが、詳しくは下記記事をご覧ください。

https://qiita.com/ywzx/items/fe6f0fa1086c25a5dfef#4-allowance%E9%96%A2%E6%95%B0-transferfrom%E9%96%A2%E6%95%B0-approve%E9%96%A2%E6%95%B0

# ソースコード

```
pragma solidity ^0.8.10;

import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/ERC20.sol";

contract MyToken is ERC20 {
    constructor(string memory name, string memory symbol) ERC20(name, symbol) {
        // Mint 100 tokens to msg.sender
        // Similar to how
        // 1 dollar = 100 cents
        // 1 token = 1 * (10 ** decimals)
        _mint(msg.sender, 100 * 10**uint(decimals()));
    }
}
```

`contract`でコントラクトの宣言をします。

A is Bで継承ができます。AがBのサブクラス。（BがAのスーパークラス)

`constructor`とはデプロイ時に実行される関数です。

https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/ERC20.sol

ERC20.solをimportしていて、ERC20は以下の3つのコントラクトをimportし継承しています。

https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/IERC20.sol

https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/extensions/IERC20Metadata.sol

https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/Context.sol

# Metamaskを使ったデプロイ

ここからは、Metamaskを使ってTestnetで実際にERC20コントラクトをデプロイし、送金してみましょう。

Metamaskはブラウザ拡張型のウォレットです。Ethereumを使うWebページに秘密鍵を露出させず、セキュアに署名をすることができます。

https://chrome.google.com/webstore/detail/metamask/nkbihfbeogaeaoehlefnkodbefgpgknn?hl=ja

↑こちらからChromeまたはBraveに追加します。

新規で作成する場合、ニーモニックが画面に表示されますが、紙に書いて厳重に保管しましょう。

(Testnetでしか使わない場合はPC上のファイルに保管でもいいでしょうが。。）

![スクリーンショット 2022-01-25 23.58.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/194002/3980caa3-171a-df22-475d-1a740108251f.png)

ネットワークをRopstenに切り替えましょう。

Metamaskを準備しておきます。

# Faucet

EthereumのTestnet`Ropsten`のFaucetからコインを入手します。

Faucetとは蛇口という意味で、ブロックチェーンの世界では、Testnetコインのバラマキ所です。

https://faucet.metamask.io/

↑MetaMask Ether Faucetが使えなくなってしまいました。

色々なFaucetを確認したところ、正常に稼働するのは以下です。（1日に0.3ETH）

https://faucet.egorfine.com/

※ハンズオン参加者が一斉にFaucetを触るとダウンする恐れがあります。既にRopstenのETHをお持ちの方は使用をお控えください。

環境は`Injected Web3`を選びます。

![スクリーンショット 2022-01-26 0.04.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/194002/8cf8a73c-a301-c1be-fc16-d5fa6ad3699f.png)

![スクリーンショット 2022-01-26 0.06.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/194002/3a500cce-b8cc-d702-50dd-542258ecad91.png)

Metamask側では、`接続`をクリックします。

![スクリーンショット 2022-01-26 0.07.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/194002/93ad4c82-a3dc-7237-dd53-bb48fd98447e.png)

Metamaskのアカウントが接続済みになっていることを確認し、Remixの`ACCOUNT`と同じであることを確認します。

![スクリーンショット 2022-01-26 0.10.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/194002/6ffe3bfa-2da6-f5bf-ff4b-1fa87aabd512.png)

NAMEとSYMBOLを入力したらデプロイしてみましょう。VMのときと同じでも違ってもどちらでも構いません。

![スクリーンショット 2022-01-26 0.11.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/194002/190b0b3d-dc0e-6ad3-2f0f-21e8fef3a2d4.png)

Deployボタンを押すと、Metamaskがポップアップします。

`確認`ボタンを押すとコントラクトをデプロイするトランザクションがブロードキャストされます。

![スクリーンショット 2022-01-26 0.12.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/194002/0f777409-51b0-04f9-d539-100188969644.png)

コンソールに`creation of MyToken pending...`と表示されます。

VMでやったときと異なり、時間がかかります。

![スクリーンショット 2022-01-26 0.16.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/194002/7af5dbe2-85d1-9121-2f94-d5ab056bb6aa.png)

デプロイできました。

![スクリーンショット 2022-01-26 0.17.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/194002/86b0eaf7-7156-ff5f-e334-fe8f5875693a.png)

transaction hashをコピーして、ropstenのetherscanで見てみましょう。

https://ropsten.etherscan.io/

↓検索窓にTransaction Hashを登録した結果がこちらです。

https://ropsten.etherscan.io/tx/0xe0715f68abdc816aea9eb9d69162a218270c72a6cbc5f87ebb213c87ac9ed99b

コントラクトの内容を見てみましょう

https://ropsten.etherscan.io/token/0xe1ad59342294e7c307e71e28af0246aeedb1364a

他のアカウントをコピーしてそれを送金先としてトークンを送ってみましょう。

![スクリーンショット 2022-01-26 0.37.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/194002/c0a70d6b-e80f-a98f-5f2d-f51bf2e3bab8.png)

![スクリーンショット 2022-01-26 0.39.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/194002/20e52791-bb4a-e7e9-8b9d-f5494b3f14ba.png)

Metamask上で、`50 WIC`と出てきました。

`確認`ボタンを押します。

送金できました。

https://ropsten.etherscan.io/tx/0x6105a2da97ea19d314964497dc5ebc06e71386f2fa1876e6209815f143dd360f

# 画面を閉じた後にコントラクトを触る方法

コードのタブで該当のファイルを開いた状態で、デプロイしたアドレスを入力すると、`Deployed Contracts`にコントラクトの関数一覧が出てきます。

![スクリーンショット 2022-01-26 0.52.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/194002/9a79e80d-1df3-8297-5ff8-95487f09e3ec.png)

# 便利ツールのご紹介

https://wizard.openzeppelin.com/

GUIが整ったERC20やERC721のソースコードを簡単に作成できるツールです。

# 続き

approve, transferFromの使い方について続編を書きました。

https://qiita.com/shu-kob/items/3dab9f7ea642f3ef0d41