7
10

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

[ERC7432] NFTのさまざまなロールを管理する仕組みを理解しよう!

Posted at

はじめに

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

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

今回は、NFTのさまざまなロールを管理するインターフェースを提案しているERC7432についてまとめていきます!

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

7432は現在(2023年9月7日)では「Review」段階です。

概要

この規格は、NFTに特定のロールを与える仕組みを提案しています。
NFTごとにロールが紐づけられており、あらかじめ設定された時間が経過すると紐づけられたロールは自動的に無効になります。
ここでの「ロール」とは、特定の機能や権限を指すもので、たとえば「管理者」や「所有者」といったものです。
これらのロールは、情報をバイト(bytes32)の形式で保持し、さらにカスタムの「_data」フィールドを持っています。
この「_data」フィールドは、ロールに関連付けられた情報を自由に格納でき、カスタマイズすることが可能です。

動機

このインターフェースは、NFT(非代替トークン)におけるロール管理のための標準の提供を目指しています。
この標準に従うことで、分散型アプリケーション(dApps)は、特権的な操作を実行するためのアクセス制御を実現できます。
たとえば、トークンの発行(エアドロップの権利など)を特定のユーザーに制限することができます。

NFTのロール管理は、dAppsとシームレスに統合され、ユーティリティ(機能や権限)を共有するメカニズムを提供します。
具体的な例として、デジタル不動産を考えてみましょう。
ユーザーはデジタルの不動産NFTを作成し、他のユーザーに「PROPERTY_MANAGER」というロールを与えることができます。
これにより、所有権を譲渡することなく、特定の機能や権限を委任できます。
同じユーザーは「PROPERTY_TENANT」というロールを複数のユーザーに与えることもでき、これによりロールを付与されたアドレスはデジタル不動産にアクセスし、対話することができます。

また、分散型金融(DeFi)においても興味深い活用事例があります。
保険ポリシーをNFTとして発行し、受益者、被保険者、保険会社などをブロックチェーン上で追跡することができます。
これにより、契約者や関係者のロールを透明かつ信頼性の高い方法で管理できます。

仕様

この規格に準拠するコントラクトは、以下のインターフェイスを実装する必要があります。

/// @title ERC-7432 Non-Fungible Token Roles
/// @dev See https://eips.ethereum.org/EIPS/eip-7432
/// Note: the ERC-165 identifier for this interface is 0xd7e151ef.
interface IERC7432 /* is ERC165 */ {
  
    /** Events **/

    /// @notice Emitted when a role is granted.
    /// @param _role The role identifier.
    /// @param _tokenAddress The token address.
    /// @param _tokenId The token identifier.
    /// @param _grantor The user assigning the role.
    /// @param _grantee The user receiving the role.
    /// @param _expirationDate The expiration date of the role.
    /// @param _data Any additional data about the role.
    event RoleGranted(
        bytes32 indexed _role,
        address indexed _tokenAddress,
        uint256 indexed _tokenId,
        address _grantor,
        address _grantee,
        uint64 _expirationDate,
        bytes _data
    );

    /// @notice Emitted when a role is revoked.
    /// @param _role The role identifier.
    /// @param _tokenAddress The token address.
    /// @param _tokenId The token identifier.
    /// @param _revoker The user revoking the role.
    /// @param _grantee The user that receives the role revocation.
    event RoleRevoked(
        bytes32 indexed _role,
        address indexed _tokenAddress,
        uint256 indexed _tokenId,
        address _revoker,
        address _grantee
    );

    /// @notice Emitted when a user is approved to manage any role on behalf of another user.
    /// @param _tokenAddress The token address.
    /// @param _operator The user approved to grant and revoke roles.
    /// @param _isApproved The approval status.
    event RoleApprovalForAll(
        address indexed _tokenAddress,
        address indexed _operator,
        bool _isApproved
    );

    /// @notice Emitted when a user is approved to manage the roles of an NFT on behalf of another user.
    /// @param _tokenAddress The token address.
    /// @param _tokenId The token identifier.
    /// @param _operator The user approved to grant and revoke roles.
    /// @param _isApproved The approval status.
    event RoleApproval(
        address indexed _tokenAddress,
        uint256 indexed _tokenId,
        address _operator,
        bool _isApproved
    );

    /** External Functions **/ 

