部署 Cadence 合约
我们在 FCL demo 中也看到了有部署合约的例子,这个文件里定义了用户需要部署的合约脚本,使用 @onflow/six-set-code
组装部署脚本的交易体:
// examples/react-fcl-demo/hide/demo/DeployContract.tsx const simpleContract = ` pub contract HelloWorld { pub let greeting: String pub event HelloEvent(message: String) init() { self.greeting = "Hello, World!" } pub fun hello(message: String): String { emit HelloEvent(message: message) return self.greeting } } ` const result = await Send(simpleContract) // fcl-deployer.ts // examples/react-fcl-demo/hide/helper/fcl-deployer.ts import * as fcl from "@onflow/fcl" import { template as setCode } from "@onflow/six-set-code" export async function Send(code: string) { const response = await fcl.send([ setCode({ proposer: fcl.currentUser().authorization, authorization: fcl.currentUser().authorization, payer: fcl.currentUser().authorization, code: code, }) ]) try { return await fcl.tx(response).onceExecuted() } catch (error) { return error; } }
这里我们看到 setCode
函数将当前授权用户的授权信息与 code 一起传入
-
Proposer —— 交易发起人
-
Authorization —— 授权人
-
Payer —— 费用支付人
-
code —— 需要部署的合约代码
这里将三种角色都设置为当前登录的用户,我们来看看 setCode
内部的实现:
// packages/six-set-code/hide/six-set-code.js import * as sdk from "@onflow/sdk" import * as t from "@onflow/types" // 定义默认的常量参数 export const TITLE = "Set Account Code" export const DESCRIPTION = "Set an Account Code on Flow with given code." export const VERSION = "0.0.0" export const HASH = "7375dc3feb96e2f8061eff548220a96bf77ceb17affd1ac113f10d15411a92c4" // 部署账户代码的脚本,也是 cadence 语法,当前的版本已经旧了,现在使用的 acct.setCode 已经被替换为 // acct.contracts.add(name: "HelloWorld", code: code.decodeHex()) export const CODE = `transaction(code: String) { prepare(acct: AuthAccount) { acct.contracts.add(name: "HelloWorld", code: code.decodeHex()) } }` // 这里的函数我添加了一个折中方案,将部署脚本也作为参数传入 export const template = ({ proposer, authorization, payer, code = "", deployScript = CODE }) => sdk.pipe([ sdk.transaction(deployScript), sdk.args([sdk.arg(Buffer.from(code, "utf8").toString("hex"), t.String)]), // 这里对 code 进行了编码与类型指定操作 sdk.proposer(proposer), sdk.authorizations([authorization]), sdk.payer(payer), sdk.validator((ix, {Ok, Bad}) => { // 添加了验证的逻辑,要求 template 类型的交易只能有一个授权 if (ix.authorizations.length > 1) ret