はじめに
『DApps開発入門』という本や色々記事を書いているかるでねです。
今回は、資産の相対価値を「価格」ではなく「別資産の数量」として返すことで、安全で実装ミスの少ないオラクル連携を実現する仕組みを提案しているERC7726についてまとめていきます!
以下にまとめられているものを翻訳・要約・補足しながらまとめていきます。
他にも様々なEIP・BIP・SLIP・CAIP・ENSIP・RFC・ACPについてまとめています。
概要
ERC7726は、資産の相対的な価値を提供するデータフィード(いわゆる価格情報)に対して、共通のAPI仕様を定義するERCです。
このERCの大きな特徴は、価格倍率(price factor)ではなく、明示的なトークン数量を扱うことを強制する点にあります。
まず「データフィード」とは、ある資産が別の資産と比べてどれくらいの価値を持つか、という情報をスマートコントラクトに提供する仕組みです。
代表的な例としては、「1 ETHが何USDか」、「1 トークンが何ETHか」といった情報です。
これらは通常、オラクルと呼ばれる外部データ提供機構を通じて取得されます。
従来の設計では、
「価格 × 数量」のように価格係数を掛け合わせて計算する方式が多く使われてきました。
しかしこの方式は、以下のような問題を引き起こしやすいです。
- 小数点の扱いを誤りやすい
- 桁数(decimals)の違いによるバグが発生しやすい
- 実装者が価格の前提条件を正しく理解していないと危険
ERC7726ではこの問題を避けるため、「価格」そのものではなく、あるトークン量が別のトークン量としてどれだけの価値を持つかを、明示的な数量として返す設計を採用しています。
このアプローチにより、以下の効果があります。
- コントラクト側の実装ミスが減る
- セキュリティが向上する
- 開発スピード(Time-to-Market)が改善する
ERC7726は「人が間違えやすい価格計算をAPI設計で防ぐ」ことを目的とした仕様です。
動機
資産の価値を正しく評価するための情報は、一箇所にまとまって存在していません。
実際には、以下のような状況があります。
- 大手オラクルプロバイダ
- 小規模または特定用途向けのデータ提供元
- 独自APIや独自フォーマット
- セキュリティモデルや信頼前提の違い
このように、情報源が分散しており、それぞれ統一されていないのが現状です。
その結果、多くのDeFiプロトコルやスマートコントラクトは、
自分たち専用の「オラクルアダプタ層」を実装してきました。
ここでいう「オラクルアダプタ層」とは、外部の価格情報を内部仕様に変換し、安全に使える形に整える中間レイヤーのことです。
しかし、このやり方には明確な問題があります。
- プロジェクトごとに似た実装が量産される
- 実装の品質や安全性にばらつきが出る
- 本来不要な工数が何度も発生する
つまり、同じような苦労を各プロジェクトが繰り返している状態です。
ERC7726は、この状況を改善するために設計されています。
多くのユースケースをカバーできる標準APIを提供することで、以下を目指しています。
- オラクル連携の複雑さを減らす
- プロトコルの中核ロジックをシンプルに保つ
- チームのオラクル知識やリソースが少なくても安全に実装できる
特に重要なのは、専門知識や潤沢な開発リソースを持たないプロダクトチームでも扱いやすい設計を優先している点です。
高度に柔軟な設計よりも、「間違えにくく、導入しやすい」ことが重視されています。
結果として、ERC7726は以下の課題に直接応えています。
| 課題 | ERC7726による対応 |
|---|---|
| オラクル仕様の乱立 | 標準APIを提供 |
| 実装ミスによる脆弱性 | 明示的なトークン数量を使用 |
| 開発コストの増大 | 共通仕様により削減 |
| 知識格差による品質差 | シンプルな設計で吸収 |
ERC7726は、価格データの「正しさ」だけでなく、それを扱う開発体験そのものを改善するためのERCです。
仕様
用語定義
ERC7726では、価格やレートという言葉を使わず、「どの資産を、どの資産で評価するか」という考え方を明確にしています。
そのために、以下の3つの用語が定義されています。
base asset(基準資産)
base asset は、「価値を知りたい対象の資産」です。
例えば、「100万 USDCがETHでいくらに相当するかを知りたい」という場合、USDCが base asset です。
このとき重要なのは、数量付きで価値を知りたい側の資産が base asset になる点です。
quote asset(評価資産)
quote asset は、base asset の価値を表現するために使う資産です。
先ほどの例では、USDCの価値をETHで表したいので、ETHが quote asset になります。
つまり、以下の関係です。
-
base asset
評価される側。 -
quote asset
評価に使う側。
value(価値)
value は、base asset の数量を、quote asset の数量として表したものです。
ここで重要なのは、小数の倍率ではないという点です。
ERC7726では、価値は必ず「実際の資産量」として表現されます。
| 内容 | 意味 |
|---|---|
| 1000e6 USDC → ETH | 283,969,794,427,307,000 ETH |
| 1000e18 ETH → USDC | 3,521,501,299,000 USDC |
どちらも「価格」ではなく、ある資産量が、別の資産でどれだけの量になるかを示しています。
この設計により、以下の問題を避けられるようになっています。
- 小数点の扱い
- 桁数(decimals)の違い
- 価格倍率の解釈ミス
メソッド定義
ERC7726が提供する必須メソッドは getQuote です。
この関数は、base asset の数量を、quote asset の数量に変換して返します。
getQuote の役割
getQuote は、「この base asset の数量は、quote asset でいくらか」という問いに直接答える関数です。
振る舞いのルール
この関数には、明確な制約があります。
- 計算結果は必ず
0に向かって切り捨てます
(小数点以下を四捨五入しないという意味です) - 計算結果が
uint256の上限を超える場合はrevertします
これにより、以下の危険な挙動を防ぎます。
- 想定外のオーバーフロー
- 暗黙の丸め処理
関数シグネチャ
以下がERC7726で定義されている getQuote の仕様です。
function getQuote(
uint256 baseAmount,
address base,
address quote
) external view returns (uint256 quoteAmount);
各引数の意味は以下です。
| 引数名 | 内容 |
|---|---|
baseAmount |
base asset の数量 |
base |
base asset のアドレス |
quote |
quote asset のアドレス |
| 戻り値 |
quote asset の数量 |
特殊なアドレスの扱い
ERC7726では、すべての資産がスマートコントラクトのアドレスを持つとは限らない、という前提を置いています。
代表的な例が、ETHやBTC、法定通貨です。
ETHの扱い
ETHはERC7528に従い、以下のアドレスで表現されます。
ERC7528については以下の記事を参考にして下さい。
0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE
これは「ETHを表すための慣習的な疑似アドレス」です。
BTCの扱い
BTCについては、以下の固定アドレスが使用されます。
0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB
これにより、ETHと同様に、アドレスを使った一貫したAPI設計が可能になります。
法定通貨など、アドレスを持たない資産
スマートコントラクト上にアドレスを持たないが、ISO 4217コードを持つ資産については、その数値コードを使います。
例えば、USDはISO 4217で「840」と定義されているため、以下のように表現されます。
address(840)
この仕組みにより、以下を同じインターフェースで扱えるようになっています。
- 仮想通貨
- ネイティブトークン
- 法定通貨
ERC7726の仕様は、「価格を返す」のではなく「資産量を変換する」という考え方を、APIレベルで徹底しています。
その結果、実装者が余計な解釈を挟む余地が減り、安全で分かりやすいオラクル連携が実現できます。
補足
ERC7726が getQuote を中心に設計されている理由は、「オンチェーンで扱う値は、できるだけ解釈の余地を減らしたい」からです。
getQuote は「base のある数量を、quote の数量に変換して返す」ので、利用側(consumer)は base と quote の decimals(小数桁)を意識せずに扱えます。
decimals はERC20トークンで「内部的に何桁を小数として扱うか」を示す仕組みですが、実装者が取り違えると桁ズレのバグや想定外の損失につながりやすいです。
getQuote はその事故を起こしにくくします。
ERC20については以下の記事を参考にして下さい。
一方で、仕様に getPrice 関数が入っていないのは、主に2つの理由です。
1つ目は、オンチェーンでは「価格(price)」そのものが必要になる場面が少ないことです。
多くの処理は、最終的に「この数量は別資産でいくらか」が分かれば足ります。
2つ目は、価格は本質的に小数になりやすく、オンチェーンでの表現が難しいことです。
整数しか扱えない前提で、どのスケール(何桁を小数として扱うか)にするかを決める必要があり、ここが実装者ごとにブレて事故の原因になります。
とはいえ「1単位あたりの価格っぽい値」が欲しいケースもあります。
ERC7726はそれを禁止しているわけではなく、getQuote を使って実現できます。
ERC20の decimals を使う一般的な表現は以下です。
oracle.getQuote(base, quote, 10**base.decimals())
これは「base をちょうど 1.0(= 10**decimals) だけ渡したとき、quote がいくつ返るか」を取っています。
結果として、「base の1単位の価値を quote 量で表したもの」になります。
ただしここでもポイントは、ERC7726の基本思想は「価格の倍率」ではなく「資産量」で返すことなので、上の書き方も「価格を返している」というより「1単位分を変換している」と捉えるのが自然です。
互換性
ERC7726は、既存の多くのデータフィード(2資産の相対価値を扱うもの)を、この標準の形で表現できるようにしています。
ここで言っている「既存のデータフィード」は、例えば「A/Bのレートを返す」タイプのオラクルや価格参照のことです。
ERC7726では「レート」ではなく「数量変換」を返すので、既存の「ペアの相対価値」は以下の形に置き換えられます。
- 「Aの数量
xが、Bの数量yに相当する」という返し方にすれば良い - つまり、既存の「価格 × 数量」という考え方を、最初から「数量変換」の結果として返す
この意味で、多くの既存データフィードは ERC7726の getQuote に寄せて実装し直せます。
セキュリティ
ERC7726はあえて、データ利用側が「このデータは正しいか」をオンチェーンで判定するための仕組みを提供していません。
ここは設計上の割り切りで、標準APIに「正しさ判定」まで含めると、前提条件や評価方法が実装ごとに異なりすぎて共通化が難しいからです。
その代わり、ERC7726に準拠した各実装(データ提供者側)が、次のような情報を自分で決めて公開することが前提になっています。
- どれくらいの品質のデータを提供するか
- どういう条件でデータ提供を止めるか(例:異常値、参照元停止、更新不能など)
そして利用側(consumer)は、その保証内容を読んだうえで、統合するかどうかを判断するべきだとされています。
ここでのポイントは、「ERC7726に準拠しているから安全」とは限らないことです。
安全性はAPIの形ではなく、そのAPIの中身(データの作り方・停止条件・運用)で決まります。
読み手が理解しやすいように整理すると、責任分界はこうなります。
| 役割 | ERC7726が提供するもの | 各実装・利用側がやるべきこと |
|---|---|---|
| データ提供者 |
getQuote という統一された返し口 |
データ品質の定義と公開、停止条件の定義と公開 |
| データ利用者 | 同じ形でデータを受け取れる | 保証内容を確認し、採用可否を判断する |
つまり ERC7726は「受け渡しの形式を標準化する」ことに集中し、
「その中身の信頼性評価」は各プロジェクトの責任でやる設計です。
これにより標準はシンプルになり、導入しやすさが上がりますが、利用側が確認を怠ると危険にもなります。
引用
alcueca (@alcueca), ruvaag (@ruvaag), totomanov (@totomanov), r0ohafza (@r0ohafza), "ERC-7726: Common Quote Oracle [DRAFT]," Ethereum Improvement Proposals, no. 7726, June 2024. [Online serial]. Available: https://eips.ethereum.org/EIPS/eip-7726.
最後に
今回は「資産の相対価値を「価格」ではなく「別資産の数量」として返すことで、安全で実装ミスの少ないオラクル連携を実現する仕組みを提案しているERC7726」についてまとめてきました!
いかがだったでしょうか?
質問などがある方は以下のTwitterのDMなどからお気軽に質問してください!
他の媒体でも情報発信しているのでぜひ他も見ていってください!