    /// @notice Grants a role to a user.
    /// @param _role The role identifier.
    /// @param _tokenAddress The token address.
    /// @param _tokenId The token identifier.
    /// @param _grantee The user receiving the role.
    /// @param _expirationDate The expiration date of the role.
    /// @param _data Any additional data about the role.
    function grantRole(
        bytes32 _role,
        address _tokenAddress,
        uint256 _tokenId,
        address _grantee,
        uint64 _expirationDate,
        bytes calldata _data
    ) external;

    /// @notice Revokes a role from a user.
    /// @param _role The role identifier.
    /// @param _tokenAddress The token address.
    /// @param _tokenId The token identifier.
    /// @param _grantee The user that receives the role revocation.
    function revokeRole(
        bytes32 _role,
        address _tokenAddress,
        uint256 _tokenId,
        address _grantee
    ) external;

    /// @notice Grants a role on behalf of a user.
    /// @param _role The role identifier.
    /// @param _tokenAddress The token address.
    /// @param _tokenId The token identifier.
    /// @param _grantor The user assigning the role.
    /// @param _grantee The user that receives the role.
    /// @param _expirationDate The expiration date of the role.
    /// @param _data Any additional data about the role.
    function grantRoleFrom(
        bytes32 _role,
        address _tokenAddress,
        uint256 _tokenId,
        address _grantor,
        address _grantee,
        uint64 _expirationDate,
        bytes calldata _data
    ) external;

    /// @notice Revokes a role on behalf of a user.
    /// @param _role The role identifier.
    /// @param _tokenAddress The token address.
    /// @param _tokenId The token identifier.
    /// @param _revoker The user revoking the role.
    /// @param _grantee The user that receives the role revocation.
    function revokeRoleFrom(
        bytes32 _role,
        address _tokenAddress,
        uint256 _tokenId,
        address _revoker,
        address _grantee
    ) external;

    /// @notice Approves operator to grant and revoke any roles on behalf of another user.
    /// @param _tokenAddress The token address.
    /// @param _operator The user approved to grant and revoke roles.
    /// @param _approved The approval status.
    function setRoleApprovalForAll(
        address _tokenAddress,
        address _operator,
        bool _approved
    ) external;

    /// @notice Approves operator to grant and revoke roles of an NFT on behalf of another user.
    /// @param _tokenAddress The token address.
    /// @param _tokenId The token identifier.
    /// @param _operator The user approved to grant and revoke roles.
    /// @param _approved The approval status.
    function approveRole(
        address _tokenAddress,
        uint256 _tokenId,
        address _operator,
        bool _approved
    ) external;

    /** View Functions **/

    /// @notice Checks if a user has a role.
    /// @param _role The role identifier.
    /// @param _tokenAddress The token address.
    /// @param _tokenId The token identifier.
    /// @param _grantor The user that assigned the role.
    /// @param _grantee The user that received the role.
    function hasRole(
      bytes32 _role,
      address _tokenAddress,
      uint256 _tokenId,
      address _grantor,
      address _grantee
    ) external view returns (bool);
  
    /// @notice Checks if a user has a unique role.
    /// @param _role The role identifier.
    /// @param _tokenAddress The token address.
    /// @param _tokenId The token identifier.
    /// @param _grantor The user that assigned the role.
    /// @param _grantee The user that received the role.
    function hasUniqueRole(
      bytes32 _role,
      address _tokenAddress,
      uint256 _tokenId,
      address _grantor,
      address _grantee
    ) external view returns (bool);
  
    /// @notice Returns the custom data of a role assignment.
    /// @param _role The role identifier.
    /// @param _tokenAddress The token address.
    /// @param _tokenId The token identifier.
    /// @param _grantor The user that assigned the role.
    /// @param _grantee The user that received the role.
    function roleData(
      bytes32 _role,
      address _tokenAddress,
      uint256 _tokenId,
      address _grantor,
      address _grantee
    ) external view returns (bytes memory data_);
  
    /// @notice Returns the expiration date of a role assignment.
    /// @param _role The role identifier.
    /// @param _tokenAddress The token address.
    /// @param _tokenId The token identifier.
    /// @param _grantor The user that assigned the role.
    /// @param _grantee The user that received the role.
    function roleExpirationDate(
      bytes32 _role,
      address _tokenAddress,
      uint256 _tokenId,
      address _grantor,
      address _grantee
    ) external view returns (uint64 expirationDate_);

    /// @notice Checks if the grantor approved the operator for all NFTs.
    /// @param _tokenAddress The token address.
    /// @param _grantor The user that approved the operator.
    /// @param _operator The user that can grant and revoke roles.
    function isRoleApprovedForAll(
      address _tokenAddress,
      address _grantor,
      address _operator
    ) external view returns (bool);

