SaaS企業で働くPdMエンジニアのブログ

SaaS企業でプロダクトマネージャー兼エンジニアとして働いています。趣味でブロックチェーンやNFTも時々やります

ERC1820 Pseudo-introspection Registry Contractについて

f:id:naomasabit:20191215194306p:plain

EthereumのERC1820 Pseudo-introspection Registry Contract(擬似説明を行うレジストリコントラクト)について説明します。

このEIPはERC | Ethereum Improvement Proposals においてファイナライズされた提案であり、ERCとして正式登録されています。

ERC1820の公式定義はこちらで、

eips.ethereum.org

こちらに基づいて説明を書いていきます。

何をするコントラクトか

ERC1820はあるアドレスと実装内容の説明マッピングを管理することができます。例えば、ERC20トークンはそれ自体にトークン名などを設定していますが、コントラクトの中身を見るまでERC20であるかどうかの説明はわかりません。 このコントラクトでは、アドレスがERC20であるか、ERC721であるかなどを管理しておくことでアドレスの説明を閲覧できます。

またこれ自体は特殊なERCで、

  • ERC20などと違って、Ethereumブロックチェーン内に1個しかコントラクトを持ちません。なぜなら、Ethereumブロックチェーン内で説明を保存する共通の台帳コントラクトという位置付けだからです。

  • そのため、ERCにデプロイするためのhexが固定されており、アドレスも固定です。

アドレスとそのインターフェースを管理するinterfacesマッピング

ERC1820コントラクトには、アドレスとインターフェースの組み合わせを管理するマッピングを持っています。

基本的にはERC1820内の以下マッピングを更新していきます。
(このマッピングを設定するアドレス:
 (インターフェースの名付けをする文字列(bytes32型):定義インターフェースが実装されているコントラクトアドレス)
 )
というマッピング定義です。

    /// @notice mapping from addresses and interface hashes to their implementers.
    mapping(address => mapping(bytes32 => address)) internal interfaces;

