Flowに代表されるブロックチェーン環境で、アカウントにオンチェーンで保存されるコンピュータプログラムは一般的にスマートコントラクトと呼ばれます。スマートコントラクトとは、信頼できる第三者を必要とせずに契約(コントラクト)の履行を検証し、実行するプログラムです。ブロックチェーン上で実行されるコンピュータプログラムは、中央機関(銀行など)に頼ることなく、重要な機能(通貨など)を仲介するため、一般的にスマートコントラクトと呼ばれます。
A New Programming Language
Cadenceはリソース指向プログラミング言語であり、これはスマートコントラクト プログラミングに新たな機能を取り入れ、開発者がコードの安全性、セキュリティ、明瞭性、およびアクセス性を確保できるようにしています。これらの機能の一部は以下の通りです。
型安全性と強力な静的型システム。
- リソース指向プログラミング:リソース指向プログラミングは、リソース(希少なデジタル資産を表すために使用される)が同時に1つの場所にしか存在できず、コピーできず、誤って紛失または削除されることがないことを保証することで、デジタル所有権のための安全で宣言的なモデルを作成する、Linear Typesとオブジェクト機能の組み合わせによる新しいパラダイムです。
- 関数およびトランザクション用の組み込みの事前条件および事後条件。
- 機能群(Cadence)ベースのセキュリティの利用により、オブジェクトへのアクセスはオブジェクトの所有者およびオブジェクトへの有効な参照を持つ者に限定されます。これがCadenceの主なアクセス制御の形です。
Cadenceの構文は、Swift、Kotlin、Rustなどの一般的な現代の汎用プログラミング言語から着想を得ています。リソース型の使用は、Diemチーム(補足: Facebookが開発したLibraの名称変更後の名前)が開発中のプログラミング言語であるMoveの型とよく対応しています。(補足: どちらもLinear Typesを取り入れてそこに保存されるものをリソース型としています)
Cadence's Programming Language Pillars
Cadenceは、新しい高レベルプログラミング言語であり、以下の要件を満たしています。
- 安全性とセキュリティ:安全性とは、スマートコントラクトの信頼性の基礎となるものです(すなわち、バグがなく、機能を果たすこと)。セキュリティとは、ネットワークやスマートコントラクトに対する攻撃(すなわち、悪意のある行為者による不正な行為)を防止することです。ブロックチェーンの不変的な性質と、高価値資産を扱うことが多いことから、スマートコントラクトでは安全性とセキュリティが重要となります。スマートコントラクトの開発では、コードの監査とレビューが重要な要素となりますが、Cadenceは、安全性とセキュリティを基盤として最高レベルに維持しながら、効率性を最大限に高めます。これは、強力な静的型システム、スマートコントラクトによる設計、およびLinear Types(資産を扱う際に有用)に着想を得た所有権プリミティブによって実現されます。
- 明瞭性:コードは読みやすく、その意味はできる限り曖昧であってはなりません。また、検証に適したものでなければ、ツールによる安全性とセキュリティの保証の確保を支援することができません。これらの保証は、コードを宣言型にし、開発者が意図を直接的に表現できるようにすることで達成できます。設計によりこれらの意図を明確にすることで、冗長性はわずかに増しますが、可読性とともに、監査とレビューの効率が向上します。
- アプローチしやすさ:コードの記述やプログラムの作成は、できる限りアプローチしやすいものでなければなりません。Swiftなどの言語の機能を取り入れることで、開発者はCadenceの構文やセマンティクスに親しみを感じられるはずです。実用的なツール、ドキュメント、およびサンプルにより、開発者は迅速かつ効果的にプログラムの作成を開始できます。
- 開発者エクスペリエンス:開発者は、初期のアプリケーションロジックからオンチェーンでのバグ修正まで、開発ライフサイクル全体を通じてサポートされるべきです。
- 直感的なリソース所有権:リソースは、資産の直接的な所有権を表す複合データ型であり、構造体(struct)に似たものです。Cadenceの強力な静的型システムにより、リソースは同時に1つの場所にしか存在できず、コーディングミスによるコピーや損失は発生しません。現在、ほとんどのスマートコントラクト言語では、所有権を記録するために台帳スタイルのアプローチが採用されており、代替可能なトークンなどの資産は、中央台帳のエントリとしてスマートコントラクトに格納されます。Cadenceのリソースは、そのリソースをアカウントのストレージに保存することで、資産の所有権を直接そのアカウントに結びつけます。その結果、所有権はスマートコントラクトのストレージに一元化されません。各アカウントがその資産を所有し、中央のスマートコントラクトによる仲裁を必要とせずに、アカウント間で自由に資産を移転することができます。
Addressing Challenges with Existing Languages
その他の言語ではスマートコントラクトの開発を先行していたが、次世代アプリケーションの長期的実行可能性に影響を与えるエリアがそれらは不足しています。
Safety
安全性とは、スマートコントラクトが意図した通りに機能することに対する信頼性です。スマートコントラクトの「一度デプロイされたら変更不可」という性質が大きく影響します。開発者は、スマートコントラクトをブロックチェーン上に公開する前に、重大な脆弱性を生み出さないよう、一定の予防措置を取らなければなりません。多くのブロックチェーンでは、脆弱性を修正する場合でも、スマートコントラクトの修正や更新は許可されていません。したがって、スマートコントラクトに存在するバグは永遠に存在し続けます。
例えば、2016年には、イーサリアムDAOスマートコントラクト(Decentralized Autonomous Organization)に見落とされていた脆弱性により、スマートコントラクトから数百万ドルが不正に引き出され、最終的にイーサリアムのフォークと2つの別々のアクティブなブロックチェーン(イーサリアムとイーサリアムクラシック)につながりました。
スマートコントラクトが変更に対応するように設計されている場合のみ、バグ修正が可能です。これは複雑性とセキュリティ上の問題をもたらす機能です。 綿密な監査とレビュープロセスにより、バグのないスマートコントラクトを確保することができます。 しかし、スマートコントラクトのコアロジックを正しく機能させるという、すでに時間のかかる作業に大幅な時間が追加されることになります。
見落とされたミスは、最も深刻な事態を引き起こす可能性があります。既存の言語では、関連する不変条件をチェックしないか、またはそれを表現するのが難しいので、金銭的価値や資産を失ったり、重複させたりすることが容易です。例えば、単なる数値は、誤って(または悪意を持って)乗算されたり、無視されたりする可能性のある送金金額を表します。
また、一部の言語では、開発者が忘れがちな動作も表現されます。例えば、固定範囲型で、オーバーフローやアンダーフローの可能性を考慮せずに、金銭的価値を表現してしまうことがあります。Ethereumのスマートコントラクト言語であるSolidityでは、オーバーフローが発生すると、こちらに示すように、値がラップアラウンドします(補足: 処理可能な範囲の最後に達した後に、最初に戻ること)。また、Solidityでは、初期化せずに変数を宣言することもできます。開発者が初期化をどこかで追加し忘れた場合、特定の値を期待してコードの別の場所で変数を読み取ろうとすると、問題が発生します。
Cadenceは型安全で、強力な静的型システムを備えており、重要なクラスの誤りや望ましくないプログラムの動作をコンパイル時(すなわち、オンチェーンでプログラムが実行される前)に防止します。型は静的にチェックされ、暗黙的な変換は行われません。また、Cadenceは算術演算のアンダーフローやオーバーフローを防止することでプログラムの安全性を向上させ、nilケースを明示的にするためのオプショナル型を導入し、常に変数の初期化を要求します。これにより、これらのスマートコントラクトの動作が明らかになり、コンテキストに依存しないことが保証されます。
Security
セキュリティと安全性を組み合わせることで、承認されていないアクセスを防止し、プロトコルで許可されたアクションのみが実行されることを保証することで、スマートコントラクトの長期にわたる成功を確実にします。一部の言語では、関数はデフォルトで公開されており、悪意のあるユーザーが攻撃ベクトルを見つけられる脆弱性が生じます。Cadenceは、機能群(Capability)ベースのセキュリティを利用しており、ユーザーや開発者が管理できるルールに基づいて、これにより型システムがアクセス制御を強化することができています。
他のスマートコントラクトとやり取りする際にも、セキュリティは考慮する必要があります。外部呼び出しは、悪意のあるコードが実行される可能性を秘めています。例えば、Solidityでは、呼び出された関数のシグネチャが利用可能なものに一致しない場合、Solidityのフォールバック関数がトリガーされます。これらの関数は悪意を持って使用される可能性があります。多重継承やオーバーロード、ディスパッチなどの言語機能により、どのコードが呼び出されたかを判断することが困難になる場合もあります。
Cadenceでは、Design By ContractとOwnership Primitivesにより、プログラムの安全性とセキュリティが強化されています。Design by contractにより、開発者は関数やインターフェースの事前条件と事後条件を宣言型で指定できるため、呼び出し側は呼び出されたコードの動作を確実に把握できます。Ownership primitivesはLinear Type(linear logic)にヒントを得たもので、資産を扱う際の安全性を高めます。これにより、例えば、貴重な資産が誤って、あるいは悪意を持って紛失されたり、複製されたりしないようにすることができます。
Clarity and Approachability
暗黙性、文脈依存性、および表現力は、開発者がしばしば直面する言語ベースの課題です。これらは、言語およびその言語を使用して構築されたプログラムの明瞭性(すなわち、コードの読みやすさや意図された機能の特定のしやすさ)やアプローチしやすさ(すなわち、コードの解釈や作成のしやすさ)に影響を与えます。例えば、Solidityではストレージは低レベルのキーバリュー方式で実装しなければならず、開発者の意図がわかりにくくなります。構文の混乱も一例で、「=+」は合法な構文ですが、おそらく意図されたであろうインクリメントではなく、代入につながります。Solidityには、意図しない結果につながる可能性がある、一般的ではない動作をする機能もあります。多重継承はプログラムで予期せぬ動作につながる可能性があり、コードのテストや監査ではこの問題を特定することはできません。
Ethereumブロックチェーンのコードの不変性は、拡張性やその場しのぎの修正を可能にするメカニズムを考慮する必要性を示しています。アップグレード可能性に対する「データ分離」アプローチのようなカスタムメイドのアプローチを使用する開発者は、データ構造の複雑性により問題に直面する可能性があり、一方、「デリゲートコールベースのプロキシ」を使用する開発者は、メモリレイアウトの一貫性により問題に直面する可能性があります。いずれにしても、これらの課題はアプローチのしやすさと全体的な拡張性を損なうことになります。Cadenceにはスマートコントラクトによるアップグレード機能がデフォルトで組み込まれており、アカウントからすべてのキーを削除することで、スマートコントラクトを不変にすることができます。
Cadenceは、インターフェースを利用してスマートコントラクト間の拡張性、コードの再利用、相互運用性を可能にすることで、プログラムの明瞭性と拡張性を向上させます。Cadenceモジュールには、プロジェクトがコードを不変にする前にテストと反復を可能にする、設定可能で透過的なアップグレード機能も組み込まれています。
Cadenceでは、関数の引数の意味を記述するために引数ラベルを使用できます。また、通貨の処理に役立つ固定小数点演算などの一般的な使用事例に対応した便利なデータ構造(辞書、セットなど)やデータ型を備えた豊富な標準ライブラリも提供しています。
Intuiting Ownership with Resources
現在、ほとんどのスマートコントラクト言語では、所有権を記録するために台帳スタイルのアプローチが採用されており、資産は中央台帳の項目としてスマートコントラクト内に格納され、この台帳が資産所有権に関する真実の源となります。この設計には多くの欠点があり、特に単一のアカウントに属する複数の資産の所有権を追跡する場合にはその欠点が顕著になります。アカウントが所有するすべての資産を特定するには、このアカウントが潜在的に含まれる可能性のあるすべてのスマートコントラクトを列挙し、アカウントがこれらの資産を所有しているかどうかを検索する必要があります。(補足: この部分はCadenceとFlowの作者であるチーフアーキテクト、Dieter Shirleyが新しいブロックチェーンを作る上で中心的に対策を考えた部分です。アカウントが何の資産を保有しているかは、そのアカウントに聞いてもわからないのです。そのアカウントの資産情報は全てスマートコントラクトに書かれている為です。)
Cadenceのようなリソース指向の言語では、リソースをアカウントのストレージに保存することで、リソースが直接的にアセットを所有するアカウントと結びつきます。その結果、所有権は単一の中央スマートコントラクトのストレージに一元化されません。代わりに、各アカウントが自身の資産を所有し、保存します。そして、中央スマートコントラクトによる仲裁を必要とせずに、アカウント間で資産を自由に転送することができます。
リソースはLinear Typeから着想を得ており、実質的な価値を持つことが多い資産を扱う際の安全性を高めます。Cadenceの型システムによって強制されるリソースは、資産が正しく操作され、悪用されないことを保証します。
すべてのリソースには、正確に1人の所有者が存在します。リソースが関数のパラメータ、変数の初期値、または同様のものとして使用される場合、オブジェクトはコピーされません。代わりに、新しい場所に移動され、古い場所は直ちに無効化されます。
リソースの所有権が適切に転送されていない場合、(すなわち、プログラムがリソースに複数の所有者を導入しようとした場合や、リソースが所有者を保持しない状態になった場合)言語はエラーを出します。例えば、リソースは正確に1つの変数にのみ割り当てることができ、複数回にわたって関数に渡すことはできません。
リソースはスコープ外に出ることはできません。関数またはトランザクションがアカウントのストレージからリソースを削除する場合は、アカウントのストレージに保存することでトランザクションを終了させるか、明示的かつ安全に削除する必要があります。リソースには「ガベージコレクション」がありません。
特別扱いを受けるリソースオブジェクトは、ランタイムによって強制的に適用される必要があります。コンパイラによる抽象化のみである場合、悪意のあるコードによって容易に価値の保証が破られてしまうでしょう。
リソースは、プログラミング環境におけるアセットの利用方法を変更し、現実世界のアセットにより近づけます。ユーザーは、自身の通貨やアセットを自身のウォレットストレージであるアカウントに保管し、それらを自由に利用することができます。ユーザーは、リソースに対してカスタムロジックや構造を定義することができ、それにより、保管方法に柔軟性を持たせることができます。さらに、誰もが自身の資産を保管しているため、レンタルの計算や課金は、ネットワーク上のすべてのユーザーに対して公平かつ均等に実施されます。
An Interpreted Language
現在、Cadenceはコンパイル言語とは対照的に、インタプリタ言語です。つまり、Cadenceアセンブリ、バイトコード、コンパイラ、Cadence VMは存在しません。
この言語の構造はコンパイルに適していますが(例えば静的型付けなど)、最初のバージョンではインタプリタを使用することで、言語機能を定義する際に、より迅速に言語機能を洗練することができます。
Getting Started with Cadence
さぁCadenceとFlowのゴールと設計について学びましたので、Flowのエミュレータとツールを使い始める準備ができました。First Stepsページで言語の基本とチュートリアルを学習しましょう。
翻訳元->https://cadence-lang.org/docs/
Flow BlockchainのCadence version1.0ドキュメント (Introduction to Cadence )