[ERC173] コントラクトの所有権を制御できる仕組みを理解しよう！

# はじめに

初めまして。
**CryptoGames**というブロックチェーンゲーム企業でエンジニアをしている **cardene（かるでね）** です！
スマートコントラクトを書いたり、フロントエンド・バックエンド・インフラと幅広く触れています。

https://cryptogames.co.jp/

代表的なゲームは**クリプトスペルズ**というブロックチェーンゲームです。

https://cryptospells.jp/

今回は、コントラクトの所有権を制御できる**ERC173**についてまとめていきます！

:::note info
以下にまとめられているものを翻訳・要約・補足しながらまとめていきます。
:::

https://eips.ethereum.org/EIPS/eip-173

# 概要
この仕様では、コントラクトを所有または制御する標準となる関数を定義します。

実装により、現在のコントラクトの所有者アドレスを取得できるようになります。
また、所有権の移転が可能になり、所有権が変更されたときの標準化されたイベントが発行されます。

# 動機
多くのスマートコントラクトは、資金を引き出したりコントラクトの管理アクションを実行したりするために、一定数のアドレスによって所有または制御される必要があります。
コントラクトの所有権を処理するためのインターフェースを標準化しておくことで、ユーザーインターフェースとコントラクトとの互換性を保つことができます。

標準化によってメリットをもたらす、コントラクトとアプリケーションの例は以下になります。

1. Ethereumのコントラクトを購入/販売/オークションする取引所。
    - コントラクトの所有者を取得し、所有権を移転することで実現できます。
2. コントラクトの所有権を保持し、コントラクトの所有権を移転できるコントラクトウォレット。
3. コントラクトのデプロイ。
    - コントラクトのデプロイでは、コントラクトの所有者のみが自分のコントラクトを追加/削除できるようにすることが合理的です。
    - コントラクトをデプロイする時、コントラクトの所有者による署名の検証が必要です。
4. コントラクトの所有権を表示および移転するインターフェース。

# 仕様
すべての**ERC173**規格のコントラクトは、**ERC173**インターフェースを実装する必要があります。
コントラクト**ERC173**インターフェースのために**ERC165**も実装する必要があります。

```javascript
interface ERC173 /* is ERC165 */ {
    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

    function owner() view external returns(address);
	
    function transferOwnership(address _newOwner) external;	
}

interface ERC165 {
    function supportsInterface(bytes4 interfaceID) external view returns (bool);
}
```

## OwnershipTransferred

コントラクトの所有権が移転した時に発行されるイベント。
コントラクトの以前の所有者と新しい所有者のアドレスが、インデックス付きでログとして発行されます。

![ブログERC & EIP (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/570269/828cfd96-fd92-75e7-efde-a3fde23f7225.png)

## owner

コントラクトの現在の所有者のアドレスを取得する関数。
`pure`または`view`として実装できます。

## transferOwnership

コントラクトの所有者を別のアドレスに移転する関数。
コントラクトの所有者のみが実行できます。
所有権を破棄する場合は、引数の`_newOwner`に`address(0)`という0アドレスを指定します。

:::note info
0アドレスを所有者に指定することで、誰も所有権を持つことができなくなります。
:::

![ブログERC & EIP (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/570269/0d29895f-7b9c-502c-c81d-7f997008212a.png)

`public`または`external`として実装できます。

# 補足

この標準の実装にあたり以下を意識する必要があります。

- コントラクト肥大化を防ぐために、インターフェース内の関数の数を最小限に抑えること。
- 既存のコントラクトとの後方互換性を保つこと。
- シンプルさ
- ガス効率

他に以下についても検討されています。

1. Ethereum Name Service (ENS) ドメイン名をコントラクトに関連付ける方法。

    - コントラクトの`owner()`関数は、特定のENS名の所有者アドレスを参照し、それをコントラクトの所有者アドレスとして使用することができます。
    - このスキームを使用すると、コントラクトの所有権を別のアドレスに移転するためにENSドメイン名の所有権を移転することができます。
    - ただし、このアプローチの欠点は、既存のコントラクトとの後方互換性がなく、所有者アドレスを取得するために外部のENS関連コントラクト実行のためのガス代が必要となる点です。

2. ERC721規格のNFTをコントラクトに関連付ける方法。

    - コントラクトの所有権をNFTの所有権と関連付けることができます。
    - このアプローチの利点は、**ERC721**規格のインフラを使用してコントラクトを売買/オークションできる点です。
    - ただし、このアプローチの欠点は、追加の複雑さとインフラが必要となる点です。
    - コントラクトは特定のNFTと関連付けられる可能性がありますが、そのNFTはコントラクトの所有権を追跡するためにプログラムされていない限り、コントラクトの所有権を追跡しないことです。
    - また、この方法でコントラクトの所有権を扱うことは後方互換性がありません。

この標準は、上記の所有権スキームや他のスキームも同じコントラクト内で実装することを排除していません。
例えば、コントラクトはこの標準を実装し、所有権を複数の方法で管理および移転できるように他のスキームも実装できます。
この標準は、後方互換性があり、軽量で実装が簡単であり、広く採用されるシンプルな所有権スキームを提供します。

# セキュリティ上の考慮事項
`owner()`関数が外部所有アカウントのアドレスを返す場合、そのプライベートキーが失われたり、漏洩しないように注意する必要があります。

# 後方互換性
既存の多くのコントラクトはすでにこの標準を実装しています。

# 最後に

今回は「コントラクトの所有権を制御できる**ERC173**」についてまとめてきました！
いかがだったでしょうか？

実装については今後追記していきます。

質問などがある方は以下のTwitterのDMなどからお気軽に質問してください！

[Twitter @cardene777](https://twitter.com/cardene777)

# 採用強化中！

CryptoGamesでは一緒に働く仲間を大募集中です。

https://www.wantedly.com/companies/cryptogames

この記事で書いた自分の経験からもわかるように、裁量権を持って働くことができて一気に成長できる環境です。
「ブロックチェーンやWeb3、NFTに興味がある」、「スマートコントラクトの開発に携わりたい」など、少しでも興味を持っている方はまずはお話ししましょう！