メインコンテンツへスキップ
mip.watch
⌘K

MRC-13

Validator Metadata Registry

最終確認 標準トラック MRC GitHub ↗ フォーラム ↗
アイデア ドラフト レビュー中 最終確認 確定 継続中

An on-chain registry standard for human-readable Monad validator metadata

作成者
Dorde Mijovic <[email protected]> (@mijovic), Jackson Lewis
作成日
2026-06-15
更新日
2026/07/30
フォーラム
22p · 13♥

ステークホルダー影響

このMIPが各対象者にとって何を変えるのかを示します。重大度とアクションフラグはモデルによって導出され、MIPのタイプ/カテゴリごとに決定論的な下限値が適用されます。

要約

このMRCは、Monadのステーキングプリコンパイルを拡張し、バリデーターの人間可読メタデータを提供するオンチェーンレジストリ契約を定義します。これにより、バリデーターの識別が容易になり、エコシステム全体での一貫性が向上します。

何が変わるか

  • オンチェーンレジストリ契約の導入 - バリデーターのメタデータを管理する新しい標準。
  • 人間可読なメタデータの追加 - 名前、ウェブサイト、説明、ロゴURLなどを含む。
  • バリデーター自身がメタデータを管理 - 権限を持つバリデーターが直接メタデータを更新可能。
  • フィールドごとの更新機能 - メタデータの特定のフィールドのみを更新できる。
  • エコシステムの一貫性向上 - 各インテグレーターが独自にメタデータを管理する必要がなくなる。

開発者

スマートコントラクトおよびdapp開発者、RPC利用者、ツール作成者

このMRCは新しいコントラクトインターフェースを導入し、ABIの変更を伴います。これにより、既存のコントラクトは再コンパイルまたは再デプロイが必要になる可能性があります。

対応が必要

ユーザー

ウォレットユーザー、EOA保有者、dapp訪問者

この変更により、バリデーターのメタデータが人間に読みやすい形式でオンチェーンに登録されるようになります。これにより、ウォレットやダッシュボードでのバリデーターの識別が容易になりますが、ユーザーが特に行動を起こす必要はありません。

バリデーター

ノード運用者、RPC運用者、委任者

このMRCは、バリデーターのメタデータをオンチェーンで管理する新しい標準を導入しますが、バリデーターの収益や運用に直接的な影響はありません。したがって、収益性や運用コストには影響を与えません。

財団

Monad財団およびCategory Labsのコア開発者

このMRCは、バリデーターのメタデータを管理するための新しいオンチェーンレジストリ標準を定義しています。これにより、エコシステム全体での一貫性が向上し、バリデーターの識別が容易になります。

対応が必要

2026/08/07 17:05に生成 · モデル: gpt-4o-mini

仕様

機械翻訳
引用

読みやすさのためのAI翻訳であり、不正確または古い場合があります。ガバナンス・投票・紛争においては英語原文のみが唯一の正式な本文です。正確な文言はGitHubの原本を参照してください。

GitHubの英語原本 ↗
## 概要

このMRCは、Monadステーキングのプリコンパイル(`0x0000000000000000000000000000000000001000`)を人間が読みやすいバリデータメタデータで拡張するオンチェーンレジストリコントラクトを指定します:名前、ウェブサイト、説明、ロゴURL、JSONの`socials`フィールド、および将来の互換性のある拡張のためのJSONの`additionalInfo`フィールド。最低限、バリデータ自身の権限アドレス — ステーキングプリコンパイルによって報告されたもの — は、そのバリデータのメタデータを書き込むことができなければなりません。実装は、自身の認可モデルの下で追加の呼び出し元に書き込みアクセスを付与することが自由です。レジストリは、フルレコードの書き込みとフィールドごとの更新、さらに保存されたレコードの読み取りメソッドの両方を公開します。

## 動機

Monadステーキングプリコンパイルは、コンセンサス層におけるバリデータのアイデンティティの真実の源ですが、意図的にコンセンサスと報酬会計に必要なデータ(権限アドレス、フラグ、ステーク、手数料、公開鍵など)だけを公開します。バリデータの人間が読みやすいアイデンティティは提供されません。