    /// @notice Checks if the grantor approved the operator for a specific NFT.
    /// @param _tokenAddress The token address.
    /// @param _tokenId The token identifier.
    /// @param _grantor The user that approved the operator.
    /// @param _operator The user approved to grant and revoke roles.
    function getApprovedRole(
        address _tokenAddress,
        uint256 _tokenId,
        address _grantor,
        address _operator
    ) external view returns (bool);

}

メタデータ拡張

NFT(非代替トークン)の従来のJSONベースのメタデータスキーマを拡張します。
そのため、この機能をサポートするDApps(分散型アプリケーション)は、必ずERC721またはERC1155のメタデータ拡張を実装する必要があります。
この拡張機能はオプションであり、開発者がロールに関する追加情報を提供できるようにします。

  1. Roles Metadata拡張
    NFTに関連付けられたロールに関する追加情報を提供するための機能です。
    例えば、特定のNFTが「PROPERTY_MANAGER」の役割を持っている場合、その「PROPERTY_MANAGER」の詳細情報を提供することができます。

  2. JSONベースのメタデータスキーマ
    通常、NFTにはJSON形式のメタデータが含まれており、それにはトークンの名前、説明、画像URLなどが含まれています。
    Roles Metadata拡張は、この既存のメタデータスキーマを拡張して、ロールに関する情報を追加できるようにします。

  3. DAppsのサポート
    Roles Metadata拡張をサポートするDAppsは、NFTのメタデータにロール情報を正しく表示し、操作できる必要があります。
    ただし、この機能を実装する際には、ERC721またはERC1155のメタデータ拡張も同時に実装しなければなりません。

アップデートされたメタデータスキーマ。

{
  
  /** Existing NFT Metadata **/

  "title": "Asset Metadata",
  "type": "object",
  "properties": {
    "name": {
      "type": "string",
      "description": "Identifies the asset to which this NFT represents"
    },
    "description": {
      "type": "string",
      "description": "Describes the asset to which this NFT represents"
    },
    "image": {
      "type": "string",
      "description": "A URI pointing to a resource with mime type image/* representing the asset to which this NFT represents. Consider making any images at a width between 320 and 1080 pixels and aspect ratio between 1.91:1 and 4:5 inclusive"
    }
  },
  
  /** Additional fields for Roles **/

  "roles": [
    {
      "id": {
        "type": "bytes32",
        "description": "Identifies the role"
      },
      "name": {
        "type": "string",
        "description": "Human-readable name of the role"
      },
      "description": {
        "type": "string",
        "description": "Describes the role"
      },
      "isUniqueRole": {
        "type": "boolean",
        "description": "Whether the role supports simultaneous assignments or not"
      },
      "inputs": [
        {
          "name": {
            "type": "string",
            "description": "Human-readable name of the argument"
          },
          "type": {
            "type": "string",
            "description": "Solidity type, e.g., uint256 or address"
          }
        }
      ]
    }
  ]
  
}

以下のJSONはERC7432メタデータの例です。

{
  // ... Existing NFT Metadata
  
  "roles": [
    {
      // keccak256("PROPERTY_MANAGER")
      "id": "0x5cefc88e2d50f91b66109b6bb76803f11168ca3d1cee10cbafe864e4749970c7",
      "name": "Property Manager",
      "description": "The manager of the property is responsible for furnishing it and ensuring its good condition.",
      "isUniqueRole": false,
      "inputs": []
    },
    {
      // keccak256("PROPERTY_TENANT")
      "id": "0x06a3b33b0a800805559ee9c64f55afd8a43a05f8472feb6f6b77484ff5ac9c26",
      "name": "Property Tenant",
      "description": "The tenant of the property is responsible for paying the rent and keeping the property in good condition.",
      "isUniqueRole": true,
      "inputs": [
        {
          "name": "rent",
          "type": "uint256"
        }
      ]
    }
  ]
  
}
  1. ロールの配列プロパティ
    これらのプロパティは、NFTの役割に関する情報を含むものです。
    開発者は必要に応じて、ロールについての追加情報(たとえば、ロールの画像や詳細な説明)を追加できます。
    しかし、「isUniqueRole」というプロパティを含めることが非常に重要です。
    この「isUniqueRole」フィールドは、あるロールが一意であるかどうかを示し、それに応じて「hasRole」または「hasUniqueRole」という関数を呼び出すかどうかを判断するのに役立ちます。

  2. inputsプロパティの重要性
    このプロパティは、特定の操作(たとえば、ロールの付与)に必要な情報を記述する場所です。
    具体的には、どのパラメーターをエンコードし、grantRole関数に渡すかを示します。
    このとき、「inputs」プロパティには、パラメーターの型を示す「type」と、複雑なデータ構造(たとえば、タプル型)の場合に使用される「components」が含まれます。
    これにより、操作が正確に実行されるための情報が提供されます。

