スマート コントラクト テクノロジの導入以来、Solidity はスマート コントラクト開発者が選択するコーディング言語となっています。
ただし、Solidity の開発者であれば、Solidity には欠点があることを既にご存じでしょう。他の欠陥の中でも、特定のデータ型の単純な取り扱いミスから主要なセキュリティ上の懸念が生じる可能性があり、組み込みのアクセス制御はありません。
Flow ブロックチェーン用に開発された新しいスマート コントラクト言語であるCadenceは、Solidity の見落としから学習し、固有の問題の多くをネイティブに解決します。また、すでに Solidity を知っていれば、簡単に習得できます。
この記事では、ケイデンスのスマート コントラクト言語を紹介し、Solidity よりもどのように改善されているかを詳しく説明し、いくつかの一般的なスマート コントラクトの例で両方の言語を並べて比較します。最終的に、Cadence に慣れ、Flow を開始する準備が整うはずです。
Cadence は Flow ブロックチェーンを強化するプログラミング言語です。
これはすべて、ケイデンスがデジタル資産の作成と管理のために高度に最適化されていることを意味します。
ケイデンスが導入する最も重要なイノベーションは、
ケイデンスは、多くの点でソリディティよりも優れています。コーディングの小さなミス、セキュリティとアクセス制御、コントラクトの展開という 3 つの例を見てみましょう。
Solidity の最大の問題のいくつかは、通常、些細なミスから生じます。たとえば、デフォルト値だけで変数を初期化すると (便利な場合もありますが)、その変数が変更されていない場合、予期しない結果が生じる可能性があります。また、固定範囲のデータ型は、潜在的なアンダーフローまたはオーバーフローの状況につながる可能性があり、そのデータ型が金銭的価値を表す場合、悲惨な状況になります。
Cadence では、初期化時に変数値を設定し、デフォルト値から不要な結果を削除する必要があります。さらに、Cadence の整数は、アンダーフローまたはオーバーフローの条件について自動的にチェックされますが、OpenZeppelin の安全な数学ライブラリを継承するか、Solidity で 0.8 以上のバージョンを使用する必要があります。
セキュリティとアクセス制御に関しては、Solidity ではカスタム修飾子を作成するか、他のセキュリティ ベースのスマート コントラクトを継承する必要がありますが、デフォルトで公開されている多くの機能も備えています。
Cadence の機能ベースのセキュリティ モデルでは、アカウントはアクセスできる機能のみを実行できます。これは、ケイデンスが基本的に言語自体に組み込まれたアクセス制御を備えていることを意味します。また、Cadence のリソース オブジェクトで定義されたメソッドは、再入攻撃の影響を受けにくくなります。これは、Solidity 開発者がロジックのフローを作成する際に強く意識しなければならないことです。
Solidity スマート コントラクトに問題が見つかった場合、開発者は完全に新しいコントラクトをデプロイしない限り問題を修正できません。それでも、脆弱なコントラクトは依然として存在します。開発者は、ユーザー ベースが新しい契約に切り替わることを確認する必要があります。
ケイデンスでは、スマート コントラクトのアップグレード機能が組み込まれており、透過的です。コードが安全かつ最終的であると宣言されたら、スマート コントラクトの所有者からキーを削除することにより、コントラクトを不変にすることができます。
全体として、ケイデンスはより安全で安全なスマート コントラクト言語であり、エラーの余地が少なくなります。
それでは、Solidity と Cadence で記述されたスマート コントラクトの違いを詳しく見てみましょう。簡単な Hello World コントラクトと、より複雑な NFT 実装について説明します。
史上最高のクラシックから始めましょう。私たちは皆、複数の言語で「Hello World」を書いてきたので、Cadence の簡単なイントロダクションです。
段階的に見ていきましょう。
まず、コントラクトの定義があります。明らかな違いは、Cadence コントラクトにはアクセス制御修飾子 (この場合は pub.この修飾子により、Flow ネットワーク内の全員がコントラクトにアクセスできるようになります。これは、Solidity コントラクトのデフォルトの動作です。
ただし、Cadence では、アクセス制御をaccess(account)
に設定することもできました。これにより、そのコントラクトを展開したアカウントへのコントラクト アクセスが制限されます。ここで、フローとイーサリアムの大きな違いがすでに見られます。コントラクトを Flow ブロックチェーンに展開するだけではありません。それらをアカウント ストレージにデプロイします。 Flow ブロックチェーンでは、各アカウントはリソースと構造を保存できるストレージで初期化されます。このストレージには独自のアクセス許可があり、これにより、コントラクトのメソッドを実行できるユーザーをきめ細かく制御できます。
次の行では、コントラクトのスコープを持つ文字列変数を定義しています。 Cadence ではセミコロンはオプションであり、 let
キーワードを使用して変数を定義します。
Cadence には、可変と不変の 2 種類の変数があります。 let
で作成された変数は不変、または定数として知られています。設定できるのは一度だけであり、契約の存続期間中は変更できません。 var
キーワードを使用して可変変数 (変更可能な変数) を定義します。
この場合、変数値を init メソッドに設定します。これは、Cadence がこのメソッドがコントラクトの展開ごとに 1 回だけ呼び出されるようにするためです。
Solidity のconstructor
に相当する Cadence はinit
メソッドです。このメソッドは、コントラクトのデプロイ時に 1 回だけ呼び出されます。
init メソッド内で、 greeting 変数の値を設定します。 Solidity はデフォルトでコントラクト変数に書き込みますが、Cadence はローカル変数に書き込み、セルフ オブジェクトを使用してコントラクト変数にアクセスする必要があります。この決定により、タイプミスをしたときに誤ってコントラクト変数に書き込むことを防ぐことができます。
コントラクトの 2 番目のメソッドは、 greeting 変数を返します。 Cadence と Solidity の両方で、メソッドへのアクセスをパブリックに宣言する必要があり、両方の言語で戻り値の型を定義する必要があります。この場合、それは文字列です。
しかし、Solidity では、ここでより低レベルである必要があります。文字列がどこにあるかを明示的に伝える必要があります。また、ブロックチェーンの状態を誤って変更しないように、関数をビューとしてマークします。
一方、Cadence は、強力かつ静的に型付けされているため、そのような低レベルの制御は必要ありません。プログラムがチェーン上で実行される前に潜在的なエラーがキャッチされ、冗長なキーワードを削除することでメソッド宣言全体が読みやすくなります。
次に、両方の言語の基本的な NFT コントラクトを見てみましょう。
両方の言語でこの例に対するアプローチが異なるため、別々に見てみましょう。最初に Solidity の例を見て、次に Cadence を見ていきます。
Solidity では、NFT は基本的に ID のリストです。これらの ID をスマート コントラクト内で追跡し、手動でインクリメントして一意性を確保する必要があります。 Solidity は、NFT やその独自性について何も知りません。これは、所有者にマップされた ID の単なるリストであり、すべてコントラクト内で手動で管理されます。これにより、ID の増分が不適切に処理された場合にエラーが発生する余地が残り、同一の ID を持つ複数の NFT が発生する可能性があります。
この例では、NFT には追加のデータが添付されていませんが、別のマッピング ID を URI に追加できます。コントラクトは、新しく作成されたすべての NFT が所有者のアドレスにマッピングされることを保証します。
もちろん、これは単純な例です。通常、リモートで安全な NFT コントラクトと、既知の JPG を NFT にアタッチするために使用されるメタデータなどの機能を取得するには、いくつかのインターフェイスを拡張する必要がありますが、基本的なメカニズムは同じです。
それでは、Cadence バージョンと、この Solidity の例をどのように改善したかを見てみましょう。
Cadence の例は、 NFT
というリソース タイプから始まります。 NFT
の前にある @ 記号に注目してください。このシンボルは、リソース タイプの使用法と動作が明示的なままであることを保証するために必要です。
リソースからインスタンスを作成でき、構造体と同じように属性を持つことができます。通常の構造体との違いは、リソースが格納するデータに加えて所有権を処理する特別な型であることです。
リソース タイプNFT
内には、id フィールドがあります。 id
フィールドは整数のUInt64
で、各 NFT リソースに与えられる一意の ID です。このid
は NFT リソースごとに異なります。つまり、リソースを複製したり組み合わせたりすることはできません。次に、 init
関数を使用してid
フィールドを初期化します。
Rust の借用チェッカーが 1 つの関数だけが変数を変更できることを保証する方法と同様に、Cadence はそのリソースに対しても同じことを保証します。
新しいリソースを作成するときは、ストレージの場所を移動する必要があります。リソースをそのままにしておくと、スマート コントラクトが適切に実行されないため、リソースとその保存場所を慎重に検討する必要があります。また、この形式の制御により、リソースが失われたり誤って削除されたりすることがなくなります。一度に 1 つの場所にしか存在できません。
mint 関数を呼び出すと、 NFT
リソースの新しいインスタンスが作成されます。この関数は、タイプがNFT
のリソースを返し、前に定義したリソースからフィールドid
を取得します。 create
キーワードは、オブジェクト指向プログラミングの new 演算子に少し似ており、新しいリソースを作成します。 <-
または move-operator は、このリソースを呼び出した後、ソースで利用できないことを明示します。
self.account
変数は、コントラクトのデプロイ ターゲットとして使用したアカウントを指します。前に学んだように、スマート コントラクトは Flow ネットワークのグローバル名前空間ではなく、アカウントに属する特別なオンチェーン ストレージにデプロイされます。そのため、スマート コントラクトはデプロイされたアカウントを認識し、その情報をメソッドで使用できます。
この例では、アカウントの save メソッドを使用します。最後のinit
関数では、リソースをsave
メソッドの最初の引数に移動し、アカウント内のどのパスに NFT を格納する必要があるかを伝えます。
NFT はリソースであるため、Flow ネットワーク上のエンティティはそれをコピーできません。その一意性を明示的に追跡する必要はありません。
ケイデンスは、アセットの作成と管理のために最適化された、スマート コントラクト プログラミング言語の新たな解釈です。これは、変数とリソースの強制管理、基本レベルでのセキュリティとアクセス制御、スマート コントラクトを不変にする前にアップグレードする機能などの手段を通じて、Solidity の欠点を軽減する最新の代替手段です。 Cadence は Flow エコシステムの可能性を広げ、Rust などの言語の多くの機能を組み込みます。
そのため、基本的により安全でセキュアな言語でスマート コントラクトを記述しようとしている開発者にとって、Cadence は優れた選択肢です。詳細については、 Cadence DocumentationおよびFlow Developer Portalを参照してください。
本当に素晴らしい一日を!