
StarknetスマートコントラクトモデルとネイティブAAを解説:独自の道を歩む技術の巨匠
TechFlow厳選深潮セレクト

StarknetスマートコントラクトモデルとネイティブAAを解説:独自の道を歩む技術の巨匠
本稿では、StarknetのスマートコントラクトモデルとネイティブAA(アカウント抽象)から出発し、その技術的ソリューションとメカニズム設計を簡単に整理して紹介します。
著者:Shew & Faust、Geekweb3
アドバイザー:CryptoNerdCn、Starknetエコシステムのコア開発者、ブラウザ上で動作するCairo開発プラットフォームWASM Cairoの創設者
概要
Starknetの主な技術的特徴には、ZK証明生成に適したCairo言語、ネイティブレベルのAA(アカウント抽象)、ビジネスロジックと状態ストレージが分離されたスマートコントラクトモデルが含まれる。
Cairoは汎用的なZK言語であり、Starknet上でのスマートコントラクト実装だけでなく、より伝統的なアプリケーションの開発にも利用できる。コンパイルプロセスでは中間言語としてSierraを導入しており、これによりCairoは頻繁に反復進化できる一方で、最下層のバイトコードを変更する必要がなく、変更点を中間言語にのみ反映させればよい。また、Cairo標準ライブラリには、アカウント抽象に必要な多くの基本データ構造がすでに組み込まれている。
Starknetのスマートコントラクトは、EVMチェーンとは異なり、ビジネスロジックと状態データを別々に格納する。Cairoコントラクトのデプロイは「コンパイル、宣言、デプロイ」の三段階から成り、業務ロジックはContract classに宣言され、状態データを持つContractインスタンスはclassと関連付けられて、後者が保持するコードを呼び出すことができる。

このようなStarknetのスマートコントラクトモデルは、コード再利用、コントラクト状態の再利用、ストレージの階層化、ゴミコントラクトの検出に有利である。また、ストレージレンタル制やトランザクションの並列処理の実現にも寄与している。後者の二つは現時点ではまだ実装されていないが、Cairoスマートコントラクトのアーキテクチャはそれらの実現に向けた「必要条件」を提供している。
Starknetチェーン上にはスマートコントラクトアカウントしか存在せず、EOAアカウントはない。初めからネイティブレベルのAAアカウント抽象をサポートしており、そのAAソリューションはERC-4337のアイデアを一定程度取り入れており、ユーザーが高度にカスタマイズされた取引処理スキームを選択できるようにしている。潜在的な攻撃シナリオを防ぐために、Starknetは多くの対策を講じており、AAエコシステムにおける重要な探求を行っている。