注意事項

  1. IERC7432インターフェースの実装
    この規格に準拠したコントラクトは、IERC7432インターフェースを実装する必要があります。
    これにより、ロール管理の標準化が促進されます。

  2. ロールの表現
    ロールはbytes32型で表されます。
    通常、ロール名はkeccak256ハッシュ関数を使用してハッシュ化され、このハッシュがロールを表します。
    例えば、ROLE_NAMEロールのハッシュはkeccak256("ROLE_NAME")です。

  3. grantRole関数
    ロールを付与する関数で、_expirationDate(有効期限)が過去の場合、エラーを発生させる必要があります。

  4. grantRoleFrom関数
    _expirationDateが過去の場合、またはmsg.sender_grantorの代わりにロールを付与する権限を持っていない場合、エラーを発生させる必要があります。

  5. revokeRole関数
    ロールを取り消す関数です。

  6. revokeRoleFrom関数
    msg.sender_revokerの代わりにロールを取り消す権限を持っていない場合、エラーを発生させる必要があります。

  7. setRoleApprovalForAll関数
    ロールの付与権限を設定する関数です。

  8. approveRole関数
    ロールの承認権限を設定する関数です。

  9. hasRole関数
    ロールの割り当てが存在し、有効期限が切れていないかどうかを確認する関数です。

  10. hasUniqueRole関数
    ロールの割り当てが存在し、有効期限が切れておらず、最後に付与されたロールであるかどうかを確認する関数で、pureまたはviewで実装さ、同時にロールの割り当てがサポートされません。

  11. roleData関数
    ロールの割り当てが存在しない場合、空のバイト配列を返します。

  12. roleExpirationDate関数
    ロールの割り当てが存在しない場合、0ゼロを返します。

  13. isRoleApprovedForAll関数
    指定した_operator_grantorの代わりにすべてのNFTに対してロールを付与および取り消す権限を持っている場合、trueを返します。

  14. getApprovedRole関数
    指定した_operator_grantorの指定したNFTに対してロールを付与および取り消す権限を持っている場合、trueを返します。

  15. ERC165のサポート
    この規格に準拠したコントラクトはERC165をサポートします。

補足

ERC7432ERC721ERC1155の拡張ではありません。
ERC7432は、特定のNFT実装に依存せず、どのNFTプラットフォームでも使えるように設計されています。
これにより、標準を外部で実装するか、NFTのコントラクト内で実装し、dAppsが不変のNFTとロールを組み合わせて使えます。

自動有効期限

自動有効期限は、ロールの付与とロールの有効性のチェックに関わります。
ロールの付与において、有効期限を設定するのがgrantRole関数の役割で、ロールの有効性を確認するのがhasRole関数の役割です。
日付はuint256ではなく、uint64で表されます。
最大のUNIXタイムスタンプは約584,942,417,355年で、これは「永久」と考えられるため、期限切れを設定しないケースにはtype(uint64).maxを使用することが推奨されています。

ユニークとユニークでないロール

この標準は、ユニークなロール(一度に1つのアカウントに割り当てられる)とノンユニークなロール(複数のアカウントに同時に付与可能)の両方をサポートしています。
ロールがユニークかノンユニークかはメタデータで指定できます。
コントラクトがメタデータを実装していない場合、すべてのロールはノンユニークとみなされます。

カスタムデータ

dAppsは、ロールの割り当て時にロール固有の情報をエンコードするためにgrantRole関数の_dataパラメーターを使用できます。
このカスタムデータはroleData関数を介して取得でき、RoleGrantedイベントと共に送信されます。
開発者はこれをオンチェーンとオフチェーンのアプリケーションに統合できます。

ロール承認

ERC7432は、ユーザーが他のアカウントにロールの付与と取り消しを承認する機能を提供します。
ユーザーは単一のNFTまたはコレクション内のすべてのNFTを管理できるアカウントを認可できます。
これにより、所有権を持たないコントラクトがERC7432を操作できるようになります。

後方互換性

