USDCの機能

# はじめに（Introduction）

以前、「[USDTのコントラクトを読む](https://qiita.com/tis-nakagawa/items/577d85d571a13d7c3bc2)」、「[USDTのコントラクトを呼ぶ](https://qiita.com/tis-nakagawa/items/224bfe783bae66c350e8)」というUSDTに関する記事を書きました。
アメリカドル（USD）に対応するコインとして[USDC](https://www.circle.com/en/usdc)があります。
今回はUSDCの機能を見てみます。

# コントラクト（Contract）

Qiitaの記事「[USDCコントラクトコード鑑賞会](https://qiita.com/visvirial/items/ef3ef6355eb5eca87241)」にあるようにUSDCはProxy という抽象コントラクトとなっています。
実際に呼ばれているコントラクトを探してみます。

Proxyのコントラクト生成はトランザクションハッシュ「[0xe7e0fe390354509cd08c9a0168536938600ddc552b3f7cb96030ebef62e75895](https://etherscan.io/tx/0xe7e0fe390354509cd08c9a0168536938600ddc552b3f7cb96030ebef62e75895)」です。

[FiatTokenProxy](https://etherscan.io/address/0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48#code)の「Constructor Arguments」から最初のコントラクトアドレスは「[0x0882477e7895bdC5cea7cB1552ed914aB157Fe56](https://etherscan.io/address/0x0882477e7895bdC5cea7cB1552ed914aB157Fe56#code)」だとわかります。
コントラクト名は「FiatTokenV1」です。

コントラクトを更新するときに「Upgraded」イベントが発生するので調べてみます。

|Transaction Hash|Event Name|Args[0]|
|:--|:--|:--|
|0xe6f0f754398d89583da8e4229c5d7aaa00739a3ae334ecfc2839ac396b4836e3|Upgraded|0xB7277a6e95992041568D9391D09d0122023778A2|
|0xe2e40640ffd5f76538cd23660cf56f00bfebd5fe925ebad6b8067c4cee18a2c3|Upgraded|0xa2327a938Febf5FEC13baCFb16Ae10EcBc4cbDCF|
|0xae3ad89e569f27d47a8a02999a6d937c12aaa6bc50e66650e7cbd3244bde9951|Upgraded|0x43506849D7C04F9138D1A2050bbF3A0c054402dd|

３回更新していることが分かります。
コントラクトはそれぞれ以下の順番で更新されています。

- [FiatTokenV1](https://etherscan.io/address/0x0882477e7895bdC5cea7cB1552ed914aB157Fe56#code)
- [FiatTokenV2](https://etherscan.io/address/0xB7277a6e95992041568D9391D09d0122023778A2#code)
- [FiatTokenV2_1](https://etherscan.io/address/0xa2327a938Febf5FEC13baCFb16Ae10EcBc4cbDCF#code)
- [FiatTokenV2_2](https://etherscan.io/address/0x43506849D7C04F9138D1A2050bbF3A0c054402dd#code)

# コントラクト機能

FiatTokenV1、FiatTokenV2、FiatTokenV2_1は１ファイルですが、FiatTokenV2_2は23ファイルにわかれています。
23ファイルから機能の比較をしてみます。

|機能|V2_2|V2_1|V2|V1|概要|
|:--|:--:|:--:|:--:|:--:|:--|
|FiatTokenV2_2.sol|✓|-|-|-|v2_2メインコントラクト|
|Address.sol|✓|✓|✓|-|**※１**|
|SafeERC20.sol|✓|✓|✓|-|**※１**|
|IERC20.sol|✓|✓|✓|-|ERC20のインターフェース|
|SafeMath.sol|✓|✓|✓|✓|オバーフロー対策した四則演算|
|FiatTokenV2_1.sol|✓|✓|-|-|v2_1メインコントラクト|
|FiatTokenV2.sol|✓|✓|✓|-|V2メインコントラクト|
|EIP712Domain.sol|✓|✓|✓|-|EIP712ドメインセパレータ **※２**|
|EIP3009.sol|✓|✓|-|-|認証Transfer **※３**|
|EIP2612.sol|✓|✓|-|-|署名Approvals **※４**|
|AbstractFiatTokenV2.sol|✓|✓|✓|-|V2抽象コントラクト|
|Pausable.sol|✓|✓|✓|✓|一時停止機能|
|Ownable.sol|✓|✓|✓|✓|承認制御機能|
|FiatTokenV1.sol|✓|✓|✓|✓|V1抽象コントラクト|
|Blacklistable.sol|✓|✓|✓|✓|許可リスト|
|AbstractFiatTokenV1.sol|✓|✓|✓|-|V1抽象コントラクト|
|Rescuable.sol|✓|✓|✓|-|**※５**|
|FiatTokenV1_1.sol|✓|✓|✓|-|v1+Rescuableコントラクト|
|SignatureChecker.sol|✓|-|-|-|ERC1271の実装 **※６**|
|MessageHashUtils.sol|✓|-|-|-|EIP712のハッシュ作成|
|EIP712.sol|✓|✓|✓|-|**※２**|
|ECRecover.sol|✓|✓|✓|-|ECDSAのrecoverライブラリ|
|IERC1271.sol|✓|-|-|-|ERC1271のインターフェース **※６**|


**※１**：Solidity の戻りデータ サイズ チェック メカニズムを自分で実装しているため、ここでは低レベルの呼び出しを実行して、このメカニズムをバイパスする必要があります。
この呼び出しを実行するには、{Address.functionCall} を使用します。この呼び出しは、ターゲット アドレスにコントラクト コードが含まれていることを確認し、低レベルの呼び出しが成功したことをアサートします。

**※２**：[EIP-712: Typed structured data hashing and signing | 型付き構造化データのハッシュと署名](https://eips.ethereum.org/EIPS/eip-712)

**※３**：[ERC-3009: Transfer With Authorization | 認証Transfer](https://eips.ethereum.org/EIPS/eip-3009)

**※４**：[ERC-2612: Permit Extension for EIP-20 Signed Approvals | 署名済みApprovalsの許可(Permit)拡張](https://eips.ethereum.org/EIPS/eip-2612)

**※５**：このコントラクトでロックされているERC20トークンを救出します。

**※６**：[ERC-1271: Standard Signature Validation Method for Contracts | コントラクトの標準署名検証](https://eips.ethereum.org/EIPS/eip-1271)

# 拡張機能の流れ

ERC20が規定している機能以外の拡張機能の流れについてみてみます。

- FiatTokenV1
    - 発行（Mint）：コインの追加、発行可能アドレスのみ可能
    - 償却（Burn）：コインの削除、発行可能アドレスのみ可能
    - 一時停止（Pausable）：ERC20の機能を停止/再開、一時停止可能アドレスのみ可能 
    - 承認制御（Ownable）：管理系関数を制限する為の承認制御
    - 許可リスト（Blacklistable）：ERC20の機能をアドレス毎に制御
- FiatTokenV2
    - トークン救出（Rescuable）：コントラクトにロックされているトークンの救出
- FiatTokenV2_1
    - 認証Transfer（EIP3009）：署名を介して代替での転送（Transfer）を可能、GAS代支払いに対する委任
    - 署名済みApprovals（EIP2612）：署名を介して代替での許可（Approvals）を可能、GAS代支払いに対する委任
- FiatTokenV2_2
    - コントラクトの署名検証（IERC1271）：EIP3009とEIP2612にERC1271を追加、コントラクトからのEIP3009とEIP2612操作が可能

# まとめ（Conclusion）

V1はUSDTと同じ機能ですが、V2から機能が拡張されています。
ERC20トークンを利用（転送や許可）する場合にはGAS代としてチェーンのメインコイン（ETHなど）が必要となります。
一般のユーザーはメインコインを持っていない為、興味のあるERC20を利用する為にはメインコインを購入するところからはじめる必要があります。
こうのようなユーザーにも対応できるように、EIP3009やEIP2612を導入したと思われます。
また、[ERC-4337: Account Abstraction Using Alt Mempool](https://eips.ethereum.org/EIPS/eip-4337)のようなコントラクトをアカウント（ウォレット）とするような仕組みも利用されてきています。
これらにも対応できるようにERC1271にも対応したと思われます。

USDCはアップデートを行いながらユーザーのニーズに合わせているようです。