本文
Starknetがトークンを発行して以降、STRKはイーサリアムの観測者にとって欠かせない要素の一つとなった。かつて「独自路線」「ユーザーエクスペリエンスを軽視」として知られたこのイーサリアムLayer2のスターは、EVM互換が主流のLayer2エコシステムの中において、まるで世間を避けた隠者のように、ひっそりと自分の畑を耕し続けてきた。
あまりにもユーザーを無視しすぎたため、Discordに公然と「電子物乞い」チャンネルを開設したことで、Starknetは一時的にファームハンターたちから非難を受け、「人情味がない」と罵られながらも、その優れた技術力は瞬時に「価値なし」と見なされてしまった。まるで『金閣寺』の「理解されぬことが唯一の誇りであった」という一節が、まさにStarknet自身の写し身のようである。
しかし、こういった業界の雑音を脇に置いて、純粋にコードにこだわる「技術的趣味」の視点から見ると、ZK Rollupの先駆者であるStarknetおよびStarkExは、Cairo愛好家の目にはまさに宝であり、ある全チェーンゲーム開発者の心の中では、StarknetとCairoこそがWeb3のすべてであり、SolidityやMoveとは比較にならない存在なのである。現在、「技術志向の極客」と「一般ユーザー」の間に横たわる最大の溝は、実はStarknetに対する認識不足によるものが多い。
ブロックチェーン技術への興味と探究心、そしてStarknetの価値発見を目指して、本稿では筆者がStarknetのスマートコントラクトモデルとネイティブAAに焦点を当て、その技術的仕組みと設計を簡単に整理する。より多くの人々にStarknetの技術的特徴を示すとともに、「理解されざる孤独な旅人」であるこのプロジェクトへの理解を深めていただきたい。
Cairo言語の超簡単解説
以下では、StarknetのスマートコントラクトモデルとネイティブAAについて重点的に議論し、StarknetがどのようにネイティブAAを実現しているかを説明する。これを読めば、なぜStarknetの異なるウォレット間でニモニックフレーズが互換できないのかという疑問も解決されるだろう。
しかし、ネイティブAAの説明の前に、まずはStarknet独自のCairo言語について学んでおこう。Cairoの進化過程には初期版であるCairo0があり、その後に現代版が登場した。現代版のCairoは文法的にRustに似ており、実際には汎用的なZK言語であり、Starknet上でスマートコントラクトを作成するだけでなく、汎用アプリケーションの開発にも使用できる。
例えば、Cairoを使ってZKベースの認証システムを開発でき、このプログラムは自前のサーバー上で実行可能で、StarkNetネットワークに依存する必要はない。つまり、検証可能な計算属性を必要とするあらゆるプログラムは、Cairoで実装できる。そして、Cairoはおそらく現時点でZK証明の生成に最も適したプログラミング言語であろう。

コンパイルプロセスに関して言えば、Cairoは中間言語を経由する方式を採用している。以下の図に示されている通り、SierraはCairo言語コンパイル過程の中間表現(IR)であり、さらにCASMという低レベルのバイナリ形式に変換され、Starknetノード上で直接実行される。

Sierraを中間形態として導入することで、Cairo言語に新機能を追加しやすくなる。多くの場合、Sierraという中間言語に変更を加えるだけでよく、低レベルのCASMコードを直接変更する必要がなくなる。これにより、多くの手間が省かれ、Starknetノードクライアントの頻繁な更新も不要になる。つまり、StarkNetの基盤ロジックを変更することなく、Cairo言語の頻繁なアップデートが可能になる。そして、Cairoの標準ライブラリには、アカウント抽象に必要な多くの基本データ構造がすでに含まれている。
Cairoの他の革新としては、ハードウェアに最適化されたマシンコードへコンパイルする理論的提案「Cairo Native」がある。この案では、Cairoをさまざまなハードウェアに対応したネイティブマシンコードにコンパイルし、Starknetノードがスマートコントラクトを実行する際にCairoVM仮想マシンに依存しなくてもよくなり、コード実行速度を大幅に向上させることが可能になる【現時点では理論段階、未実装】。

Starknetスマートコントラクトモデル:ロジックと状態ストレージの分離
EVM互換チェーンとは異なり、Starknetのスマートコントラクトシステムは画期的な革新を果たしており、これらの革新は多くがネイティブAAや将来実装予定の並列トランザクション機能のために準備されている。ここで知っておくべきことは、イーサリアムなどの従来型パブリックチェーンでは、スマートコントラクトのデプロイは一般的に「コンパイル後にデプロイ」する方式を取る。ETHスマートコントラクトを例に挙げると:
1. 開発者はローカル環境でスマートコントラクトを記述した後、エディタを使ってSolidityコードをEVMバイトコードにコンパイルし、EVMが直接理解・処理できるようにする;
2. 開発者はスマートコントラクトをデプロイするトランザクションを送信し、コンパイル済みのEVMバイトコードをイーサリアムチェーン上に展開する。