ERC7432は、トークンのアドレス(tokenAddress)とトークンのID(tokenId)をすべての関数とイベントで提供することを要求します。
これにより、NFTのロールに関する情報を一元的に管理できる独立したERC7432コントラクトを使用できます。
これは、他のNFT関連の関数(例:ownerOfbalanceOf)が不要であることを意味し、さまざまなNFT実装との統合がスムーズに行えるようになります。

参考実装

以下のGithubに格納しています。


roleAssignments

mapping(address => mapping(address => mapping(address => mapping(uint256 => mapping(bytes32 => RoleData))))) public roleAssignments;

概要

ロールの割り当て情報を格納するマッピング配列。
各キーに対応するロールの情報が保持されます。

詳細

  • grantor
    • ロールを付与するアカウントのアドレス。
  • grantee
    • ロールを受け取るアカウントのアドレス。
  • tokenAddress
    • トークンのアドレス。
  • tokenId
    • トークンのID。
  • role
    • ロールを表すハッシュ。
  • RoleData
    • ロールの有効期限とカスタムデータを格納する構造体。

latestGrantees

mapping(address => mapping(address => mapping(uint256 => mapping(bytes32 => address)))) public latestGrantees;

概要

最新の受益者(grantee)を追跡するマッピング配列。
各トークンとロールに対して最新の受益者が保持されます。

詳細

  • grantor
    • ロールを付与するアカウントのアドレス。
  • tokenAddress
    • トークンのアドレス。
  • tokenId
    • トークンのID。
  • role
    • ロールを表すハッシュ。
  • grantee
    • 最新の受益者(grantee)のアドレス。

tokenIdApprovals

mapping(address => mapping(address => mapping(uint256 => mapping(address => bool)))) public tokenIdApprovals;

概要

トークンIDごとのオペレーターの承認情報を追跡するマッピング配列。

詳細

  • grantor
    • ロールを付与するアカウントのアドレス。
  • operator
    • オペレーターのアドレス。
  • tokenAddress
    • トークンのアドレス。
  • isApproved
    • オペレーターが承認されているかどうかの状態。

tokenApprovals

mapping(address => mapping(address => mapping(address => bool))) public tokenApprovals;

概要

トークンごとのオペレーターの承認情報を追跡するマッピング配列。

詳細

  • grantor
    • ロールを付与するアカウントのアドレス。
  • operator
    • オペレーターのアドレス。
  • tokenAddress
    • トークンのアドレス。
  • isApproved
    • オペレーターが承認されているかどうかの状態。

validExpirationDate

modifier validExpirationDate(uint64 _expirationDate) {
    require(_expirationDate > block.timestamp, "ERC7432: expiration date must be in the future");
    _;
}

概要
有効期限の日付が未来であることを確認する修飾子。

詳細

  • _expirationDate
    • 確認される有効期限の日付。

onlyApproved

modifier onlyApproved(address _tokenAddress, uint256 _tokenId, address _grantor) {
    require(
        isRoleApprovedForAll(_tokenAddress, _grantor, msg.sender) ||
            getApprovedRole(_tokenAddress, _tokenId, _grantor, msg.sender),
        "ERC7432: sender must be approved"
    );
    _;
}

概要

指定された条件を満たす場合にのみ関数を実行できる修飾子。
送信者が承認されているかどうかを確認します。

詳細

  • _tokenAddress
    • トークンのアドレス。
  • _tokenId
    • トークンのID。
  • _grantor
    • ロールを付与するアカウントのアドレス。

grantRole

function grantRole(
    bytes32 _role,
    address _tokenAddress,
    uint256 _tokenId,
    address _grantee,
    uint64 _expirationDate,
    bytes calldata _data
) external {
    _grantRole(_role, _tokenAddress, _tokenId, msg.sender, _grantee, _expirationDate, _data);
}

概要
指定したロール(_role)を特定のトークン(_tokenAddress_tokenId)の受託者(_grantee)に付与する関数。

詳細
権限の有効期限(_expirationDate)およびデータ(_data)も指定できます。

引数

  • _role
    • 付与するロールの識別子。
  • _tokenAddress
    • トークンのアドレス。
  • _tokenId
    • トークンの識別子。
  • _grantee
    • ロールを受け取るアドレス。
  • _expirationDate
    • ロールの有効期限(Unixタイムスタンプ形式)。
  • _data
    • 任意のデータ。

grantRoleFrom

function grantRoleFrom(
    bytes32 _role,
    address _tokenAddress,
    uint256 _tokenId,
    address _grantor,
    address _grantee,
    uint64 _expirationDate,
    bytes calldata _data
) external override onlyApproved(_tokenAddress, _tokenId, _grantor) {
    _grantRole(_role, _tokenAddress, _tokenId, _grantor, _grantee, _expirationDate, _data);
}