ウォレット、ブロックエクスプローラー、ステーキングダッシュボード、ガバナンスUI、および委任ツールは、数値の`validatorId`ではなく、認識可能な名前とロゴでバリデータを表示する必要があります。現在、各インテグレーターはこれを独自に解決しています — 通常はオフチェーンの`metadata.json`ファイルや中央集権的にキュレーションされたリストを維持することによって — これによりエコシステム全体で不一致な命名、壊れたまたは古いリンク、そして一人のキュレーターがバリデータをユーザーにどのようにラベル付けするかを制限する中央集権リスクが生じます。

許可のない、バリデータが制御するオンチェーンレジストリは、キュレーションのボトルネックを排除します:すでにステーキングパラメータを制御している同じ権限キーが、バリデータのメタデータを公開することが許可されており、任意のインテグレーターはこの標準に準拠したレジストリコントラクトから直接それを読み取ることができます。

## 仕様

この文書におけるキーワード「MUST」、「MUST NOT」、「REQUIRED」、「SHALL」、「SHALL NOT」、「SHOULD」、「SHOULD NOT」、「RECOMMENDED」、「NOT RECOMMENDED」、「MAY」、および「OPTIONAL」は、[RFC 2119](https://www.ietf.org/rfc/rfc2119.html)および[RFC 8174](https://www.ietf.org/rfc/rfc8174.html)に記載されている通りに解釈されるものとします。

### 概要

準拠した実装は、以下に定義された`IValidatorMetadata`インターフェースに準拠した単一のコントラクトをデプロイする必要があります。コントラクトは、任意の`validatorId`の現在の権限アドレスを決定するために、`0x0000000000000000000000000000000000001000`のMonadステーキングプリコンパイルをクエリし、呼び出し時にその権限アドレスからの書き込み呼び出しを受け入れる必要があります。実装は、独自の認可ルールの下で他の呼び出し元からの書き込みを追加で受け入れることができます。詳細は[Authorization](#authorization)を参照してください。

### インターフェース

```solidity
interface IValidatorMetadata {
    /// バリデーターのメタデータへの成功した書き込みごとに発火します。
    event MetadataUpdated(uint64 indexed validatorId, address indexed authority, Metadata metadata);

    /// バリデーターのメタデータレコード。書き込みルールおよび`socials`と`additionalInfo`フィールドのJSON
    /// 規約についてはField Semanticsを参照してください。
    struct Metadata {
        string name;
        string website;
        string description;
        string logo;
        string socials;
        string additionalInfo;
    }

    /// `updateMetadataField`のフィールドセレクタ。
    enum Field {
        NAME,
        WEBSITE,
        DESCRIPTION,
        LOGO,
        SOCIALS,
        ADDITIONAL_INFO
    }

    /// 権限解決に使用されるMonadステーキングプリコンパイルのアドレス。
    /// 実装は`0x0000000000000000000000000000000000001000`を返さなければなりません。
    function STAKING_PRECOMPILE() external view returns (address);

    /// バリデーターの完全なメタデータレコードを設定または置き換えます。認可された呼び出し元
    /// およびリバート条件はAuthorizationおよびField Semanticsで定義されています。
    function setMetadata(uint64 validatorId, Metadata calldata metadata) external;

    /// 単一のフィールドを更新し、他のフィールドはそのままにします。`validatorId`のレコードがまだ存在しない場合はリバートします。
    /// `setMetadata`はレコードを作成できる唯一のエントリポイントです。`field == SOCIALS`または`ADDITIONAL_INFO`の場合、呼び出し元は
    /// UTF-8 JSONオブジェクトを渡すべきです; レジストリは`value`をそのまま保存します。
    function updateMetadataField(uint64 validatorId, Field field, string calldata value) external;

    /// `validatorId`の完全な保存されたメタデータレコードを読み取るか、レコードが存在しない場合はすべてデフォルトの
    /// `Metadata`構造体を返します。`hasMetadata`を使用して曖昧さを解消します。
    function getMetadata(uint64 validatorId) external view returns (Metadata memory metadata);

    /// `validatorId`のメタデータレコードが書き込まれた場合は真。`name`が空でないことと同等であり、`name`は
    /// すべての書き込みで必須です。
    function hasMetadata(uint64 validatorId) external view returns (bool);

    /// バリデーターの保存された名前のみを読み取るか、メタデータが設定されていない場合は空の文字列を返します。
    function getValidatorName(uint64 validatorId) external view returns (string memory);
}
```

### 認可

すべての書き込みエントリポイント(`setMetadata`、`updateMetadataField`)について、実装は呼び出し時に`STAKING_PRECOMPILE()`のステーキングプリコンパイルで`getValidator(validatorId).authority`を呼び出してバリデーターの権限を解決し、`msg.sender`がそのアドレスと等しい場合に呼び出しを受け入れる必要があります。実装は権限アドレスをキャッシュまたはシャドウイングしてはなりません: ステーキングプリコンパイルでの権限の変更は即座に有効でなければなりません。

MRC-13: バリデーター メタデータ レジストリ

==== 翻訳マークダウン ====
このベースラインを超えて、実装は独自の認可モデルを定義する自由があり、追加の呼び出し元からの書き込みを受け入れることができます — 例えば、委任されたオペレーターキー、マルチシグラッパー、ガバナンスコントラクト、または指定されたメタデータマネージャーなど — 選択されたスキームの下でアクセスが許可されていない呼び出し元は拒否される必要があります。 認可されていない呼び出し元のリバート理由は実装に依存しますが、文字列ではなくカスタムエラー(例: `Unauthorized()`)であるべきです。

### フィールドの意味

- `name` は必須であり、メタデータを持つバリデーターに対しては空であってはなりません。 `setMetadata` は空の `name` が与えられた場合にリバートしなければなりません。 `updateMetadataField` は `Field.NAME` と空の値で呼び出された場合にリバートしなければなりません。上記のように、リバート理由は実装に依存しますが、カスタムエラー(例: `ValidatorNameEmpty()`)であるべきです。
- `website`、`description`、`logo`、`socials`、および `additionalInfo` はオプションの文字列です。 レジストリはその内容を検証してはなりません; 統合者はそれらを信頼できない入力として扱い、レンダリング前にサニタイズするべきです。
- `socials` は非空の場合、UTF-8 JSONオブジェクトであるべきです。そのキーは小文字のプラットフォーム識別子であり、値は対応するプロフィールURLまたはハンドルであるべきです。例えば:

  ```json
  {
    "x": "https://x.com/monad_xyz",
    "telegram": "https://t.me/monad",
    "discord": "https://discord.gg/monad",
    "github": "https://github.com/monad-developers"
  }
  ```

  プラットフォームキーのセットはこのMRCによって列挙されていません — 統合者は未知のキーを不透明として扱い、そのまま通過させるべきです。 `socials` をJSONオブジェクトとしてエンコードすること(構造体内で個々のソーシャルプラットフォームを名前付けするのではなく)は、エコシステムのソーシャルメディアの風景が時間とともに変化する中で、レジストリを使いやすく保ちます。
- `additionalInfo` は非空の場合、UTF-8 JSONオブジェクトであるべきです。これは将来の互換性のあるメタデータ拡張(例: 委任ポリシー、署名された証明、コンテンツハッシュ、将来のMRCペイロード)用に予約されており、このMRCによって定義されたトップレベルのスキーマはありません; 下流のMRCはその中に予約されたキーの名前空間を定義することができます。
- `socials` と `additionalInfo` は生の文字列として保存されます。 レジストリはそれらを解析しようとせず、構文的に無効なJSONを拒否せず、読み取り時にバイト単位で返さなければなりません。したがって、JSONの準拠はライターと消費者によって強制される慣習であり、レジストリによって強制されるものではありません。

### 書き込み前提条件

`setMetadata` は新しいレコードを作成できる唯一のエントリポイントです。 `updateMetadataField` は既存のレコードがない `validatorId` に対して呼び出された場合にリバートしなければなりません(すなわち、`hasMetadata(validatorId)` が `false` である場合)。この不変条件が「`name` は必須」というルールを強制可能にします: 空の `name` を持つレコードは存在できません。なぜなら、作成する唯一の方法である `setMetadata` が空の名前を拒否し、フィールドの更新はレコードが存在する前には実行できないからです。

### イベント

成功した書き込みごとに正確に1つの `MetadataUpdated` イベントが発生しなければなりません。 `metadata` フィールドは、書き込み直後に観測可能な完全なレコードを反映しなければなりません — `updateMetadataField` に対しては、これは以前に保存されたフィールドに加えて新しく更新されたフィールドを意味します。

### 読み取りの意味

- `getMetadata`、`getValidatorName`、および `hasMetadata` はステーキングプリコンパイルを呼び出してはなりません。
- `STAKING_PRECOMPILE()` は `0x0000000000000000000000000000000000001000` を返さなければなりません。
- `hasMetadata` は保存された `name` が非空である場合にのみ `true` を返さなければなりません。 `name` は空の文字列に設定できないため、これは「このバリデーターに対してメタデータが書き込まれたことがあり、その後ヌルにされていない」ということと同等です。
- 実装はこのインターフェースの外で追加のビュー関数を公開することができます(例: 統合された「ステーキング情報 + メタデータ」リーダー)、しかしここで定義された関数の意味を変更してはなりません。
==== 終了 ====

### チェーンの詳細

このMRCに準拠したレジストリコントラクトは、デプロイ時に選択された通常のコントラクトアドレスにデプロイされます — プレコンパイルアドレスではなく — そして、レジストリが権限解決のために`0x0000000000000000000000000000000000001000`のプレコンパイルを呼び出すという点を除いて、両者は無関係です。

このMRCは、特定のバイトコードやアドレスではなく、インターフェースと動作仕様を定義します。独立してデプロイされた準拠実装は、任意のMonad-EVMネットワーク上で共存することができます。このMRCは、それらのいずれかを標準的なものとして指定せず、アドレスを記録しません。統合者とバリデーターは、自身の信頼と運用の好みに基づいて、どの準拠デプロイメントに書き込み、どのデプロイメントから読み取るかを選択します。

任意のデプロイメントは、`0x0000000000000000000000000000000000001000`でステーキングプレコンパイルを公開しているネットワーク上でのみ有効です。プレコンパイルが存在しないネットワークでは、書き込みメソッドはリバートし、プレコンパイルを介してプロキシする読み取りメソッドはゼロレコードを返すため、そのようなネットワーク上では準拠レジストリは機能しません。

## 理由

**なぜステーキングのプリコンパイルに権限を固定するのか?** プリコンパイルはすでに `validatorId` から権限アドレスへの標準的なマッピングを保持しており、権限のローテーションがコンセンサスによって認識される唯一のメカニズムです。他のソース(例えば、名前に対するECDSA署名)からアイデンティティを再導出することは、二次的で異なるアイデンティティシステムを導入することになります。

**なぜ `setMetadata` を `updateMetadataField` から分離するのか?** 例えばロゴのURLだけを変更したいバリデーターは、1つの短い文字列を変更するために、全体のレコード(潜在的に長い `description` や `additionalInfo` フィールドを含む)を再提出しなければならなくなります。フィールドごとの更新はガスとコールデータのコストを削減し、権限が他のフィールドを誤って上書きする可能性を減らします。

**なぜ `name` が唯一の必須フィールドなのか?** 名前のないバリデーターは、設定されていないレコード(`hasMetadata` を参照)と区別がつきません。他のすべてのフィールドには防御可能な空のデフォルトがあります — バリデーターは正当な理由でウェブサイトを持たない、ロゴを持たない、またはソーシャルプレゼンスを持たない場合があります。

**なぜJSONの `additionalInfo` フィールドが必要なのか?** 構造体を拡張することはABIを壊す変更です。自由形式のテキストフィールドは、将来のMRCが構造化された拡張(委任ポリシー、署名された証明、IPFS CIDなど)を新しいレジストリのデプロイやストレージの移行なしにレイヤーできるようにします。JSONが不透明な `bytes` ブロブよりも選ばれた理由は、レコードの残りがすでに人間が読めるテキストであり、この分野のオフチェーンの消費者はすでにJSONを話し、バイナリペイロードは必要なときにJSON値内で16進数エンコードできるからです。

**なぜ `socials` にJSONを使用するのか(プラットフォームごとに1列ではなく)?** 構造体内で特定のプラットフォームを指定すると、レジストリが今日のソーシャルメディアの風景に固定されてしまいます。プラットフォーム識別子でキー付けされたJSONオブジェクトは、ツールが既知のキー(`"x"`、`"telegram"`、…)を選び出すのに十分構造化されており、セットを規定することなく新しいプラットフォームをバリデーターが追加でき、プラットフォームを削除しても死んだ構造体フィールドを残しません。レジストリは意図的にJSONを解析しません — それはオンチェーンで高価であり、仕様が特定のJSON方言を固定することを強制することになります — したがって、準拠は作成者と読者の間で社会的に強制されます。

**なぜ権限アドレスはベースラインであり、唯一のライターではないのか?** 権限アドレスは、すべてのバリデーターが今日実際に制御している唯一のアイデンティティであるため、それに固定することで一貫した、コンセンサスに沿ったデフォルトを提供します。しかし、バリデーターにはメタデータ管理を委任する正当な理由があります — ホットキー/コールドキーの分離、ブランドをステーキングキーに触れずに回転させるチームオペレーター、セキュリティを重視するオペレーターのためのマルチシグ制限の変更 — そして、これらのフローが権限キーを共有することを強制すると、その影響範囲が拡大するか、バリデーターが再びオフチェーンのキュレーションに追い込まれることになります。実装が権限のベースラインを超えてライターセットを拡張できるようにすることで、デフォルトパスの監査可能性を保持し(誰でも権限が少なくとも許可されていることを確認できます)、運用上現実的なポリシーの余地を残します。

**なぜデータをオンチェーンに保存するのか、単にコンテンツハッシュではなく?** 名前をオンチェーンに保存することは、バリデーターのガス予算に対して安価であり、名前やウェブサイトのような一級フィールドのために外部のコンテンツアドレスストレージの可用性に依存することを排除し、ライトインテグレーターがIPFSやHTTPフェッチャーを実行せずにメタデータを読み取ることを可能にします。より重い拡張ペイロードは、`additionalInfo` を使用してコンテンツハッシュを保持することがあります。

## 後方互換性

このMRCは純粋に追加的です:新しいアプリケーションレイヤーのコントラクトを指定し、ステーキングのプリコンパイル、EVM、または既存のコンセンサスやネットワーキングの動作を変更しません。後方互換性のない変更は導入されません。

現在オフチェーンの `metadata.json` ファイルを消費しているエコシステムツールは、引き続きそれを使用することができます。ツールは、利用可能な場合はレジストリから読み取るように移行すべきであり、オフチェーンファイルはまだメタデータを登録していないバリデーターのためのフォールバックとして扱うべきです。

## テストケース

準拠した実装は以下の動作を示すことが期待されます:

1. バリデーターの権限からの `setMetadata` の呼び出しは成功し、完全なレコードを永続化し、保存されたレコードと共に `MetadataUpdated` を発行します。
2. バリデーターの現在の権限でもなく、実装の独自のスキームの下で認可されていないアドレスからの `setMetadata` の呼び出しはリバートします。
3. `metadata.name == ""` の `setMetadata` の呼び出しはリバートします。他のすべてのフィールドが非空であり、呼び出し元が認可されていてもです。
4. `hasMetadata` が `false` の `validatorId` に対する `updateMetadataField` の呼び出しは、呼び出し元のアドレスに関係なくリバートします。
5. 各 `Field` バリアントに対する `updateMetadataField` の呼び出しは、そのフィールドのみを更新し、他のすべてのフィールドは変更せず、更新後の完全なレコードを持つ `MetadataUpdated` を発行します。
6. `updateMetadataField(_, NAME, "")` の呼び出しはリバートします。他の `field` と空の `value` を持つ呼び出しは成功し、そのフィールドをクリアします。
7. `updateMetadataField(_, ADDITIONAL_INFO, value)` の呼び出しは、レジストリによるJSON検証を行わずに `additionalInfo` に `value` をそのまま保存します。
8. ステーキングプリコンパイルのバリデーターの権限が `A` から `B` に移行した後、`B` からの書き込みはレジストリに対するアクションを必要とせず成功し、権限がライブで解決されることを示します。
9. `hasMetadata(id)` は、書き込まれたことがない任意の `id` に対して `false` を返し、成功した `setMetadata` の後に `true` を返します。
10. `STAKING_PRECOMPILE()` は `0x0000000000000000000000000000000000001000` を返します。

## 参照実装

規範的なアーティファクト

フォーラムでの議論

22件の投稿 · 13件のいいね · 4 日前
フォーラムで続きを読む ↗
  1. @Đorđe Mijović #1 2026/06/16 17:53

    What this MRC is proposing A draft MRC for a permissionless on-chain registry of validator metadata. Each validator’s authority address — as already known to the staking precompile — can publish a record containing their name, website, description, logo, socials, and a forward-compatible JSON extension blob, keyed to the validatorId . The problem it solves The staking precompile knows what consensus needs — validator IDs, authority addresses, stake, commission — but nothing humans can read. Today every wallet, explorer, dashboard, and delegation tool solves this independently: maintain your own metadata.json file, scrape socials, ask validators directly. The result is fragmented naming across the ecosystem and a quiet concentration of “who gets to label validator N” in whoever happens to be curating the list a user is looking at. A registry contract where validators publish their...

  2. @Roman Karpenko #2 2026/06/16 19:28

    Supportive — I sit on both sides of this: a validator (testnet id 267) currently published via the off-chain validator-info repo, and the operator of MonadPulse, a third-party indexer that reads names from it today. A single on-chain shape I write myself removes the “who labels validator N” fragmentation directly. One addition worth considering for additionalInfo: a conventional key for self-declared infrastructure (hosting provider / ASN / region). Today infra concentration is only visible by scraping gossip and mapping IPs to ASNs by hand; a validator-declared field would give explorers and delegation tools a first-class place to surface provider diversity. Open-schema in additionalInfo keeps it optional and forward-compatible. Happy to integrate the reference deployment into MonadPulse once it’s live.

  3. @Vladimir Understanding #3 2026/06/16 22:29

    We support this direction. From a validator operator perspective, this solves a very real problem: validator identity is currently fragmented across explorers, wallets, dashboards, and privately maintained lists. That creates inconsistent names/logos, stale links, and unnecessary dependence on whoever curates a given frontend. Having validator-controlled metadata anchored to the same authority model used by staking feels like the right baseline. It keeps the registry permissionless, makes the source of the update auditable, and gives integrators a simple common shape to read from. A few points I’d like to highlight: First, I strongly agree that the authority address should be the required baseline writer, but not necessarily the only writer. In practice, teams should not have to touch their core staking authority key just to update a logo, website, or social link. Delegated metadat...

  4. @Colinka | Proofoflines.org #4 2026/06/16 22:44

    Supportive, and this sits close to what we work on. We run ProofLine, a Japan testnet full-node, and publish a geo and ASN concentration map of the active set. We build it by scraping peer endpoints from gossip, mapping IPs to ASNs, and aggregating by provider, so the “who labels validator N” fragmentation shows up on the infrastructure side too, not just naming. That points to one field worth considering for additionalInfo : a conventional key for self-declared infrastructure (hosting provider / ASN / region). It is useful on its own, and its value grows when it can be cross-checked against what the network actually observes. We already produce that observed side (provider and ASN inferred from live peer endpoints), so a declared field would let explorers and delegation tools surface drift between what an operator states and what is measured: stale entries, accidental mislabels, or...

  5. @badfriend #5 2026/06/17 19:03

    Great idea. I’ve spent a lot of time in different blockchain explorers lately and this was a problem everywhere. More than 50% of validators didn’t even have a description or name. At the same time, some profiles were filled out really well, which reflects the exact issue you’re talking about. The only thing that concerns me is that pfps will stay offchain. Let’s make our own monad validator punks.