(画像出典:not-satoshi.com)
Starknetのスマートコントラクトも「まずコンパイル、次にデプロイ」という考え方に従っているが、スマートコントラクトはCairoVMがサポートするCASMバイトコードの形式でチェーン上に展開される。しかし、スマートコントラクトの呼び出し方法や状態ストレージのパターンに関しては、EVM互換チェーンとは大きな違いがある。
正確に言うと、イーサリアムのスマートコントラクト=ビジネスロジック+状態情報であり、たとえばUSDTコントラクトはTransferやApprovalといった関数機能を実装しているだけでなく、すべてのUSDT保有者の資産状態も保持している。コードと状態が密結合しており、これが多くの問題を引き起こしている。DAPPコントラクトのアップグレードや状態移行が困難になり、トランザクションの並列処理も妨げられる。これは重い技術的負担である。

これに対して、Starknetは状態の保存方法を改良し、そのスマートコントラクト実装では、DAPPのビジネスロジックと資産状態が完全に分離され、別々の場所に保存される。このメリットは明らかで、まずシステムが重複または余分なコードのデプロイをより迅速に識別できるようになる。その原理は次の通りである:
イーサリアムのスマートコントラクト=ビジネスロジック+状態データ。もし複数のコントラクトのビジネスロジック部分が全く同じでも、状態データが異なれば、それらのコントラクトのハッシュも異なり、システムはこれらが冗長かどうか、あるいは「ゴミコントラクト」が存在するかを判別するのが難しい。
一方、Starknetの方式では、コード部分と状態データが直接分離されているため、システムはコード部分のハッシュに基づいて、同一のコードが複数回デプロイされていないかを容易に判別できる。なぜなら、それらのハッシュが一致するからである。これにより、コードの重複デプロイを防止し、Starknetノードのストレージスペースを節約できる。
Starknetのスマートコントラクトシステムでは、コントラクトのデプロイと利用は「コンパイル、宣言、デプロイ」の三段階に分けられている。アセット発行者がCairoコントラクトをデプロイする場合、最初にローカル端末で作成したCairoコードを、Sierraおよび低レベルバイトコードCASMの形式にコンパイルする必要がある。
次に、コントラクトデプロイ者は「declare」トランザクションを送信し、コントラクトのCASMバイトコードとSierraの中間コードをチェーン上に展開する。これをContract Classと呼ぶ。

(画像出典:Starknet公式サイト)
その後、あなたがそのアセットコントラクトで定義された関数機能を利用したい場合は、DAPPフロントエンドを通じて「deploy」トランザクションを送信し、Contract Classに関連付けられたContractインスタンスをデプロイする。このインスタンス内に資産状態が保存される。その後、ユーザーはContract Class内の関数を呼び出して、Contractインスタンスの状態を変更できる。
オブジェクト指向プログラミングを理解している人なら、StarknetのClassとInstanceがそれぞれ何を意味するかすぐに理解できるはずだ。開発者が宣言するContract Classは、スマートコントラクトのビジネスロジックのみを含み、誰でも呼び出せる関数機能だが、実際の資産状態を持たず、「資産エンティティ」を直接実現していない。つまり「魂」はあるが「肉体」はない状態である。
そして、ユーザーが具体的なContractインスタンスをデプロイすると、アセットは「実体化」される。資産「実体」の状態を変更したい場合、例えば自分のトークンを他人に送る場合、Contract Classにあらかじめ書かれた関数を直接呼び出せばよい。このプロセスは、従来のオブジェクト指向言語における「インスタンス化」と類似している(ただし完全に一致するわけではない)。

