# [ERC7996] コントラクトの追加機能を見分けるFeatureの仕組みを理解しよう！

> ERC7996は、スマートコントラクトが実装している機能を標準的な方法で公開し、それを検出できるようにするための仕組みを定めています。

- URL: https://cardene.dev/articles/c1cb447f14ce0fb34077
- 公開日: 2025-08-26
- 更新日: 2025-08-26
- トピック: Blockchain
- タグ: ethereum, solidity, smartcontract, ブロックチェーン

## はじめに

『DApps開発入門』という本や色々記事を書いているかるでねです。

https://amzn.asia/d/gxvJ0Pw

今回は、**ERC165**では表現できないスマートコントラクトの追加機能を「**Feature**」として標準化し、名前と識別子で一貫して公開・検出できる仕組みを提案している**ERC7996**についてまとめていきます！

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

https://github.com/adraffy/ethereum-ercs/blob/contract-features/ERCS/erc-7996.md

他にも様々なEIP・BIP・SLIP・CAIP・ENSIPについてまとめています。

https://cardene.notion.site/ERC-EIP-2a03fa3ea33d43baa9ed82288f98d4a9?pvs=4

## 概要

**ERC7996**は、スマートコントラクトが実装している機能を標準的な方法で公開し、それを検出できるようにするための仕組みを定めています。
特に、**ERC165**のインターフェースとして表現できない機能について、それらを「**特徴（Feature）**」として扱うことで、統一的に表現・識別できるようにしています。

:::message
**ERC165**については以下の記事を参考にしてください。
:::

[\[ERC165\] コントラクトが特定のインターフェースをサポートしているか確認する仕組みを理解しよう！](/articles/541184977a5cba51b759)

## 動機

Ethereum Name Service（ENS）は2016年に作られた古いコントラクトとの互換性を維持するため、長年にわたり**ERC165**を活用してきました。
しかし、コントラクトが持つあらゆる機能を一意のインターフェースとして表現することは不可能です。
つまり、インターフェースだけでは網羅できない機能が存在していました。

そこで「**Feature（特徴）**」という概念を導入することで、既存のインターフェースを壊さずにコントラクトが持つ機能を表現できるようにしています。
**ERC7996**では、その「**Feature**」を標準化し、さらに機能の識別方法（名前付けのルール）を標準化することで、異なるコントラクト間でも一貫した互換性を保てるようにすることを目的としています。

## 仕様

**ERC7996**では、スマートコントラクトが持つ「**Feature（特徴）**」を標準的に識別・公開する仕組みが定められています。
ここでいう「**Feature**」とは、**ERC165**のインターフェースでは表現できない機能や性質のことを指します。

### Featureの識別方法

Featureは一意に識別できる名前を持ちます。
その名前は「**リバースドメイン形式（reverse domain name）**」を使って表されます。
例えば、ENSリゾルバの拡張機能としてのマルチコールは次のように命名されます。

```
eth.ens.resolver.extended.multicall
```

この名前を基に、`keccak256` というハッシュ関数を使って得られる先頭4バイトが「**Feature Identifier（特徴識別子）**」になります。
具体例は以下です。

```
bytes4(keccak256("eth.ens.resolver.extended.multicall")) = 0x96b62db8
```

つまり、名前によって機能を表し、それをハッシュ化して短い識別子に変換するルールです。

### コントラクトが実装するFeatureの公開方法

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

```solidity
interface IERC7996 {
    /// @notice 特定のFeatureがサポートされているかを確認する。
    /// @param featureId Featureの識別子（bytes4形式）
    /// @return `true` の場合、そのFeatureはコントラクトでサポートされている。
    function supportsFeature(bytes4 featureId) external view returns (bool);
}
```

このインターフェース自体は**ERC165**に対応しており、そのインターフェース識別子は `0x582de3e7` です。

### コントラクトがFeatureを実装しているか確認する方法

まず**ERC165**に従って、そのコントラクトが `IERC7996` インターフェースをサポートしているかを確認します。
もしサポートしていれば、そのコントラクトはFeatureを扱える可能性があります。

### 特定のFeatureを実装しているか確認する方法

対象コントラクトがFeatureを扱うことを確認したら、次に `supportsFeature(featureId)` を呼び出します。その戻り値が `true` であれば、そのFeatureを実装していることが分かります。

ただし注意点として、Featureを扱うコントラクトであっても、実際には一つもFeatureを実装していない可能性もあります。
そのため、必ず `supportsFeature` を使って確認する必要があります。

## 補足

**ERC7996**では、新しい標準を定義することで、既存の**ERC165**に「**無理やり作られた擬似的なインターフェース（synthetic interfaces）**」を追加する必要がなくなります。
つまり、コントラクトの機能を表現するために不要にインターフェース識別子の領域を消費することを避けられる、という考え方です。
これにより、**ERC165**の識別子空間を保護しつつ、機能表現の柔軟性を確保できます。

## 互換性

この仕組みを知らないコントラクトやアプリケーションであっても、従来の動作に影響はありません。
新しい「**Feature**」標準を理解していない利用者やシステムに対しても、従来通りの挙動を維持できるように設計されています。
また、ENS（Ethereum Name Service）はすでにこの仕組みを実装済みであり、実際に運用の中で使われています。

## セキュリティ

**ERC165**と同様に、「**Featureに対応している**」と宣言しているからといって、そのコントラクトが実際にその機能を正しく実装しているとは限りません。
つまり、コントラクトは虚偽の宣言をすることができるため、利用者側で追加の検証や注意が必要です。

そのため、Featureを利用するアプリケーションやサービスは、単に宣言を信じるのではなく、実際の動作を確認するなど、必要に応じた安全対策を講じる必要があります。

## 最後に

今回は「**ERC165**では表現できないスマートコントラクトの追加機能を「**Feature**」として標準化し、名前と識別子で一貫して公開・検出できる仕組みを提案している**ERC7996**」についてまとめてきました！
いかがだったでしょうか？

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

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

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

https://chaldene.net/

https://zenn.dev/heku

https://cardene.substack.com/

https://mirror.xyz/0xcE77b9fCd390847627c84359fC1Bc02fC78f0e58

https://cardene.notion.site/ERC-EIP-2a03fa3ea33d43baa9ed82288f98d4a9?pvs=4
