资讯详情

资讯详情

Sway 谓词(Predicate)完整指南:无需部署、以代码为钥的资产所有权程序

Sway 谓词Predicate完整指南无需部署、以代码为钥的资产所有权程序【免费下载链接】sway Empowering everyone to build reliable and efficient smart contracts.项目地址: https://gitcode.com/GitHub_Trending/sw/sway导读在 Sway 语言中谓词Predicate是一种以“代码即密钥”为核心的轻量程序类型它不访问合约存储、不需要部署上链仅在交易执行期间存在并在求值为true时代表对链上 UTXO 资源的所有权。本文以 Sway 官方文档《Predicates》 为主体结合当前仓库Sway 编译器与 Forc 工具链的源码与端到端测试用例系统讲解谓词的定义、地址生成、转账与花费流程、花费条件以及编译器为谓词施加的约束帮助你理解并上手编写自己的谓词。什么是谓词从 Sway 的视角看谓词是“返回布尔值的程序”并且在执行结果为true时代表对某些资源的所有权。它与合约Contract、脚本Script并列同属 Sway 的四类程序之一其余为合约、脚本、库详见 Sway 程序类型总览。与合约最本质的区别在于谓词没有任何对合约存储storage的访问权限它不能读写任何持久化状态。以下是一个最简单的谓词它恒为truepredicate; // 所有谓词都必须提供一个返回布尔值的 main 函数。 fn main() - bool { true }这个例子的实现同样存在于仓库的端到端测试中见 basic_predicate/src/main.sw其测试期望运行后返回值为 1即true见同目录下的 test.toml。谓词的地址就是字节码根bytecode root上述谓词的地址为0xd19a5fe4cb9baf41ad9813f1a6fef551107c8e8e3f499a6e32bccbb954a74764。任何发送到该地址的资产都可以通过执行上面的谓词来解锁或领取因为它恒为true。这个地址并不是随机生成的账户地址而是谓词字节码的根bytecode root。在仓库的包构建逻辑中这一计算发生在 forc-pkg/src/pkg.rs对于TreeType::PredicateForc 会调用fuel_tx::Input::predicate_owner(self.bytecode.bytes)计算根哈希将其以十六进制形式写入输出目录下名为包名-bin-root的文件后缀常量SWAY_BIN_ROOT_SUFFIX定义在 forc-pkg/src/pkg.rs。也就是说只要字节码确定谓词地址就确定任何人都可以离线计算出它。无需部署却拥有链上地址谓词不需要部署到区块链因为它只存在于一笔交易期间。但谓词地址本身会在链上作为一笔或多笔 UTXO 的所有者存在。这是谓词区别于合约的关键点之一合约需要部署、有持久化状态谓词则是“用完即走”的临时程序链上唯一与它相关的痕迹是它所拥有的 UTXO。向谓词转账在 Fuel 网络中代币可以发送到谓词的地址即上述字节码根。由于谓词地址是一个普通地址转账动作本身与向任何地址转账无异——用户只需把资产发往谓词地址即可。此时链上会形成由该谓词地址所有的 UTXO等待后续被条件满足的交易所花费。花费谓词资产与常规账户不同花费谓词名下的 coin UTXO不需要提供有效签名而是必须同时满足两个条件提供的谓词字节码的根root与 UTXO 的所有者匹配该谓词在交易上下文中求值为true。如果谓词发生回滚revert或试图访问不纯净impure的 VM 操作码则求值结果自动为false资产无法释放。仓库中恰好有一个专门展示这些非法情况的测试 predicate_invalid_opcodes/src/main.sw它在谓词体内以内联汇编方式使用了bal、bhei、bhsh、burn、call、cb、ccp、croo、csiz、gm、log、logd、mint、smo、time、tr、tro等操作码这些属于不纯净操作码在谓词中是不被允许的。测试注释还指出retd无法测试、rvrt被允许且专门用于中止谓词而存储类操作码srw、srwq、sww、swwq由于需要给main标注#[storage(read, write)]该标注本身对谓词就是非法的而无法测试。一个直观的类比代码即私钥传统的 12 或 24 个助记词会派生出一个私钥私钥用于生成有效签名类比之下谓词的代码本身就可以被看作私钥。任何人只要拥有这段代码都可以执行谓词但只有在谓词求值为true时该地址名下的资产才会被释放。因此“密钥”不是一段保密的数字而是一段公开可验证、可编程的判定逻辑——这正是谓词实现条件化资产控制的根基。花费条件可编程的解锁逻辑谓词真正的威力在于它可以检查正在花费其代币的那笔交易并可能接收运行时参数runtime arguments二者都可能影响谓词的求值结果。具体而言谓词可以检查交易的输入inputs、输出outputs、脚本字节码script bytecode等谓词可以声明带参数的main函数由花费方在交易中传入运行时参数需要特别强调的是谓词不能读写内存但它可以检查交易的输入与输出。一个典型的例子是 OTC场外交易交换谓词用户指定希望用asset1换取asset2数量为5然后把自己的asset1发送给谓词。只有当谓词能够验证交易输出中确实有5枚asset2被发送回原始用户时asset1才被允许转出谓词。这样谓词充当了一个无需信任中间人的“托管条件机”。仓库中的 main_args_predicate/src/main.sw 展示了带运行时参数的谓词predicate; fn main(baba: u64, keke: u64) - bool { let sum baba keke; sum 1337 }这个谓词接受两个u64参数只有二者之和等于1337时才求值为true。它证明了谓词可以接收外部传入的参数并将参数参与判断逻辑——解锁条件因此可以做到任意复杂。编译器对谓词的硬性约束源码级验证谓词的诸多限制并非约定俗成而是由编译器强制执行的。在 sway-core/src/language/ty/program.rs 的类型检查阶段TreeType::Predicate会依次被校验必须存在且只能有一个main函数没有main会报NoPredicateMainFunction多于一个会报MultipleDefinitionsOfFunctionmain不得包含ref mut参数经由check_no_ref_main检查main的返回类型必须是bool否则报PredicateMainDoesNotReturnBool。此外sway-core/src/language/ty/program.rs 中的disallow_impure_functions会遍历谓词内所有函数声明含main凡是纯度purity不是Pure的函数一律报ImpureInNonContract错误。这从编译器层面保证了谓词体内不存在任何不纯净操作如访问存储。对存储的限制同样有测试佐证storage_in_predicate/src/main.sw 直接在谓词中声明storage块编译器会报出“Declaring storage in a predicate is not allowed”错误predicate_calls_impure/src/main.sw 则在谓词中给函数标注#[storage(read, write)]同样被拒绝。用 Forc 构建与查看谓词根项目形态谓词项目以predicate;作为文件首行声明程序类型枚举见 sway-core/src/language/parsed/program.rs。项目清单Forc.toml与普通 Sway 项目一致例如 basic_predicate 的 Forc.toml 中通过entry main.sw指定入口文件。也可以用命令快速初始化forc init --path PATH --predicate初始化带谓词目标的工程见 forc/src/cli/commands/init.rsforc new PATH --predicate新建一个空的谓词工程见 forc/src/cli/commands/new.rs。构建输出forc build对谓词项目的输出与脚本、合约不同见 forc/src/cli/commands/build.rs 的文档说明谓词项目会像脚本、合约一样产出二进制字节码文件项目名.bin额外产出一个包含字节码根哈希的文件项目名-bin-root这个根就是谓词地址十六进制形式前缀0x。专用命令forc predicate-root工具链还提供了专用于谓词的命令forc predicate-root见 forc/src/cli/commands/predicate_root.rs其作用是“计算谓词的 predicate-root对于工作区则输出工作区内所有谓词的根”。其实现位于 forc/src/ops/forc_predicate_root.rs构建选项使用了pkg::MemberFilter::only_predicates()——该过滤器保证只构建谓词类型的成员其余类型一律跳过forc-pkg/src/pkg.rs然后复用常规构建流程在构建过程中打印并落盘每个谓词的根。也就是说无论你是想验证某个谓词地址还是想在工作区中批量获取多个谓词地址forc predicate-root都是最直接的入口。小结谓词是 Sway 中极具特色的一类程序它没有存储、无需部署、以字节码根为链上地址以“根匹配 求值为true”替代签名来完成资产花费并允许通过检查交易输入输出和接收运行时参数来实现任意复杂的解锁条件。从仓库源码可以看到编译器和工具链为这一模型提供了完整的支撑——强制的main签名约束、纯函数限制、存储禁令以及-bin-root产物和forc predicate-root命令。如果你想进一步探索推荐继续阅读 Sway 程序类型总览并对照仓库中 should_pass/language 与 should_fail 目录下的谓词测试用例动手验证。【免费下载链接】sway Empowering everyone to build reliable and efficient smart contracts.项目地址: https://gitcode.com/GitHub_Trending/sw/sway创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
觉得有用,分享给同行:

为您的企业打造数字门面

稳重轻奢商务风格,端正雅致视觉,长效耐看不易过时。

立即咨询 →