概要
特定のトークン(_tokenAddress_tokenId)の所有者(_grantor)が指定したロール(_role)を受託者(_grantee)に付与する関数。

詳細
所有者の承認が必要です。

引数

  • _role
    • 付与するロールの識別子。
  • _tokenAddress
    • トークンのアドレス。
  • _tokenId
    • トークンの識別子。
  • _grantor
    • ロールを付与する所有者のアドレス。
  • _grantee
    • ロールを受け取るアドレス。
  • _expirationDate
    • ロールの有効期限(Unixタイムスタンプ形式)。
  • _data
    • 任意のデータ。

_grantRole

function _grantRole(
    bytes32 _role,
    address _tokenAddress,
    uint256 _tokenId,
    address _grantor,
    address _grantee,
    uint64 _expirationDate,
    bytes calldata _data
) internal validExpirationDate(_expirationDate) {
    roleAssignments[_grantor][_grantee][_tokenAddress][_tokenId][_role] = RoleData(_expirationDate, _data);
    latestGrantees[_grantor][_tokenAddress][_tokenId][_role] = _grantee;
    emit RoleGranted( _role, _tokenAddress, _tokenId, _grantor, _grantee, _expirationDate, _data);
}

概要
ロールの付与と内部処理を行う関数。

引数

  • _role
    • 付与するロールの識別子。
  • _tokenAddress
    • トークンのアドレス。
  • _tokenId
    • トークンの識別子。
  • _grantor
    • ロールを付与する所有者のアドレス。
  • _grantee
    • ロールを受け取るアドレス。
  • _expirationDate
    • ロールの有効期限(Unixタイムスタンプ形式)。
  • _data
    • 任意のデータ。

revokeRole

function revokeRole(bytes32 _role, address _tokenAddress, uint256 _tokenId, address _grantee) external {
    _revokeRole(_role, _tokenAddress, _tokenId, msg.sender, _grantee);
}

概要
指定したロール(_role)を特定のトークン(_tokenAddress_tokenId)の受託者(_grantee)から取り消す関数。

詳細

  • _role
    • 取り消すロールの識別子。
  • _tokenAddress
    • トークンのアドレス。
  • _tokenId
    • トークンの識別子。
  • _grantee
    • ロールを持っている受託者のアドレス。

revokeRoleFrom

function revokeRoleFrom(
    bytes32 _role,
    address _tokenAddress,
    uint256 _tokenId,
    address _revoker,
    address _grantee
) external override onlyApproved(_tokenAddress, _tokenId, _revoker) {
    _revokeRole(_role, _tokenAddress, _tokenId, _revoker, _grantee);
}

概要
特定のトークン(_tokenAddress_tokenId)の所有者(_revoker)が指定したロール(_role)を受託者(_grantee)から取り消す関数。

詳細
所有者の承認が必要です。

引数

  • _role
    • 取り消すロールの識別子。
  • _tokenAddress
    • トークンのアドレス。
  • _tokenId
    • トークンの識別子。
  • _revoker
    • ロールを取り消す所有者のアドレス。
  • _grantee
    • ロールを持っている受託者のアドレス。

_revokeRole

function _revokeRole(
   

 bytes32 _role,
    address _tokenAddress,
    uint256 _tokenId,
    address _revoker,
    address _grantee
) internal {
    delete roleAssignments[_revoker][_grantee][_tokenAddress][_tokenId][_role];
    delete latestGrantees[_revoker][_tokenAddress][_tokenId][_role];
    emit RoleRevoked(_role, _tokenAddress, _tokenId, _revoker, _grantee);
}

概要
ロールの実際の取り消しと内部処理を行う関数。

詳細

  • _role
    • 取り消すロールの識別子。
  • _tokenAddress
    • トークンのアドレス。
  • _tokenId
    • トークンの識別子。
  • _revoker
    • ロールを取り消す所有者のアドレス。
  • _grantee
    • ロールを持っている受託者のアドレス。

hasRole

function hasRole(
    bytes32 _role,
    address _tokenAddress,
    uint256 _tokenId,
    address _grantor,
    address _grantee
) external view returns (bool) {
    return roleAssignments[_grantor][_grantee][_tokenAddress][_tokenId][_role].expirationDate > block.timestamp;
}

概要
指定したトークン(_tokenAddress_tokenId)の所有者(_grantor)が特定の受託者(_grantee)に対して役割(_role)を持っているか確認する関数。

