跳到主要内容

代码迁移:Cadence To 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 合约粘贴到 Cadence types 编辑器;保留顶层的 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 模块,不会向服务器发送任何内容。生成器是嵌入在页面脚本中的大型 WebAssembly 包(约 29 MB),首次加载可能较慢。

名称按种类加前缀: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。

规范与参考资料