ICPとEthereumのTransactionの違い
はじめに
ICについて学ぶ上で、従来のブロックチェーンのTransactionの処理はIC上ではどうなっているのかを見るとICの良さが別の角度からわかるのでまとめます。指摘やコメント歓迎です!
またインターネットコンピュータの用語などはこちらにまとめているのでよかったら参考にしてください。
インターネットコンピュータ(IC)における「メッセージ」は、キャニスター間の通信や、ユーザーとキャニスター間のインタラクションを実現するための基本的な仕組みです。 ICは、従来のブロックチェーンとは異なり、アクターモデル(後に解説)を採用しており、トランザクションではなく、メッセージを使用して通信を行っています。
また、従来のブロックチェーンでは、トランザクションはアトミックに実行されます。つまり、トランザクション内のすべての操作が成功するか、すべてが失敗するかのいずれかです。一方、ICのメッセージは、アトミックではありません。メッセージ内の個々の操作は、他の操作とは独立して成功または失敗する可能性があります。このため、ICの開発者は、メッセージの非アトミックな性質を考慮して、アプリケーションを設計する必要があります。
それでは詳しく見ていきましょう!
アクターモデル
ICPの最も特徴的な点は、アクターモデルを採用していることです。Ethereum開発者にとっては馴染みがありませんが、アクターモデルでは「メッセージ」を介して非同期に通信を行います。
アクターモデルでは、各アクター(ICPではキャニスター)が独立した計算単位として動作します。Ethereumのスマートコントラクトが同期的に呼び出されるのに対し、キャニスターは非同期にメッセージを受信し、処理を行います。
またトランザクションとメッセージの構造を見比べると以下のようになります。
トランザクション構造
- From: 送信者アドレス
- To: 受信者アドレス
- Value: 送金額
- Data: 実行するコード
- Gas関連パラメータ
- 署名
メッセージ構造
- 送信元(キャニスターIDまたはユーザーID)
- 宛先(キャニスターID)
- メソッド名
- 引数
- 転送されたCycles
ちなみにメッセージの種類
- Update call: キャニスターの状態を変更するために使用される。
- Query call: キャニスターの状態を読み取るために使用される。
- Response message: 更新メッセージやクエリメッセージに対する応答として使用される。
- Ingress message: 外部ユーザーからキャニスターに送信されるメッセージ。ICとユーザーインタラクションの最初のエントリーポイント。
トランザクションのアトミック性からの解放
Ethereumでは、トランザクションのアトミック性が保証されています。つまり、トランザクション内のすべての操作が成功するか、すべてが失敗するかのいずれかです。
一方、ICPのメッセージはアトミックにも非アトミックにもすることが可能です。キャニスター間のメッセージは基本的に非同期で処理されます。ただし、awaitを使用しない関数内の処理はアトミックに実行されることが保証されています。これにより、swapなど整合性が重要な処理ではアトミック性を確保しつつ、それ以外の処理では非同期実行による高いスケーラビリティを実現しています。
// ICPでのメッセージ処理の例
public shared func transfer(to: Principal, amount: Nat) : async Result<(), Text> {
switch (await tokenCanister.transfer(to, amount)) {
case (#ok) {
// 転送成功の処理
#ok(())
};
case (#err(e)) {
// 個別のエラーハンドリングが可能
#err("Transfer failed: " # e)
};
}
}
// アトミックな処理の例
public shared func swap(args : SwapArgs) : async Result<(), SwapError> {
// awaitを使用しないため、この関数内の処理は全て成功するか全て失敗する
balancesA.put(args.user_b, tokenA_amount);
balancesA.delete(args.user_a);
balancesB.put(args.user_a, tokenB_amount);
balancesB.delete(args.user_b);
#ok(());
}
EOAとInternet Identity
Ethereumでは、EOA(Externally Owned Account)が秘密鍵でトランザクションに署名します。この仕組みでは、秘密鍵の管理やガス代の支払いなど、エンドユーザーにとって複雑な側面があります。
ICPは、Internet Identity(II)という異なるアプローチを採用しています。IIは、WebAuthnを活用した生体認証やデバイスベースの認証を提供します。これは、Web2のユーザー体験に近い使いやすさを実現しつつ、分散型の認証を可能にしています。
リバースガスモデルによる新しいインセンティブ設計
Ethereumでは、トランザクションの送信者がガス代を支払う必要があります。これに対し、ICPは「リバースガスモデル」を採用しています。
ICPでは、計算リソースは「Cycles」という単位で測られ、キャニスター自身が消費します。キャニスターの開発者やDAO組織が事前にCyclesを購入し、エンドユーザーは直接的なガス代を支払う必要がありません。この仕組みが、Web2のようなシームレスなユーザー体験を可能にしています。
// ICPでのCycles管理の例
let cycles = 100_000_000n;
await ic.create_canister({cycles: cycles});
実践的な影響:DAppアーキテクチャの違い
これらの違いは、DAppのアーキテクチャ設計に大きな影響を与えます。
ステート管理
EthereumのDAppでは、スマートコントラクトの状態変更はトランザクションを通じて同期的に行われ、イベントを通じて変更を通知します。一方、ICPでは各キャニスターが独自の状態を持ち、非同期メッセージを通じて更新を行います。
エラーハンドリング
Ethereumでは、トランザクションのアトミック性により、require
やrevert
を使用した単純なエラーハンドリングが一般的です。ICPでは、非同期処理に対応したより柔軟なエラーハンドリングが可能になります。
まとめ
ICPのメッセージングモデルは、Ethereumのトランザクションモデルとは大きく異なりますが、これらは制限というよりも、新しい可能性ある特徴だと思います。非同期通信、柔軟なエラーハンドリング、リバースガスモデルなどの特徴は、高頻度の状態更新が必要なアプリケーションやユーザーフレンドリーなDAppsなど多くのユースケースがありそうです。
Discussion
これは、もう少し正確に書いたほうがいいかも。
ドキュメント上(どのドキュメントか覚えてないけど)は、非同期メッセージごとにコミットされると記述されてます。
awaitで待っているとき、失敗すると、一つ前の非同期メッセージ後の状態まで、ロールバックされます。
成功するとそこで、状態が確定されます。
ここからは、コメントというより雑談ですが、ICPのメッセージは、他のチェーンと同様にブロックに入るので、トランザクションと呼んでもいいんじゃないかと思ったり。
Block Creation: In each round of the consensus protocol, a block containing a set of messages is created. These blocks form a chain, extending the existing blockchain.
Consensus Process: The consensus layer of ICP is responsible for agreeing on which messages should be included in blocks and in what order. This ensures all nodes process messages in the same sequence.
Message Types: Blocks can contain two types of messages:
Block Finalization: Once a block is finalized through consensus, its messages are passed to the message routing layer for further processing.
Message Routing: The message routing layer takes the messages from finalized blocks and places them into the input queues of their target canisters.
Execution: The execution layer then processes these messages from the input queues, potentially generating new messages in output queues.