ERC1820でinterfaceに関連する関数は以下で、setやgetなどがありますね。

    function canImplementInterfaceForAddress(bytes32 interfaceHash, address addr) external view returns(bytes32);
    function getInterfaceImplementer(address _addr, bytes32 _interfaceHash) external view returns (address) {
    function setInterfaceImplementer(address _addr, bytes32 _interfaceHash, address _implementer) external {
    function interfaceHash(string calldata _interfaceName) external pure returns(bytes32) {

addressの管理権限を設定するmanagersマッピング

ERC1820ではmanagersというマッピングも設定できます。managersは、interfacesに登録するアドレスの管理アドレスを設定できます。managerに設定されているアドレスは、manager管理下のアドレスについてinterfacesに登録できます。

managersマッピングは以下で、(対象アドレス:managerアドレス)のマッピングです。

    /// @notice mapping from addresses to their manager.
    mapping(address => address) internal managers;

managersマッピングに関連する関数は以下になります。

    function setManager(address _addr, address _newManager) external {
    function getManager(address _addr) public view returns(address) {

どのように呼び出されるか、ERC1400の実装からみてみる

ConsenSysのセキュリティトークン実装であるERC1400ではこのERC1820コントラクトが使われています。ERC1820を呼び出す実装をERC1820Clientコントラクトとして実装しています。

Client実装から、ERC1400.solのコンストラクタでERC1820の関数を呼び出しています。こちらでは"ERC1400Token"をインターフェースのラベル付け文字列として使っています。

// ERC1400.solのコンストラクタ。setInterfaceImplementationで呼び出している
  constructor(
    string memory name,
    string memory symbol,
    uint256 granularity,
    address[] memory controllers,
    address certificateSigner,
    bytes32[] memory defaultPartitions
  )
    public
    ERC1400Partition(name, symbol, granularity, controllers, certificateSigner, defaultPartitions)
  {
    // "ERC1400Token"というラベルとこのSTのアドレスを引数にしている
    setInterfaceImplementation("ERC1400Token", address(this));
    _isControllable = true;
    _isIssuable = true;
  }


/// Base client to interact with the registry.
contract ERC1820Client {
    // 0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24はERC1820のアドレス
    ERC1820Registry constant ERC1820REGISTRY = ERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);

    // interfacesを登録する関数
    function setInterfaceImplementation(string memory _interfaceLabel, address _implementation) internal {
        bytes32 interfaceHash = keccak256(abi.encodePacked(_interfaceLabel));
        ERC1820REGISTRY.setInterfaceImplementer(address(this), interfaceHash, _implementation);
    }

    // 登録済interfacesにアクセスするための関数
    function interfaceAddr(address addr, string memory _interfaceLabel) internal view returns(address) {
        bytes32 interfaceHash = keccak256(abi.encodePacked(_interfaceLabel)); // 引数のラベルをkeccak256ハッシュ化
        return ERC1820REGISTRY.getInterfaceImplementer(addr, interfaceHash);
    }

    // address(this)- ここではERC1400アドレスのmanagerを設定する
    function delegateManagement(address _newManager) internal {
        ERC1820REGISTRY.setManager(address(this), _newManager);
    }
}

まとめ

ERC 1820は、対象のアドレスに求める関数たちが実装されているかを確認できるレジストリとして利用できるコントラクトです。ConsensysにおけるERC1400のコンストラクタでの使い方のように、デプロイ時に登録しておくことでアドレスの説明をみることができます。

ERC165という同種のインターフェースを確認する規格もあるのですが、こちらとの互換性を保つためにERC165のための関数もERC1820には定義されています。ERC165は @y_nakajo さんのブログが詳しいです。

ContractのInterface検出機能の提案ERC-165とERC-820を調べてみた - アルゴリズムとかオーダーとか

また、ERC1820の仕組みをENSのようなドメインサービスとの組み合わせも考えられるかもしれません。ノートで書いているエンジニアがブロックチェーンを見るマガジンにENSを書いていただいたのでよければこちらもご覧ください。

note.com

エンジニアがブロックチェーンを見るマガジンもよろしくお願いします

note.com

  • zhimei87

    突然のご連絡失礼致します。
    金融・投資系の総合Eコマースサイト「GogoJungle」を運営しております
    株式会社ゴゴジャンのマーケティング担当の寺崎と申します。

    GogoJungleではFXシステムトレード、裁量トレード系ノウハウ、
    仮想通貨投資、投資助言の月額サービスなど
    多岐に渡った商品を取り扱っております。

    ASPも兼ねておりまして、販売商品やFX会社の口座開設案件に関して
    アフィリエイト報酬をお支払いしております。

    ぜひ弊社「GogoJungle」プラットフォームにて、お持ちのEAや投資に関する電子書籍、
    ノウハウを出品されてみませんか?

    投資助言資格を持つ弊社が販売代理人となり、出品から販促までサポート致します。


    ◆EA販売手数料35%~
    (プログラマー様活躍中!ニックネームで出品可能、独自認証システム有りで不正コピーを防止)

    ◆電子書籍・インジケーター
    販売手数料10%~

    ◆記事販売
    販売手数料15%~
    月額課金、記事単品販売可能

    ◆メルマガ
    販売手数料25%~


    また、出品まではご興味ないという場合でも、ブログ運営のついでにアフィリエイトはいかがでしょうか?
    数多くの商品を取り扱っておりますので「パートナー」登録もぜひご検討ください!



    ご興味ございましたら、ぜひ下記より出品者登録ください。
    また、ご質問等ございましたらいつでもお気軽にご相談ください。
    https://www.gogojungle.co.jp/post/1/15363


    ご出品心よりお待ちしております。

    株式会社ゴゴジャン
    マーケティング
    寺崎

コメントを書く