スマートコントラクトがClassとインスタンスに分離された結果、ビジネスロジックと状態データが分離され、Starknetに以下のような特性をもたらす:
1. ストレージの階層化と「ストレージレンタル制」の実現を促進
ストレージの階層化とは、開発者が自身のニーズに応じてデータを任意の場所(例えばStarknetチェーン外)に配置できることを指す。StarkNetはCelestiaなどのDAレイヤーとの互換性を予定しており、DAPP開発者はデータをこれらの第三者DAレイヤーに保存できる。例えば、ゲームは最も重要なアセットデータをStarknetメインネットに保存し、その他はCelestiaなどのチェーン外DAレイヤーに保存できる。セキュリティ要件に応じてDAレイヤーをカスタマイズ選択するこの方式は、Starknetによって「Volition」と名付けられている。
いわゆるストレージレンタル制とは、各人が占めるストレージ容量に応じて継続的に料金を支払うべきであるということ。占めるオンチェーンスペースの量に応じて、理論的には継続的に家賃を支払うべきである。
イーサリアムのスマートコントラクトモデルでは、コントラクトの所有権が明確ではなく、ERC-20コントラクトの「家賃」をデプロイ者が支払うべきか、それともアセット保有者が支払うべきか判別がつかず、ストレージレンタル機能の導入が遅れている。デプロイ時にデプロイ者に一時的な費用を請求するだけであるが、このストレージ料金モデルは合理的ではない。
一方、Starknet、Sui、CKB、Solanaのスマートコントラクトモデルでは、スマートコントラクトの所有権がより明確に区別されており、ストレージ料金の徴収が容易である【現時点ではStarknetはストレージレンタル制を直接導入していないが、将来的に実現予定】
2. 真のコード再利用を実現し、ゴミコントラクトのデプロイを削減
共通のトークンコントラクトをclassとしてチェーン上に宣言し、誰もがそのclass内の関数を呼び出して、自分専用のトークンインスタンスをデプロイできるようにできる。また、コントラクトはclass内のコードを直接呼び出せるため、SolidityにおけるLibrary関数ライブラリと同様の効果を実現できる。
同時に、Starknetのこのスマートコントラクトモデルは「ゴミコントラクト」の検出にも役立つ。前述の通り。コード再利用とゴミコントラクト検出をサポートすることで、Starknetはオンチェーンデータ量を大幅に削減し、ノードのストレージ負荷を可能な限り軽減できる。
3. 真のコントラクト「状態」再利用
ブロックチェーン上のコントラクトアップグレードは主にビジネスロジックの変更に関係するが、Starknetの場合、スマートコントラクトのビジネスロジックと資産状態は元々分離されているため、コントラクトインスタンスが関連するコントラクトタイプclassを変更すれば、ビジネスロジックのアップグレードが完了する。資産状態を新しい場所に移行する必要はなく、このアップグレード方式はイーサリアムよりも徹底的でよりネイティブである。
一方、イーサリアムコントラクトがビジネスロジックを変更するには、しばしばそれをプロキシコントラクトに「外部委託」し、依存するプロキシコントラクトを変更することで主コントラクトのロジックを変更するが、この方法は簡潔ではなく、「ネイティブ」でもない。

(画像出典:wtf Academy)
あるシナリオでは、古いイーサリアムコントラクトが完全に廃止された場合、内部の資産状態を新しい場所に直接移行できず、非常に面倒である。一方、Cairoコントラクトは状態を移行する必要がなく、そのまま「再利用」できる。
4. トランザクションの並列処理を促進
異なるトランザクション命令の並列度をできるだけ高めるには、異なる人の資産状態を分散して保存することが不可欠である。これはビットコイン、CKB、Suiなどで見られる。そしてこの目標を達成するための前提条件は、スマートコントラクトのビジネスロジックと資産状態データを切り離すことにある。Starknetはまだトランザクションの並列処理に向けて深い技術的実装を行っていないが、今後これを重要な目標として掲げる予定である。
StarknetのネイティブAAとアカウントコントラクトのデプロイ
実際、「アカウント抽象」や「AA」という概念はイーサリアムコミュニティが生み出した独特なものであり、多くの新規パブリックチェーンでは、EOAアカウントとスマートコントラクトアカウントの区別がなく、初めからイーサリアム式のアカウント体系の落とし穴を回避している。例えばイーサリアムでは、EOAアカウントの所有者はチェーン上にETHを持っていないとトランザクションを発行できないため、多様な認証方式を直接選択できず、カスタムの支払いロジックを追加することも非常に面倒である。一部の人々は、イーサリアムのこのアカウント設計はまさに「反人類的」だとさえ考えている。
StarknetやzkSyncEraなど「ネイティブAA」を強調するチェーンを観察すると、明らかな違いが見られる。まず、StarknetとzkSyncEraはアカウントタイプを統一しており、チェーン上にはスマートコントラクトアカウントしか存在せず、初めからEOAアカウントというものは存在しない(zkSync Eraはユーザーが新しく作成するアカウントに、あらかじめコントラクトコードをデプロイして、イーサリアムEOAアカウントの特徴を模倣することで、Metamaskとの互換性を確保する)。

