ローカルに構築したブロックチェーン上にERC20トークンをデプロイして転送・償却してみた

# はじめに
先日,自分のWindowsマシンにWSL2でUbuntu環境を作り,そこにHyperledgerBesuのブロックチェーンを構築。そこに極めて簡単なコントラクトをデプロイして遊んだのだった。これである。

https://qiita.com/oldEng/items/557ceb29a7849e92b5f2

これがなかなか面白く,老技術者に箱庭的愉楽を与えてくれたのだった。今回はせっかく作った箱庭にもう少し植栽がほしくなり,まずはERC20トークンをデプロイした次第。

# コード
ERC20のシンプルな実装はネットですぐに見つかった。拝借しよう｡

```solidity:ERC20Token.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;

interface tokenRecipient { function receiveApproval(address _from, uint256 _value, address _token, bytes calldata _extraData) external; }

contract TokenERC20 {
   string public name;
   string public symbol;
   uint8 public decimals = 18;
   uint256 public totalSupply;

   mapping (address => uint256) public balanceOf;
   mapping (address => mapping (address => uint256)) public allowance;

   event Transfer(address indexed from, address indexed to, uint256 value);
   event Approval(address indexed _owner, address indexed _spender, uint256 _value);
   event Burn(address indexed from, uint256 value);

   constructor(
       uint256 initialSupply,
       string memory tokenName,
       string memory tokenSymbol
   ) public {
       totalSupply = initialSupply * 10 ** uint256(decimals);
       balanceOf[msg.sender] = totalSupply;
       name = tokenName;
       symbol = tokenSymbol;
   }

   function _transfer(address _from, address _to, uint _value) internal {
       require(_to != address(0));
       require(balanceOf[_from] >= _value);
       require(balanceOf[_to] + _value >= balanceOf[_to]);
       uint previousBalances = balanceOf[_from] + balanceOf[_to];
       balanceOf[_from] -= _value;
       balanceOf[_to] += _value;
       emit Transfer(_from, _to, _value);
       assert(balanceOf[_from] + balanceOf[_to] == previousBalances);
   }

   function transfer(address _to, uint256 _value) public returns (bool success) {
       _transfer(msg.sender, _to, _value);
       return true;
   }

   function transferFrom(address _from, address _to, uint256 _value) public returns (bool success) {
       require(_value <= allowance[_from][msg.sender]);     // Check allowance
       allowance[_from][msg.sender] -= _value;
       _transfer(_from, _to, _value);
       return true;
   }

   function approve(address _spender, uint256 _value) public
       returns (bool success) {
       allowance[msg.sender][_spender] = _value;
       emit Approval(msg.sender, _spender, _value);
       return true;
   }

   function approveAndCall(address _spender, uint256 _value, bytes memory _extraData)
       public
       returns (bool success) {
       tokenRecipient spender = tokenRecipient(_spender);
       if (approve(_spender, _value)) {
           spender.receiveApproval(msg.sender, _value, address(this), _extraData);
           return true;
       }
   }

   function burn(uint256 _value) public returns (bool success) {
       require(balanceOf[msg.sender] >= _value);
       balanceOf[msg.sender] -= _value;
       totalSupply -= _value;
       emit Burn(msg.sender, _value);
       return true;
   }

   function burnFrom(address _from, uint256 _value) public returns (bool success) {
       require(balanceOf[_from] >= _value);
       require(_value <= allowance[_from][msg.sender]);
       balanceOf[_from] -= _value;
       allowance[_from][msg.sender] -= _value;
       totalSupply -= _value;
       emit Burn(_from, _value);
       return true;
   }
}
```


こいつをRemixにNew File「ERC20Token.sol」として貼り付けて

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202911/f0f93451-8f78-b6d0-d19c-f1737d2ec825.png)

左側でSolidity compilerを選び,コンパイルのボタンを押下｡

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202911/74504869-ec06-c472-1e67-1b20d7b81191.png)

左側でDeploy & run transactionsを選ぶ｡
Metamaskを拡張機能から立ち上げ,TokenTest1というアカウントを用意。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202911/19242b45-7bc5-8921-ab93-c2cc0e96e340.png)

RemixのこのＶを押して

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202911/6b589b23-ce82-9ab8-0c0e-7b2ac10eb570.png)