詳細

  • _role
    • 確認するロールの識別子。
  • _tokenAddress
    • トークンのアドレス。
  • _tokenId
    • トークンの識別子。
  • _grantor
    • ロールを持つ所有者のアドレス。
  • _grantee
    • ロールを持っているか確認する受託者のアドレス。

戻り値

  • true
    • 受託者がロールを持っており、有効期限内であることを示すbool値。
  • false
    • 受託者が役割を持っていないか、有効期限が切れていることを示すbool値。

hasUniqueRole

function hasUniqueRole(
    bytes32 _role,
    address _tokenAddress,
    uint256 _tokenId,
    address _grantor,
    address _grantee
) external view returns (bool) {
    return latestGrantees[_grantor][_tokenAddress][_tokenId][_role] == _grantee && roleAssignments[_grantor][_grantee][_tokenAddress][_tokenId][_role].expirationDate > block.timestamp;
}

概要
指定したトークン(_tokenAddress_tokenId)の所有者(_grantor)が特定の受託者(_grantee)に対してロール(_role)を持っていて、そのロールがユニークか確認する関数。

詳細

  • _role
    • 確認するロールの識別子。
  • _tokenAddress
    • トークンのアドレス。
  • _tokenId
    • トークンの識別子。
  • _grantor
    • ロールを持つ所有者のアドレス。
  • _grantee
    • ロールを持っているか確認する受託者のアドレス。

引数
なし。

戻り値

  • true
    • 受託者が唯一のロールを持っており、有効期限内であることを示すbool値。
  • false
    • 受託者が唯一の役割を持っていないか、有効期限が切れていることを示すbool値。

roleData

function roleData(
    bytes32 _role,
    address _tokenAddress,
    uint256 _tokenId,
    address _grantor,
    address _grantee
) external view returns (bytes memory data_) {
    RoleData memory _roleData = roleAssignments[_grantor][_grantee][_tokenAddress][_tokenId][_role];
    return (_roleData.data);
}

概要
指定したトークン(_tokenAddress_tokenId)の所有者(_grantor)が特定の受託者(_grantee)に対してロール(_role)に関連付けられたデータを取得する関数。

詳細

  • _role
    • データを取得するロールの識別子。
  • _tokenAddress
    • トークンのアドレス。
  • _tokenId
    • トークンの識別子。
  • _grantor
    • ロールを持つ所有者のアドレス。
  • _grantee
    • データを取得する受託者のアドレス。

戻り値

  • data_
    • ロールに関連付けられたデータ。

roleExpirationDate

function roleExpirationDate(
    bytes32 _role,
    address _tokenAddress,
    uint256 _tokenId,
    address _grantor,
    address _grantee
) external view returns (uint64 expirationDate_){
    RoleData memory _roleData = roleAssignments[_grantor][_grantee][_tokenAddress][_tokenId][_role];
    return (_roleData.expirationDate);
}

概要
指定したトークン(_tokenAddress_tokenId)の所有者(_grantor)が特定の受託者(_grantee)に対してロール(_role)の有効期限を取得する関数。

詳細

  • _role
    • 有効期限を取得するロールの識別子。
  • _tokenAddress
    • トークンのアドレス。
  • _tokenId
    • トークンの識別子。
  • _grantor
    • ロールを持つ所有者のアドレス。
  • _grantee
    • 有効期限を取得する受託者のアドレス。

戻り値

  • expirationDate_
    • ロールの有効期限(Unixタイムスタンプ形式)。

supportsInterface

function supportsInterface(bytes4 interfaceId) external view virtual override returns (bool) {
    return interfaceId == type(IERC7432).interfaceId;
}

概要
指定したインターフェースがサポートされているかどうかを確認する関数。
特定のインターフェース(IERC7432)のサポートを確認するために使用されます。

詳細
特定のインターフェース(IERC7432)のサポートを確認するために使用されます。

引数

  • interfaceId
    • 確認するインターフェースの識別子。

戻り値

  • true
    • 指定したインターフェースがサポートされています。
  • false
    • 指定したインターフェースがサポートされていません。

setRoleApprovalForAll

function setRoleApprovalForAll(
    address _tokenAddress,
    address _operator,
    bool _isApproved
) external override {
    tokenApprovals[msg.sender][_tokenAddress][_operator] = _isApproved;
    emit RoleApprovalForAll(_tokenAddress, _operator, _isApproved);
}

概要
所有者が指定したトークン(_tokenAddress)の特定のオペレーター(_operator)に対するロール承認を設定または解除する関数。

