はじめに
『DApps開発入門』という本や色々記事を書いているかるでねです。
今回は、EthereumのスマートコントラクトがSolanaを外部ストレージとして扱い、書き込みと読み取りをクロスチェーンで安全に行う仕組みを提案しているERC7694についてまとめていきます!
以下にまとめられているものを翻訳・要約・補足しながらまとめていきます。
他にも様々なEIP・BIP・SLIP・CAIP・ENSIP・RFC・ACPについてまとめています。
概要
ERC7694は、Ethereumにおけるクロスチェーン・ストレージルーティングの仕組みを拡張し、Solanaブロックチェーンをストレージ先として直接利用できるようにする標準です。
これまでEthereumのスマートコントラクトは、以下のような外部ストレージに処理を委譲できました。
- Ethereum L1 コントラクト
- Ethereum L2(レイヤー2)
- オフチェーンのデータベース
ERC7694は、ここにSolanaという別のL1ブロックチェーンを新たな保存先として追加します。
EthereumからSolanaへの処理委譲とは何か
ERC7694により、Ethereum L1上のスマートコントラクトは、「自分自身のロジックの一部として、Solanaへの書き込み処理を遅延実行(defer)する」という構成を取れるようになります。
ここで重要なのは以下の点です。
- Ethereumコントラクトが直接Solanaを実行するわけではない
- クライアント(ウォレットや実行環境)がSolanaトランザクションを扱えることが前提
- Ethereum側はSolanaに保存されるべき処理をルーティング指定するだけ
つまり、EthereumコントラクトはSolanaを「外部ストレージ兼実行環境」として扱います。
EIP3668との関係(Offchain Lookup)
Solanaに保存されたデータは、そのままではEthereumコントラクトから参照できません。 そこでERC3668(Offchain Lookup)が利用されます。
ERC3668については以下の記事を参考にしてください。
ERC3668とは、「スマートコントラクトの実行中に、オフチェーンのHTTPサービスからデータを取得し、その結果を検証付きでコールバックさせる仕組み」です。
ERC7694では以下の流れになります。
- Solanaにデータを書き込む
- HTTPゲートウェイがSolana上のデータを取得
- そのデータをERC3668に準拠したフォーマットに変換
- EthereumコントラクトがOffchain Lookupを通じて参照
これにより、Ethereum側のコントラクトはSolanaを意識せずに、標準的な方法でデータを取得できます。
ERC7694が目指すもの
ERC7694は、Ethereumが利用できるブロックスペース(計算・保存の場)を、 Ethereumエコシステムの外側まで広げることを目的としています。
Ethereumを「中心」としつつも、以下の他チェーンの特性を、Ethereumコントラクトの設計に直接組み込めるようにする標準です。
- 実行コストが安い
- 独自の設計思想を持つ
- 異なるユーザー層を持つ
動機
既存のCross-Chain Storage Router Protocolの限界
EIP7700で定義された Cross-Chain Storage Router Protocol(CCIP-Store)では、 以下の3種類の外部ストレージルーターが定義されていました。
| ストレージ先 | 特徴 |
|---|---|
| Ethereum L1 | 完全にオンチェーンだが高コスト |
| Ethereum L2 | 安価だが Ethereum に依存 |
| データベース | 柔軟だが中央集権的 |
ERC7694は、ここにSolana向けの第4のストレージルーターを追加します。
中央集権リスクの問題
L2やデータベースは、スケーラビリティの面では優れていますが、どちらも「中央集権化の要因」を内包しています。
L2 の中央集権要因
- Ethereum インネットとの共有セキュリティ
- シーケンサーやブリッジ設計への依存
つまり、L2 は「Ethereumの延長」であり、完全に独立した存在ではありません。
データベースの中央集権要因
- 単一または少数の物理サーバー
- 運営主体への信頼が必須
これはブロックチェーンの思想とは相反します。
独立した合意形成を持つストレージの必要性
この背景から、独自のコンセンサスアルゴリズムを持つブロックチェーンをストレージとして使う方が望ましいという考え方が出てきます。
Solanaは以下の特徴を持っています。
- Ethereumとは独立したL1ブロックチェーン
- 高スループットかつ低コスト
- 実運用されている強力なエコシステム
ERC7694は、こうしたSolanaの特性を「Ethereumの外部ストレージとして正式に扱う」ためのルールを定義します。
クライアントに求められる振る舞い
ERC7694では、Ethereumクライアントやウォレットが、以下を行うことを前提としています。
- Solana向けのトランザクション生成
- 署名および送信
- 必要に応じたキー管理
これにより、Ethereumユーザーは追加の専用ツールなしでSolanaを利用できます。
ユースケース:ENS のようなチェーン非依存プロトコル
例えば ENS(Ethereum Name Service)のようなチェーン非依存プロトコルでは、
- 名前解決ロジックはEthereum側で管理
- 実データはSolanaに保存
- Solanaユーザーにもネイティブに対応
といった設計が可能になります。
これにより、以下の利点があります。
- EthereumとSolanaのユーザーを同時に取り込める
- 高コストなEthereumストレージを節約できる
- それでも検証可能性は維持できる
仕様
ERC7694は、Ethereumコントラクトがストレージ書き込み処理をSolanaに委譲するための具体的な実装ルールを定義しています。 この仕様は大きく分けて次の流れで構成されています。
- Ethereum側でSolanaへのストレージルーティングを宣言する方法
- EVMとSVM間でのデータ型変換ルール
- Solana側での書き込み処理の前提
- Solanaに保存されたデータをEthereumから読み取る方法
Solanaストレージルーターの基本構造
StorageRoutedToSolana エラー
ERC7694では、Solanaへのストレージ書き込みは「エラーによるルーティング」として表現されます。 これはEIP-7700で定義されたストレージルーティングの設計を踏襲したものです。
StorageRoutedToSolana
error StorageRoutedToSolana(
bytes32 programId,
bytes32 account
);Solanaへのストレージ書き込みをクライアントに通知するために発生させるエラー。
Ethereumコントラクトは、Solanaに直接書き込みを行いません。
代わりにこのエラーを revert することで、「Solanaに対してこの内容を書き込んでほしい」という意図をクライアントに伝えます。
programId はSolanaにおけるプログラム(Ethereum のコントラクトに相当)を示し、account は書き込みを実行する管理用ウォレットを示します。
パラメータ
programId- Solana上のプログラムIDを
bytes32で表現した値。
- Solana上のプログラムIDを
account- Solana上で書き込みを行う管理アカウントを
bytes32で表現した値。
- Solana上で書き込みを行う管理アカウントを
Ethereumコントラクト側の実装例
setValue
function setValue(
bytes32 node,
bytes32 key,
bytes32 value
) external {
(
bytes32 programId,
bytes32 account
) = getMetadata(node);
revert StorageRoutedToSolana(
programId,
account
);
}Solanaへのストレージ書き込みを要求する関数。
この関数は Ethereum上では実際の書き込み処理を行いません。
getMetadata によって、対象となるSolanaプログラム IDと管理アカウントを取得し、その情報を StorageRoutedToSolana エラーとして revert します。
この revert を検知したクライアントが、Solanaトランザクションを実行します。
引数
node- ストレージの名前空間や対象ノードを表す識別子。
key- ノード内のキーを表す識別子。
value- 保存する値を表す識別子。
EVMとSVMのエンコーディング差異
Solanaの仮想マシン(SVM)では、アドレスや識別子に base58 エンコーディングが使われます。
一方、EVMでは hex エンコーディングが標準です。
そのためERC7694では、以下の処理が必須になります。
- Ethereum側では
bytes32として扱う - Solana側では
PubKeyとして扱う - クライアントが両者を相互変換する
Solana書き込み処理の疑似コード
setValue(Solana 側呼び出し)
const [programId, account, node, key, value] = E2SVM(
[programId, account, node, key, value],
["bytes32", "bytes32", "bytes32", "bytes32", "bytes32"]
);
const program = new program(programId, rpcProvider);
const wallet = useWallet();
if (wallet.publicKey === account) {
await program(wallet).setValue(node, key, value);
}Ethereumから受け取ったデータをSolanaプログラムに書き込む処理。
EVMの bytes32 型はすべてSVMの PubKey 型へ変換されます。
Solanaプログラムの呼び出しは、あらかじめ指定された管理アカウントのみが実行可能です。
これにより、任意のユーザーによる不正な書き込みを防ぎます。
Solanaプログラム側の実装イメージ
setValue(Solana プログラム)
pub fn setValue(
ctx: Context,
node: PubKey,
key: PubKey,
value: PubKey
) -> ProgramResult {
...
}Solana上でデータを書き込む関数。
この関数では、プログラム IDの検証や rent exemption(口座維持に必要な残高)の確認を行います。
その後、アカウントデータをデシリアライズし、node と key の組み合わせで値を保存します。
保存されたデータは後からEthereum側で参照される前提です。
EVMとSVMのデータ型対応表
ERC7694 では、EVMとSVM間の型変換を厳密に定義しています。
| EVM | SVM |
|---|---|
| uint8 | u8 |
| uint16 | u16 |
| uint32 | u32 |
| uint64 | u64 |
| uint128 | u128 |
| uint256 | u256 |
| bytes1 | [u8; 1] |
| bytes2 | [u8; 2] |
| bytes4 | [u8; 4] |
| bytes8 | [u8; 8] |
| bytes16 | [u8; 16] |
| bytes32 | PubKey |
| bytes | Vec |
| string | String |
| address | [u8; 20] |
※ u256 はSVMにネイティブ実装はありませんが、Rustのクレートで一般的に対応されています。
SolanaからEthereumへの読み取り
Solanaに保存されたデータは、Ethereumコントラクトから直接参照できません。 ここでERC3668 準拠した HTTPゲートウェイが使われます。
ERC3668対応HTTP ートウェイ
Solanaデータ読み取り処理
const [programId, node, key] = parseQuery(path);
const [programId, node, key] = E2SVM(
[programId, node, key],
["bytes32", "bytes32", "bytes32"]
);
const program = new program(programId, rpcProvider);
const value = await program.getValue(node, key);
const data = abi.encode(["bytes"], [value]);
emitERC3668(data);SolanaのデータをEthereum向けに変換して返す処理。
ゲートウェイはURLパスから引数を取得し、Solanaプログラムを呼び出します。
取得した値はSVMの型からEVMの bytes32 に変換され、ERC3668形式でEthereumに返されます。
データが存在しない場合は null 相当の値が返されます。
Solana 側の読み取り関数
getValue
pub fn getValue<'a>(
ctx: Context,
node: Pubkey,
key: Pubkey,
account: &AccountInfo<'a>,
) -> Result<Pubkey, ProgramError> {
...
}Solana上に保存された値を取得する関数。
指定されたアカウントが正しいプログラムに属していることを検証し
シリアライズされたデータから node と key に対応する値を取得します。
値が存在しない場合はエラーを返します。
補足
ERC7694における StorageRoutedToSolana() の設計は、EIP7700で定義されているCCIP-Storeの StorageRoutedToL2() と非常によく似た思想を採用しています。
ここで重要なのは、「Ethereumコントラクト自身が他チェーンを直接呼び出さない」という点です。 Ethereumはあくまで意図を宣言するだけで、実行はクライアントに委ねます。
revert を使ったルーティングという設計
Ethereumのスマートコントラクトは、Solanaのような異なる実行環境(SVM)を直接呼び出すことができません。
そのためERC7694では、以下の方法を取ります。
- 書き込み処理を最後まで実行しようとしない
- 途中で
revertする revertの中に「どこに」、「何を」実行すべきかを含める
この revert が、クロスチェーン実行のトリガーになります。
以下は、提示された図の流れをそのまま整理したものです。
sequenceDiagram
participant Client
participant L1 as Ethereum L1 Contract
participant SOL as Solana Program
Client->>L1: setValue(calldata)
L1-->>Client: revert StorageRoutedToSolana(programId, account)
Client->>SOL: Execute on Solana(programId, account, calldata)
SOL-->>Client: response1. クライアントがEthereumコントラクトを呼び出す
ユーザーやアプリケーションは、通常どおりEthereumのL1コントラクトに対して
setValue のような関数を呼び出します。
この時点では、呼び出し側はSolanaを意識する必要はありません。
2. Ethereumコントラクトが revert でルーティングを宣言する
Ethereumコントラクトは処理を続行せず、StorageRoutedToSolana(programId, account) を含む revert を発生させます。
この revert はエラーではありますが失敗を意味しません。
ここで伝えられる情報は以下の2点です。
| 項目 | 意味 |
|---|---|
programId |
Solana 側で呼び出すプログラム |
account |
実行を許可された管理アカウント |
これにより、クライアントは「この処理はSolanaで、このプログラムとアカウントを使って実行する」という指示を正確に受け取ります。
3. クライアントがSolana上で実行する
クライアントは revert 内容を解析し、以下を行った上で、Solanaプログラムを呼び出します。
- EVMの
calldataをSVM用に変換 programIdをbase58にデコード- 指定された
accountを使って署名
ここで初めて実際のストレージ書き込みが行われます。
4. Solana の実行結果がクライアントに返る
Solanaプログラムの実行結果は、クライアントに返却されます。 このレスポンスは、その後ERC3668を通じてEthereum側から参照される可能性があります。
StorageRoutedToL2 との共通点
ERC7694の StorageRoutedToSolana() は、EIP7700における StorageRoutedToL2() と以下の点で共通しています。
revertを使って実行先を指定する- 実行はクライアントが行う
- Ethereumコントラクトは実行環境を意識しない
つまり設計思想は完全に同一です。
唯一の技術的な違い
両者の違いは実行環境の差に起因します。
| 項目 | L2 | Solana |
|---|---|---|
| 仮想マシン | EVM | SVM |
| アドレス形式 | hex | base58 |
| 基本型 | uint256, bytes32 | u64, PubKey |
このためERC7694では、EVMとSVM間のデータ型キャストが明示的に定義されています。 それ以外の設計は、CCIP-Storeの延長線上にあります。
なぜこの設計が重要なのか
この設計によりERC7694は以下の特性を持ちます。
- Ethereumコントラクトは一切変更を強いられない
- クライアント実装で柔軟に対応できる
- 将来、他のL1を追加する際も同じパターンを使える
つまり、Solana専用の特別な仕組みではなく、汎用的なクロスチェーン実行モデル として成立しています。
引用
Avneet Singh (@sshmatrix), 0xc0de4c0ffee (@0xc0de4c0ffee), "ERC-7694: Solana Storage Router [DRAFT]," Ethereum Improvement Proposals, no. 7694, April 2024. [Online serial]. Available: https://eips.ethereum.org/EIPS/eip-7694.
最後に
今回は「EthereumのスマートコントラクトがSolanaを外部ストレージとして扱い、書き込みと読み取りをクロスチェーンで安全に行う仕組みを提案しているERC7694」についてまとめてきました! いかがだったでしょうか?
質問などがある方は以下のTwitterのDMなどからお気軽に質問してください!
他の媒体でも情報発信しているのでぜひ他も見ていってください!


