本文へスキップ

CadenceからGoコードへの変換器 — Numio

WebAssembly にコンパイルした easi-gen を使って、Flow の Cadence コントラクトにある struct、resource、event から Go の struct を生成します。フィールドには godence エンコーダー用の `godence:"..."` タグが付き、String? などのオプショナル型は対応する通常の Go 型になります。

flow-go-sdk と godence を使う Go バックエンドで、Flow ブロックチェーンのスクリプト結果やコントラクトのイベントをデコードする。

Cadence types

Go types

こんなときに使えます

  • flow-go-sdk と godence を使う Go バックエンドで、Flow ブロックチェーンのスクリプト結果やコントラクトのイベントをデコードする。
  • スクリプトを手書きする代わりに、コントラクトの公開関数に対するクエリ関数付きの型付き Go クライアントを生成する。

使い方

  1. Cadence types エディターに Cadence コントラクトを貼り付けます。トップレベルの pub contract ブロックは残してください。コントラクト外の struct は受け付けられません。
  2. 必要に応じて Output Settings を開き、"Generate Interaction Code With Functions" をオンにすると、package ヘッダー、インポート、ContractX 型、pub fun ごとの Go メソッドも生成されます。
  3. Go types パネルをプロジェクトにコピーし、godence のインポートを追加します。フィールドが *big.Int を使う場合、import "math/big" は自動で追加されます。

Cadence コントラクト

pub contract Marketplace {
  pub struct Listing {
    pub let id: UInt64
    pub let seller: Address
    pub var price: UFix64
    pub var tags: [String]
    pub var meta: {String: String}
    pub var note: String?

    init() { self.id = 0; self.seller = 0x01; self.price = 0.0; self.tags = []; self.meta = {}; self.note = nil }
  }

  pub event Sold(id: UInt64, buyer: Address)
}

Go struct

type StructListing struct {
	Id     uint64            `godence:"id"`
	Seller string            `godence:"seller"`
	Price  uint64            `godence:"price"`
	Tags   []string          `godence:"tags"`
	Meta   map[string]string `godence:"meta"`
	Note   string            `godence:"note"`
}

type EventSold struct {
	Id    uint64 `godence:"id"`
	Buyer string `godence:"buyer"`
}

仕様と制限

生成はすべてブラウザー内で行われます。ページは easi-gen の WebAssembly モジュールを読み込み、サーバーには何も送信しません。ジェネレーターはページのスクリプトに埋め込まれた大きな(約 29 MB の)WebAssembly バンドルなので、初回の読み込みに時間がかかることがあります。

名前には種類に応じたプレフィックスが付きます: StructListing、ResourceNFT、EventSold。フィールド名は先頭が大文字になり、元の Cadence の名前は godence タグに残ります。

実際の型マッピング: UInt64 → uint64、Int8 → int8、Int → *big.Int、UFix64 → uint64、Fix64 → int64、Address → string、[T;2] → [2]T、{K:V} → map[K]V。

デフォルト設定では型宣言だけが生成され、package 行はなく、pub fun の本体は無視されます。追加されるインポートは、Int フィールドに *big.Int が必要なときの "math/big" だけです。

FAQ

"no top level contract found" と表示されるのはなぜですか?

ジェネレーターは pub contract 内の宣言しか読まないため、単独の struct はこのエラーになります。エディターのデフォルトのサンプルのように、pub contract Example { ... } などのコントラクトブロックで囲んでください。

オプショナル型はどう扱われますか?

オプショナルの記号は取り除かれます。String? は string になり、Listing? を返す関数は StructListing にマッピングされます。nil の結果はゼロ値にデコードされるため、値の欠落は自分で確認してください。

"Generate Interaction Code With Functions" で何が追加されますか?

package 行と import 行、コントラクトのアドレスを確認するコンストラクター付きの ContractName 型、そして公開関数ごとのメソッドが追加されます。各メソッドは Cadence スクリプトを組み立て、ExecuteScriptAtLatestBlock を実行し、結果を godence でデコードします。

ネストした struct や多次元配列に対応していますか?

対応しています。別の struct の中で宣言された struct は独立した Go の型になり、[[String]] は [][]string に、ネストした辞書は map[string]map[string]string のようなネストした map になります。

仕様を確認する