引数

  • _tokenAddress
    • ロール承認を設定または解除するトークンのアドレス。
  • _operator
    • ロール承認を設定または解除するオペレーターのアドレス。
  • _isApproved
    • ロール承認を設定する場合はtrue、解除する場合はfalse

approveRole

function approveRole(
    address _tokenAddress,
    uint256 _tokenId,
    address _operator,
    bool _approved
) external override {
    tokenIdApprovals[msg.sender][_tokenAddress][_tokenId][_operator] = _approved;
    emit RoleApproval(_tokenAddress, _tokenId, _operator, _approved);
}

概要
所有者が指定したトークン(_tokenAddress_tokenId)に対して特定のオペレーター(_operator)に対するロール承認を設定または解除する関数。

引数

  • _tokenAddress
    • ロール承認を設定または解除するトークンのアドレス。
  • _tokenId
    • ロール承認を設定または解除するトークンの識別子。
  • _operator
    • ロール承認を設定または解除するオペレーターのアドレス。
  • _approved
    • ロール承認を設定する場合はtrue、解除する場合はfalse

isRoleApprovedForAll

function isRoleApprovedForAll(
    address _tokenAddress,
    address _grantor,
    address _operator
) public view override returns (bool) {
    return tokenApprovals[_grantor][_tokenAddress][_operator];
}

概要
所有者が指定したトークン(_tokenAddress)の特定のオペレーター(_operator)に対するロール承認が設定されているか確認する関数。

引数

  • _tokenAddress
    • ロール承認を確認するトークンのアドレス。
  • _grantor
    • ロール承認を設定した所有者のアドレス。
  • _operator
    • ロール承認を確認するオペレーターのアドレス。

戻り値

  • true
    • ロール承認が設定されています。
  • false
    • ロール承認が設定されていません。

getApprovedRole

function getApprovedRole(
    address _tokenAddress,
    uint256 _tokenId,
    address _grantor,
    address _operator
) public view override returns (bool) {
    return tokenIdApprovals[_grantor][_tokenAddress][_tokenId][_operator];
}

概要
所有者が指定したトークン(_tokenAddress_tokenId)に対して特定のオペレーター(_operator)に対するロール承認が設定されているか確認する関数。

引数

  • _tokenAddress
    • ロール承認を確認するトークンのアドレス。
  • _tokenId
    • ロール承認を確認するトークンの識別子。
  • _grantor
    • ロール承認を設定した所有者のアドレス。
  • _operator
    • ロール承認を確認するオペレーターのアドレス。

戻り値

  • true
    • ロール承認が設定されています。
  • false
    • ロール承認が設定されていません。

セキュリティ考慮事項

NFTロールインターフェースを統合する開発者にとっての重要事項は以下になります。

  • 適切なアクセス制御の確保
    • 不正なロールの割り当てや取り消しを防ぐために、適切なアクセス制御メカニズムを実装しましょう。
    • これにより、権限のない操作を防ぎ、セキュリティを向上させます。
  • セキュリティ対策の検討
    • スマートコントラクトの実装中に潜在的な攻撃(例:再入攻撃)を考慮し、適切なセキュリティ対策を実施しましょう。
    • セキュリティの確保は非常に重要です。
  • NFTの所有権の確認
    • ERC7432はNFTの所有権を自動的に確認しないため、dAppはNFTの所有者を明示的にクエリし、正確な所有者(_grantor)をhasRole関数に渡す責任があります。
    • これにより、ロールの割り当てが正確であることを保証できます。
  • ユニークまたはノンユニークなロールの確認
    • ロールがユニーク(一度に1つのアカウントにしか割り当てられない)かノンユニーク(複数のアカウントに同時に割り当てられる)かを確認する責任はdAppにあります。
    • ユニークなロールの場合、他のアカウントに割り当てられていないことを確認するために、hasUniqueRole関数を使用する必要があります。

引用

Ernani São Thiago (@ernanirst), Daniel Lima (@karacurt), "ERC-7432: Non-Fungible Token Roles [DRAFT]," Ethereum Improvement Proposals, no. 7432, July 2023. [Online serial]. Available: https://eips.ethereum.org/EIPS/eip-7432.

最後に

今回は「NFTのさまざまなロールを管理するインターフェースを提案しているERC7432」についてまとめてきました!
いかがだったでしょうか?

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

Twitter @cardene777

他の媒体でも情報発信しているのでぜひ他も見ていってください!

7
10
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
10

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?