【Candid】インターネットコンピューターのインターフェース

  • Candidとはなんなんでしょう。

試しにインターネットコンピューターでプログラミングをしてみようと思っている方向けの記事です。

Candidはインターネットコンピューターの言語の一つとして紹介されていますがRustやMotokoとの役割の違いについて触れ、実際の使われ方を紹介していきます。

Candidはインターフェース記述言語

最初に結論から。

Candidはインターフェース記述言語(IDL)としてインターネットコンピューターに用意されました。

MotokoとRustはプログラミング言語として使われているのとは異なりますね。

Candidの使われ方としてはMotokoとCandid、RustとCandid組み合わせで使っていきます。

ちなみに拡張子.didです。

姿かたちはこのようなもの。


※インターネットアイデンティティのdidファイル抜粋

個人的にはかなり直観的なインターフェースかなと思ってます。見た目からもプログラムのように読めるので初見でもある程度理解できる方も多いのではないでしょうか。

処理の記述がないのでシンプル。まさに「インターフェース」ですね。

インターフェース記述言語(IDL)とは?

そういえばIDLってなんだっけ?

現状のWebプログラミングで使用されているIDLで有名なのはRESTやWSDLですね。JSONやXML形式で記述されて使われています。ことなるアプリ間でも連携するために使用されています。

RESTではなくCandid

すでに実績十分なIDLがあるのでRESTやWSDLでもよいような気がしますが、新しくCandidを開発した理由は公式ドキュメントにも書かれています。

抜粋すると

  • データだけでなくサービス内容も記述できる
  • サーバー側の型とマッピングしやすい
  • インターフェースをアップデートするルールが定義できる
  • 関数を参照にとれる

(一部REST・WSDLでもあるような気もしますが・・・)

読み取りに使用されるquery、そしてデータを更新すうるupdateに対応することができるので、インターネットコンピューターの機能をサポートするのに最適なIDLをつくった、ということでしょう。データだけではなくサービスや関数を引数にとれたりするのは面白いですね。

Candidの役割

Candid役割の一つはクライアント生成ですね。これはRESTやWSDLにも存在する機能。公開されているインターフェース仕様を読み込むことでサポートされているプログラムにクライアントを自動生成してくれます。

(例)hello.d.tsファイル

helloサンプル・プログラミングを実行してみると以下のように

.did/js/tsが生成される

declarationsディレクトリの下に.didファイル元に.d.tsと.jsファイルも生成されるので、あとはそれを利用するだけでスマートコントラクトが可能です。

Candidの使用方法

Candidは使用するプログラミング言語によって扱いが変わります。それぞれ見てみましょう。

motokoは自動生成

はい。MotokoではCandidは自動生成です。つまりやることはありません。dfx deployでキャニスターを展開するときなどに、Motokoのコードから.didファイルを生成してくれます。

RustのCandidの記述

Rustの場合はMotokoとは違い自分で記述していく必要があります。

Rustでプロジェクトを作成するとlib.rsのある階層にdidファイルも生成されます。

Rustのコードのquery,updateに合わせてdidファイルに書き込みます。

なお、declarationsディレクトリにあるdidには書かないようにしましょう。

※declarationsは別のプロジェクトが参照する先として使われるアウトプット用です。

実際の記述

具体的な書き方は公式ドキュメントに記載があるのでご確認ください。基本はここにあります。

https://smartcontracts.org/docs/current/references/candid-ref

本記事では、Rustのコードと対応する書き方について少しふれておきます。

RustとCandidの対応

インターネットコンピューターのスマートコントラクトの特徴である

  • update
  • query

を取り扱ったのち

使用頻度が高いキーワードを紹介したいと思います。

  • record
  • vec
  • variant
  • opt

前提

cargoの依存関係には次のパッケージが含まれている前提で話していきます。

  • candid
  • ic-cdk
  • ic-cdk-macros
  • serde

query

helloサンプルにもあるので引用しましょう。didファイルにはgreetが用意されています。特徴は「query」が最後にあること。


対応するrustのコードはこちら。


ic_cdk_macrosにあるqueryマクロを使えばOK。

update

つづいてupdateです。

updateはcandidではqueryを外せばOKです。


対応するrustのコードはこちら。queryからupdateに変えておきます。


メソッド名のリネーム

「name」でメソッドをリネームすることができます。query、update共通です。


rustの命名規則からCandidで公開したい外部向けの命名規則に変換できますね。

recordと構造体

構造体に対応するrecordです。まずはCandid側をみてみましょう。


recodeに対応する構造体はこちら。


derive属性にCandidTypeを入れておきます。

フィールドのリネーム

メソッド名と同じく、フィールド名もリネーム可能です。ただic_cdk_macrosではなく、使用するのは「serde」です。

vecと配列

配列に対応するのはvecです。例えばBookの配列を返すCandidがこちら。


対応するrustのコードはこちら。


rustの可変配列もVecなので、割とまんまですね。

variantと列挙型

メソッドの実行結果によってことなる型が返したい場合に使用されるのがvariantです。リクエストが不適切なときにエラーオブジェクトを返却したいときなどに使用できます。


対応するrustのコードはこちら。上記はtrueを渡せばBookが返され、falseを渡すとエラーメッセージを返すメソッドです。


variantには列挙型で対応です。

optとOption

optはNullになる可能性がある型を扱います。


対応するrustのコードはこちら。variantの例と似た形で、単にNoneを返すかBookを返すか単純なものです。


rustのOptionは列挙型なので本質的にはvariantと同じでしょうが、Nullを扱えるインターフェースは高頻出なので専用でoptが用意されています。

まとめ

Motokoが自動でRustが手動なのは気になりますが、いずれアップデートでRustも自動生成にならないかなと期待しています。

  • Candidはインターネットコンピューターで使用されるインターフェース記述言語(IDL)
  • Motoko使用時は自動生成、Rustは手動生成

つまみ食い的な記事なので、まだ取り扱っていないcandidの項目がちらほらあります。funcやらprincipal等が用意されているので折をみて、この記事で更新しようかと思います。

ちなみに、funcはdfx canister callでは動くんですけど、candid_uiで微妙な動きをしたりするので、動作確認にはまだ注意が必要です。