ENVIRONMENTやCONTRACTを確認し,ACCOUNTに先ほどのTokenTest1のIDが入っているか確認。
INITIALSUPPLYに発行金額,TOKENNAMEにトークン名（ここではtaka Tokenとした｡takaとはわが幼名なり）,TOKENSYMBOLにはトークン記号（ここではTKCとした）｡DEPLOYの下の3箇所の記入が終わったらtransact｡

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202911/148cd834-2c13-2a24-6793-227edb60b508.png)


するとMetamaskがこんな風に立ち上がるので確認を押下。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202911/8c7b8bec-d31e-4212-58a1-b4f9c1c18081.png)

画面隅にこんなかわいいのが出たら成功だ。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202911/b1b1a2ab-4821-fdef-2dbc-d78b96b1b9ed.png)

左下のこういうののコピーマークをつついてコピーする。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202911/ea0d1936-54bf-2453-029c-3ff9dca225a8.png)


Metamaskで「トークンをインポート」

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202911/3b9b0aef-f307-647f-7b39-4e72e0898811.png)

トークンコントラクトアドレスに先ほどコピーしたやつを貼り付け,「カスタムトークンを追加」を押下。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202911/ff1f6e32-bdc7-8c4c-8da8-e18cfd80e656.png)


こんなのが出たら「トークンをインポート」

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202911/960b19af-968d-7351-8f65-89b70717d8da.png)

1000TKC入った！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202911/8e3ebc64-ad62-03ea-5183-2ede14537e59.png)

# 転送 transfer
次にトークンの転送transferをしてみる｡
転送先のTokenTest2のアドレスをコピー。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202911/e9e7b3d1-fab7-cf9d-49fe-035d946f3e8e.png)

TokenTest1に戻る。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202911/2b636715-2c71-601a-364b-a8d31f92c309.png)

左下の>を突いてみる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202911/c8028cdc-361d-fcce-f745-b7f85b3c76c0.png)

出てきた関数の一覧からtransferの右脇のvを突き,

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202911/0302dedb-82d1-8d32-4dd8-276bd9e0ea78.png)

出てきたこれに先ほどコピーしたTokenTest2のアドレスと金額を10の-18乗単位で入力してtransact｡

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202911/5d35730e-723a-6d03-f939-3a168242756c.png)

1の後に0を20個並べたので,100TKC転送でよろしいね。確認を押下｡

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202911/b5070580-7ed9-4b9d-325f-0c33ad62f3aa.png)

また，かわいいのが出た。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202911/30ec3e46-a789-2f0b-bdb8-54ca1f3f5f10.png)

まず転送元は100TKC残高が減っている。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202911/8c556b47-95af-7321-49a3-0d7f954459ff.png)

次にトークンコントラクトのアドレスをコピー｡

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202911/88f4ebe2-1f20-30cc-f792-b1d298041544.png)

転送先のTokenTest2を開いて，「トークンをインポート」

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202911/11929d4f-605d-6185-a868-44583382963c.png)

トークンコントラクトのアドレスを貼り付けて「カスタムトークンを追加」と押下｡

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202911/e0988131-4207-0c59-349e-7014370d469d.png)

確かに100TKCなので「トークンをインポート」。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202911/5ee7a8d9-1aed-dba7-a2e5-2c4633d2afac.png)

入りました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202911/c2cb1fe5-fc95-4a93-acac-3610afe8575f.png)

# 償却　burn
まずはTokenTest2を表示。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202911/be86b838-f5c7-44c5-daf4-7ff172a480fa.png)


burnの右のvを突く｡
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202911/1927c174-370f-151e-c520-e953b327dc2c.png)

100TKC分を_valueとして記入しtransact｡

![スクリーンショット 2022-04-05 021114.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202911/611c4059-4172-87e9-647a-13bad14c1871.png)

そうするとMetamaskが立ち上がってくるので「確認」押下。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202911/c967fc44-0f85-1457-10c3-67ed01f49f0b.png)

きれいに償却されている。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202911/a4321896-4a58-9b00-a0ba-99a7d8d1a766.png)

## 謝辞
こちらのページを参考にさせていただきました。
https://note.com/toshitoissho/n/na924948e027d