一方、StarknetはMetamaskなどのイーサリアム周辺インフラとの直接互換を考慮しておらず、ユーザーが初めてStarknetウォレットを使う際、専用のコントラクトアカウントが自動的にデプロイされる。要するに前述のコントラクトインスタンスをデプロイするのだ。このコントラクトインスタンスは、ウォレット提供者が事前にデプロイしたコントラクトclassに関連付けられ、classにあらかじめ書かれた機能を直接呼び出せる。
ここで一つ面白い話題に触れる:STRKのエアドロップを受け取る際、多くの人がArgentとBraavosのウォレットが互換できないことに気づいた。ArgentのニモニックフレーズをBraavosにインポートしても、対応するアカウントをエクスポートできない。これはArgentとBraavosが異なるアカウント生成計算方式を採用しており、同じニモニックフレーズでも生成されるアカウントアドレスが異なるためである。
具体的には、Starknetでは新しくデプロイされるコントラクトアドレスは決定論的アルゴリズムで算出され、以下の式が使われる:

上記式中のpedersen()は、ZKシステムで使いやすいハッシュアルゴリズムであり、アカウント生成のプロセスは、pedersen関数にいくつかの特殊なパラメータを入力してハッシュを生成するものであり、このハッシュが生成されたアカウントアドレスとなる。
上図はStarknetが「新しいコントラクトアドレス」を生成する際に使うパラメータを示している。deployer_addressは「コントラクトデプロイ者」のアドレスを表し、このパラメータは空でもよい。つまり、事前にStarknetコントラクトアカウントを持っていなくても、新しいコントラクトをデプロイできる。
saltはコントラクトアドレス計算時のソルト値であり、単純に言えば乱数のことである。この変数は実際にはコントラクトアドレスの重複を避けるために導入されている。class_hashは前述の通り、コントラクトインスタンスに対応するclassのハッシュ値である。constructor_calldata_hashは、コントラクト初期化パラメータのハッシュを表す。
上記の式に基づき、ユーザーはコントラクトをチェーン上にデプロイする前から、生成されるコントラクトアドレスを事前に計算できる。Starknetは、ユーザーが事前にStarknetアカウントを持っていなくても直接コントラクトをデプロイすることを許可しており、その流れは以下の通り:
1. ユーザーは自分がデプロイするコントラクトインスタンスがどのコントラクトclassに関連付けるかを決定し、そのclassのハッシュを初期化パラメータの一つとして使用し、saltを算出し、生成されるコントラクトアドレスを把握する;
2. ユーザーがどこにコントラクトをデプロイするかを把握したら、まずそのアドレスに一定量のETHを送金し、デプロイ費用とする。通常、このETHはL1からクロスチェーンブリッジを経由してStarknetネットワークに移動させる;
3. ユーザーがコントラクトデプロイのトランザクションを送信する。
実際、すべてのStarknetアカウントは上記のプロセスでデプロイされているが、ほとんどのウォレットはこれらの詳細を隠蔽しており、ユーザーはそのプロセスを感じ取れない。まるでETHを送金しただけでコントラクトアカウントのデプロイが完了したかのように見える。

