2022-05-22Candidとはなんなんでしょう。試しにインターネットコンピューターでプログラミングをしてみようと思っている方向けの記事です。Candidはインターネットコンピューターの言語の一つとして紹介されていますがRustやMotokoとの役割の違いについて触れ、実際の使われ方を紹介していきます。Candidはインターフェース記述言語(IDL)としてインターネットコンピューターに用意されました。MotokoとRustはプログラミング言語として使われているのとは異なりますね。Candidの使われ方としてはMotokoとCandid、RustとCandid組み合わせで使っていきます。ちなみに拡張子は.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は自動生成です。やることはありません。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の対応インターネットコンピューターのスマートコントラクトの特徴であるupdatequeryを取り扱ったのち使用頻度が高いキーワードを紹介したいと思います。recordvecvariantopt前提cargoの依存関係には次のパッケージが含まれている前提で話していきます。candidic-cdkic-cdk-macrosserdequeryhelloサンプルにもあるので引用しましょう。didファイルにはgreetが用意されています。特徴は「query」が最後にあること。対応するrustのコードはこちら。ic_cdk_macrosにあるqueryマクロを使えばOK。updateつづいてupdateです。updateはcandidではqueryを外せばOKです。対応するrustのコードはこちら。queryからupdateに変えておきます。メソッド名のリネーム「name」でメソッドをリネームすることができます。query、update共通です。rustの命名規則からCandidで公開したい外部向けの命名規則に変換できますね。構造体に対応するrecordです。Candid側をみてみましょう。recodeに対応する構造体はこちら。derive属性にCandidTypeを入れておきます。フィールドのリネームメソッド名と同じく、フィールド名もリネーム可能です。ic_cdk_macrosではなく、使用するのは「serde」です。配列に対応するのはvecです。Bookの配列を返すCandidがこちら。対応するrustのコードはこちら。rustの可変配列もVecなので、割とまんまですね。variantと列挙型メソッドの実行結果によってことなる型が返したい場合に使用されるのがvariantです。リクエストが不適切なときにエラーオブジェクトを返却したいときなどに使用できます。対応するrustのコードはこちら。上記はtrueを渡せばBookが返され、falseを渡すとエラーメッセージを返すメソッドです。variantには列挙型で対応です。optとOptionoptはNullになる可能性がある型を扱います。対応するrustのコードはこちら。variantの例と似た形で、単にNoneを返すかBookを返すか単純なものです。rustのOptionは列挙型なので本質的にはvariantと同じでしょうが、Nullを扱えるインターフェースは高頻出なので専用でoptが用意されています。まとめMotokoが自動でRustが手動なのは気になりますが、いずれアップデートでRustも自動生成にならないかなと期待しています。Candidはインターネットコンピューターで使用されるインターフェース記述言語(IDL)Motoko使用時は自動生成、Rustは手動生成つまみ食い的な記事なので、まだ取り扱っていないcandidの項目がちらほらあります。funcやらprincipal等が用意されているので折をみて、この記事で更新しようかと思います。callでは動くんですけど、candid_uiで微妙な動きをしたりするので、動作確認にはまだ注意が必要です。