コントラクト・コール(Contract Call)のご紹介
アルゴランドAVM1.1:コントラクト間コール
ここ数ヶ月、Algorandのスマートコントラクト機能は着実に成熟し、開発者は強力で多様なdapps(分散型アプリケーション)を構築することができるようになりました。最新の機能は、あるスマートコントラクトから別のスマートコントラクトを呼び出すことができるようになったことです。
従来、スマートコントラクトは、ユーザーがアプリケーションコールのトランザクションを開始することによってのみ呼び出すことができました。複数のコントラクトを含む複雑なアプリケーションを構築するには、各コントラクトのローカルまたはグローバルステートに情報を保存し、別のコントラクトがそれを検索して実行ロジックで使用する必要がありました。しかし現在では、コントラクトが他のコントラクトを直接呼び出すことができるようになりました。
このアップデートの影響を理解するために、いくつかの例を見てみましょう。
例1:常にベストディールを得る
「Automated Market Makers」(AMM)は資産取引のプラットフォームであり、資産と資産の交換に利用できます。AMMは、スマートコントラクトを使ってブロックチェーン上に構築されています。
アリスはAlgorandでAMMを書きました。ALGOからUSDCへの取引のための流動性プールを備えています。ユーザーはアリスのスマートコントラクトを呼び出して、ALGOをUSDCに交換したり、逆にUSDCをALGOに交換したりすることができる。
ボブもまた、ALGOをUSDCに交換するために使用できる、Algorand上のAMMを書きました。
マリアは暗号資産トレーダーです。彼女はALGOに楽観的で、10,000USDCをALGOにスワップしたいと考えています。彼女はアリスとボブのAMMのどちらを使ってスワップを行うべきでしょうか?どの瞬間にも、スワップレートは各AMMで準備率に基づいて変動しています。マリアはどのようにして最良のスワップレートを得ることができるでしょうか? 彼女は、両方の現在のスワップレートを手動で見て、ブロックチェーン・ネットワークにアプリケーション・コール・トランザクションを送信することができます。残念ながら、彼女の取引が処理されるまでの数秒の間に、スワップレートは彼女にとって不利な方向に変化する可能性があります。
幸いなことに、マリアは偶然にも開発者でもあるので、スマート・コントラクトを書いて、常に最高のスワップ・レートを得られるようにしています。マリアのコントラクトは両方のレートをチェックし、より有利なレートのスマートコントラクトを呼び出して実際にスワップを行います。これはすべてオンチェーンでアトミックに行われるため、マリアがUSDCに対して最大量のALGOを得られることが保証されています。
これは、マリアのコントラクトが他のコントラクトを呼び出すことができるためにのみ可能です。
例2:アプリケーションの安全性チェック
エリヤは別の暗号資産トレーダーです。彼はアリスのAMMを使って USDCをALGOと交換することにも興味がありますが、アリスのスマートコントラクトを信用できるかどうかはわかりません。彼は彼女のコードを監査し、それはかなり良いように見えるのですが、彼は彼女のAMMを使用することによって、彼がだまされていないことを絶対に確認したいと思います。さらに、現在のスワップのボラティリティを考えると、彼は自分が納得できるレートを得られると確信してスワップを開始したいのです(このレートの変化に対する許容度は「スリッページ」と呼ばれます)。
エリヤはプログラマでもあるので、自分の問題を解決するためにスマートコントラクトを書きます。エリヤのスマートコントラクトは、エリヤが取引してもよいと考えるスワップレートを入力として受け取ります。このコントラクトは最初の取引として、アリスのAMMを呼び出し、100USDCをいくらかのALGOと交換することを送信します。その後、エリヤのスマートコントラクトは、エリヤのアカウントが予想される量のALGOを受け取ったことを確認するために、アサート・ステートメントを使用します。アサートが失敗すると、スマートコントラクト全体が失敗し、したがってアリスのAMMへの呼び出しを含むすべての効果がロールバックされます。アサートが成功した場合、コードはエリヤが期待通りのものを得ていることを保証しています。
これは、エリヤのコントラクトがアリスのコントラクトを呼び出すことができるからこそ可能なのです。
この例は一般化することができます。コントラクトAを直接呼び出すのではなく、 コントラクトAを呼び出して、期待することが実際に起こることを保証する独自のコントラクトを作成することができるようになりました。
例3:他のコントラクトの使用
ファティマはNFTマーケットプレイスを構築しており、人々は彼女のDappを使ってNFTを売買することができます。ファティマは、人々がUSDCまたはALGOのいずれかを使用して決済することができるようにしたいと考えています。しかし、買い手がALGOを使ってAlgo Gator #54を買いたいのに、売り手がUSDCで支払われることを希望したらどうなるでしょうか。ファティマの販売コントラクトはアリスのAMMを呼び出し、買い手のALGOをUSDCと交換します。そして売り手と買い手の両方が、その取引から欲しいものを手に入れることができるのです。
これは、ファティマのコントラクトがアリスのコントラクトを呼び出すことができるからこそ可能なのです。
この例は一般化することもできます。コントラクト同士が呼び合うことができるようになれば、コントラクトはいくつものDappsのユーティリティとして機能するようになります。ファティマは自分でAMMを書き、ALGO-USDCペアの流動性プールを維持することもできましたが、すでにあるものを簡単に使うことができるのであれば、そうする必要はあるのでしょうか?
コントラクトからコントラクトへの呼び出しに関するいくつかの具体的な内容
上記の最初の2つの例は、コントラクトコール機能に明確な機能的価値があることを示しています。3つ目は、モジュラー・コントラクトが無数のアプリケーションで使用される無限の可能性を示唆しています。
しかし、この新機能を利用したDappsを設計する上で、技術的に注意しなければならないことがあります。
コントラクトが他のコントラクトを呼び出すことは、スマートコントラクトの内部から開始される取引であるため、一種の「内部取引」です。そのため、コントラクトAから呼び出されたコントラクトは、コントラクトAと同じトランザクション・グループに属することになります。
コントラクトAがコントラクトBを呼び出し、そのコントラクトBがコントラクトCを呼び出すなど、8段階まで可能です。
有効なコール・シーケンス
AVM1.0で内部トランザクションが導入されて以来、トップレベル・コントラクトごとの内部トランザクションの数に制限が設けられています。この制限は、以前は各トップレベル取引内で16の内部取引でしたが、1つの取引グループ内で合計256の内部取引に変更されました。
2つの有効な取引グループ
内部取引数の制限により許可されない取引グループ。このグループにはコントラクトコールが1件、支払いトランザクションが256件あり、合計257件の内部トランザクションがあります。
Algorand上のスマートコントラクトは、パフォーマンスを保証するために700のオペコード・バジェットが与えられています。コントラクトからコントラクトを呼び出す場合、トランザクション・グループ全体に700のオペコード・バジェットが追加で割り当てられます。言い換えれば、オペコード・バジェットは、内部コントラクトの呼び出しを含むグループ全体にプールされます。例>ジェームスは、いくつかのハッシュを含む特に複雑なスマートコントラクトを書いており、彼はそれが実行するために700以上のオペコード・バジェットが必要になることを知っています。彼は、トップレベル・コントラクトから空のコントラクトを呼び出し、効果的に700オペコード・バジェットを追加しました。それでも足りない場合は、256個の内部コントラクトを呼び出して、256*700の合計で約18万オペコード・バジェットをこのプログラムに使うことができます。Algorandでの開発に慣れている人なら、オペコード・バジェットはすでにトランザクション・グループ全体にプールされており、最大16のトランザクションを持つことができることを思い出すでしょう。256の内部トランザクションは、トランザクション・グループ全体に対するものです。言い換えれば、あるスマートコントラクトが256の内部ペイを呼び出すと、そのコントラクトを呼び出すトランザクション・グループには他のトランザクションは存在できないことになります。
Algorand上のすべてのトランザクションは、最低0.001 ALGOの手数料を要することを忘れないでください。他の2つのコントラクトを呼び出すコントラクトは、実行に0.003 ALGOのコストがかかります。例>ジェームスのコントラクトが256の内部コントラクトを呼び出す場合、それをすべて実行するには0.256ALGO(執筆時、~0.18$)のコストがかかることになります。
Algorand上のスマートコントラクトは、呼び出されると特定の外部リソースへのアクセスを与えられます。開発者は、コントラクトが対話するアドレス、アプリケーション、資産を定義しなければなりません(これらは、「外部」アプリケーション/資産/アドレスと呼ばれます)。コントラクトから呼び出されたコントラクトは、トップレベル・コントラクトがアクセスできる外部オブジェクトのサブセットにアクセスすることができます。これとは別に、トランザクション・グループで作成されたアセットやアプリは、深さに関係なく、グループ内のすべてのコントラクトから暗黙のうちにアクセスできるようになります。
コントラクトAは、コントラクトAを呼び出すコントラクトを呼び出すことはできません。この動作は「リエントランシー(re-entrancy)」と呼ばれ、セキュリティ脆弱性の可能性を高めることが知られており、このような制限が設けられています。
リエントランシー制限で禁止される2つのトランザクション群
コードレベルの詳細や、コントラクト間の呼び出しと同時にリリースされる他の機能についての情報は、開発者ポータルの記事をご覧ください。 Contract Calls and an ABI Come to Algorand.
前回のアップデートであるAVM 1.0については、こちらをご覧ください。Discover AVM 1.0
コントラクトコール機能は現在AlgorandのBetanetにあり、2022年3月中旬にはMainnetとTestnetに登場する予定です。Betanetでぜひお試しください。Discord, github, forum.などを通じてのフィードバックもお待ちしています。
元記事:https://medium.com/algorand/hello-contract-calling-abff8fc00939
Comments