この方式はいくつかの互換性の問題を引き起こしている。異なるウォレットがアカウントアドレスを生成する際、結果が一致しないため、以下の条件を満たすウォレットのみが混在使用可能である:
-
ウォレットが使用する秘密鍵から公開鍵を派生させるアルゴリズムと署名アルゴリズムが同じであること;
-
ウォレットのsalt計算プロセスが同じであること;
-
ウォレットのスマートコントラクトclassの実装細部に根本的な違いがないこと;
前述のケースでは、ArgentとBraavosはどちらもECDSA署名アルゴリズムを使用しているが、双方のsalt計算方法が異なり、同じニモニックフレーズでも両ウォレットで生成されるアカウントアドレスが不一致になる。
ここで再びアカウント抽象の話に戻ろう。StarknetとzkSync Eraは、トランザクション処理プロセスに関与する一連のプロセス――身元検証(デジタル署名の検証)、Gas手数料の支払いなど――をすべて「チェーンの底層」の外に移している。ユーザーは自身のアカウント内で、これらのロジックの実装細部をカスタマイズできる。
例えば、Starknetのスマートコントラクトアカウント内に専用のデジタル署名検証関数をデプロイできる。Starknetノードがあなたが発信したトランザクションを受信すると、あなたがチェーン上のアカウントにカスタマイズした一連のトランザクション処理ロジックを呼び出す。これにより、明らかに柔軟性が増す。
一方、イーサリアムの設計では、身元検証(デジタル署名)などのロジックはノードクライアントコードに固定されており、アカウント機能のカスタマイズをネイティブにサポートしていない。

(Starknetのアーキテクトが示したネイティブAA方式の概念図。トランザクション検証とgas費資格検証がチェーン上のコントラクトで処理されるように移動され、チェーンの基盤仮想マシンはユーザーがカスタムまたは指定したこれらの関数を呼び出せる)
zkSyncEraおよびStarknet公式関係者の説明によれば、このアカウント機能のモジュール化の考え方にはEIP-4337の影響が見られる。ただし、zkSyncとStarknetは初めからアカウントタイプを統合し、トランザクションタイプを統一し、すべてのトランザクションを統一された入口で受け取り処理している点が異なる。一方、イーサリアムは歴史的負債がある上に、財団がハードフォークのような乱暴な進化方式をできるだけ避けたいと考えているため、EIP-4337という「迂回路」的な方式をサポートしている。しかし、その結果として、EOAアカウントと4337方式がそれぞれ独立したトランザクション処理プロセスを採用しており、ぎこちなく、肥大化しており、ネイティブAAほど機敏ではない。

(画像出典:ArgentWallet)
しかし、現時点ではStarknetのネイティブアカウント抽象はまだ完全に成熟していない。実践の進捗を見ると、StarknetのAAアカウントは署名検証アルゴリズムのカスタマイズを実現しているが、手数料支払いのカスタマイズについては、現時点では実際にはETHとSTRKでのgas料金支払いのみをサポートしており、第三者によるgas代行支払いはまだサポートしていない。したがって、StarknetのネイティブAAの進捗は「理論的枠組みは基本的に成熟しているが、実践的実装は進行中」と言える。
Starknet内にはスマートコントラクトアカウントしかないため、トランザクションの全プロセスはアカウントスマートコントラクトの影響を考慮している。まず、Starknetノードのメモリプール(Mempool)がトランザクションを受信した後、検証を行う必要があり、検証ステップには以下が含まれる:
-
トランザクションのデジタル署名が正しいか。この際、トランザクション発信者のアカウント内にあるカスタム検証関数が呼び出される;
-
トランザクション発信者のアカウント残高がgas料金を支払えるか;
注意すべき点は、アカウントスマートコントラクト内のカスタム検証関数を使用することは、攻撃シナリオの存在を意味する。メモリプールが新規トランザクションの署名検証を行う際、gas料金を請求しない(もし直接請求すれば、さらに深刻な攻撃シナリオが発生する)。悪意のあるユーザーは、まず自身のアカウントコントラクト内に非常に複雑な検証関数をカスタム設定し、多数のトランザクションを発信して、それらの検証時にカスタムの複雑な検証関数を呼び出させることで、ノードの計算リソースを完全に枯渇させることができる。
この状況を回避するために、StarkNetはトランザクションに以下の制限を設けている:
-
単一ユーザーが単位時間あたりに発行できるトランザクション数に上限がある;
-
Starknetアカウントコントラクト内でカスタム定義された署名検証関数には、複雑さに関する制限がある。あまりに複雑な検証関数は実行されない。Starknetは検証関数のgas消費量に上限を設けており、gas消費量が高すぎる場合は直ちにそのトランザクションを拒否する。また、アカウントコントラクト内の検証関数が他のコントラクトを呼び出すことも禁止されている。
Starknetのトランザクションフロー図は以下の通り:

注目に値するのは、トランザクション検証プロセスをさらに加速するために、Starknetノードクライアント内に直接BraavosおよびArgentウォレットの署名検証アルゴリズムを実装している。ノードがこれらの主要なStarknetウォレットから生成されたトランザクションを検出した場合、クライアントに内蔵されたBraavos/Argent署名アルゴリズムを呼び出し、キャッシュに類似した思想により、Starknetはトランザクション検証時間を短縮できる。
トランザクションデータはソーターによる検証(ソーターの検証ステップはメモリプールの検証よりもはるかに深い)を通過した後、ソーターがメモリプールからのトランザクションをまとめて処理し、ZK証明生成者に渡す。この段階に入ったトランザクションは失敗してもgas料金が請求される。
しかし、Starknetの歴史を知っている読者は、初期のStarknetは失敗したトランザクションに対して手数料を請求しなかったことを覚えていよう。最も一般的なトランザクション失敗ケースは、ユーザーが1ETHしか持っていないのに10ETHを送金しようとする場合であり、このトランザクションは明らかに論理エラーを含み、最終的に必ず失敗するが、実際に実行されるまでは誰も結果が分からない。
しかし、過去のStarknetでは、このような失敗トランザクションに対して手数料を請求しなかった。このコストゼロのエラートランザクションはStarknetノードの計算リソースを浪費し、DDoS攻撃の温床となる。表面上は、失敗トランザクションに手数料を請求することは簡単そうに見えるが、実際には非常に複雑である。Starknetが新版のCairo1言語をリリースしたのは、まさに失敗トランザクションのgas料金徴収問題を解決するためだった。
ご存じの通り、ZK Proofは有効性証明であり、失敗したトランザクションの結果は無効であり、チェーン上に出力結果を残せない。有効性証明を使って、「ある命令の実行が無効であり、出力結果を生じない」ことを証明しようとすることは、奇妙に聞こえるだけでなく、実際には不可能である。そのため、過去のStarknetは証明を生成する際、出力結果を生じない失敗トランザクションをすべて除外していた。
Starknetチームは後に、より賢明な解決策を採用した。すべてのトランザクション命令がオンチェーンで出力結果を生じるようにする新しいコントラクト言語Cairo1を構築した。一見、すべてのトランザクションが出力結果を生じるということは、論理エラーが決して発生しないことを意味するように見えるが、実際にはトランザクションが失敗するのはバグに遭遇して命令実行が中断される場合が多い。
トランザクションが中断せず、常に成功して出力結果を生じるのは難しいが、実際には非常に簡単な代替案がある。論理エラーにより中断した場合でも、出力結果を返すようにする。ただしこのとき、False値を返して、このトランザクションの実行が順調でなかったことを知らせればよい。
ただし、False値を返すということは、出力結果を返したことになる。つまり、Cairo1では、命令に論理エラーがあったか、一時的に中断したかに関わらず、常に出力結果を生じてオンチェーンに記録される。この出力結果は正しいものでも、Falseというエラーメッセージでもよい。
For Example、以下のコード断があるとする

ここで _balances::read(from) - amount はアンダーフローによりエラーを起こす可能性があり、この場合、対応するトランザクション命令が中断・停止し、チェーン上にトランザクション結果を残さない。一方、これを以下のように書き換え、トランザクションが失敗しても出力結果を返してオンチェーンに保存すれば、見た目上、すべてのトランザクションがスムーズにオンチェーンに結果を残しているように見え、一律で手数料を請求することも非常に合理的に思える。

Starknet AAコントラクト概要
本稿の読者の中にはプログラミング背景を持つ方もいると思われるので、ここではStarknetにおけるアカウント抽象コントラクトのインターフェースを簡単に紹介する:
上記インターフェースの __validate_declare__ はユーザーが発信するdeclareトランザクションの検証に使用され、__validate__ は通常のトランザクション検証に使用され、主にユーザーの署名が正しいかを検証する。__execute__ はトランザクションの実行に使用される。Starknetコントラクトアカウントはデフォルトでmulticall(多重呼び出し)をサポートしていることがわかる。多重呼び出しはいくつかの面白い機能を実現できる。例えば、DeFi操作時に以下の3つのトランザクションをまとめて実行できる:
-
第一のトランザクションでトークンをDeFiコントラクトに承認する
-
第二のトランザクションでDeFiコントラクトのロジックをトリガーする
-
第三のトランザクションでDeFiコントラクトへの承認を取り消す
もちろん、多重呼び出しはアトミック性を持つため、より複雑な用途もある。例えば、裁定取引を実行するなど。
まとめ
Starknetの主な技術的特徴には、ZK証明生成に適したCairo言語、ネイティブレベルのAA、ビジネスロジックと状態ストレージが独立したスマートコントラクトモデルが含まれる。
Cairoは汎用的なZK言語であり、Starknet上でスマートコントラクトを実装できるだけでなく、より伝統的なアプリケーションの開発にも利用できる。コンパイルプロセスでは中間言語としてSierraを導入しており、これによりCairoは頻繁に反復進化できる一方で、最下層のバイトコードを変更する必要がなく、変更点を中間言語にのみ反映させればよい。また、Cairo標準ライブラリには、アカウント抽象に必要な多くの基本データ構造がすでに含まれている。
Starknetのスマートコントラクトは、EVMチェーンとは異なり、ビジネスロジックと状態データを別々に格納する。Cairoコントラクトのデプロイは「コンパイル、宣言、デプロイ」の三段階から成り、業務ロジックはContract classに宣言され、状態データを持つContractインスタンスはclassと関連付けられて、後者が保持するコードを呼び出すことができる。
Starknetの上記スマートコントラクトモデルは、コード再利用、コントラクト状態の再利用、ストレージの階層化、ゴミコントラクトの検出に有利であり、ストレージレンタル制やトランザクションの並列処理の実現にも寄与している。後者の二つは現時点ではまだ実装されていないが、Cairoスマートコントラクトのアーキテクチャはそれらの実現に向けた「必要条件」を提供している。
Starknetチェーン上にはスマートコントラクトアカウントしか存在せず、EOAアカウントはない。初めからネイティブレベルのAAアカウント抽象をサポートしている。そのAAソリューションは一定程度ERC-4337の考えを取り入れており、ユーザーが高度にカスタマイズされた取引処理スキームを選択できるようにしている。潜在的な攻撃シナリオを防ぐために、Starknetは多くの対策を講じており、AAエコシステムにおける重要な探求を行っている。
TechFlow公式コミュニティへようこそ
Telegram購読グループ:https://t.me/TechFlowDaily
Twitter公式アカウント:https://x.com/TechFlowPost
Twitter英語アカウント:https://x.com/BlockFlow_News














