news 2026/9/12 14:22:39

Sway Libraries 指南:用 library 关键字构建可复用智能合约代码

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Sway Libraries 指南:用 library 关键字构建可复用智能合约代码

Sway Libraries 指南:用 library 关键字构建可复用智能合约代码

【免费下载链接】sway🌴 Empowering everyone to build reliable and efficient smart contracts.项目地址: https://gitcode.com/GitHub_Trending/sw/sway

本篇指南聚焦 Sway 语言的四种程序类型之一——Library(库),讲解它在当前 Fuel 生态 Sway 编译器中如何定义、组织与导入。通过阅读本文,你将掌握library关键字的声明规则、mod子模块机制、内部库与外部库两种导入方式,以及标准库std和社区sway-libs参考库的实际用法,从而在自己的智能合约项目中实现真正可复用的代码设计。

什么是 Sway Library

Sway 中的库(Library)是用于定义新的通用行为的文件。与合约(Contract)、脚本(Script)和谓词(Predicate)不同,Sway 程序类型中的前三种都可以部署到区块链上,而库永远不会被直接部署到链上,它只是一个为代码复用而设计的工程。这一点在 Sway Program Types 概述 中有明确说明:每个 Sway 文件必须以声明程序类型的关键字开头;一个工程可以包含多个库,但只能有一个合约、脚本或谓词。

Sway 库最典型的代表是 Sway 标准库(Standard Library),它通过forc new创建的所有 Forc 工程隐式可用,无需任何额外配置。库最适合处理那些"常见且可复用"的逻辑,例如定点数学(fixed-point math)或大数数学(big number math)运算,正是 index.md 中给出的示例场景。

编写 Library:library 关键字与结构

在 Sway 中,库通过在文件开头使用library关键字并跟一个名称来定义,这样它就能被其他文件导入:

library; // library code

从编译器实现看,library是 Sway 解析器中的保留关键字(见 sway-parse/src/keywords.rs)。在解析模块类型时,解析器依次识别scriptcontractpredicate之后,检测librarytoken 并将模块标记为ModuleKind::Library(见 sway-parse/src/module.rs),这从源码层面印证了library;script;等声明一样,是程序类型的硬性声明。

注意:在library关键字后,实际库文件中的声明并不一定需要一个显式的库名标识(如文档示例所示,标准库的每个子库文件都以裸library;开头),库的"名称"由其所在Forc.tomlname字段决定,详见下文。

参考范例:标准库中的 Option

学习库设计的最佳参考是 Sway 标准库。以Option<T>为例,它是标准库提供的泛型枚举类型,用变体Some(..)表示值存在、用None表示值缺失。其源文件 sway-lib-std/src/option.sw 展示了库文件的标准结构:

  • library关键字——声明这是一个库文件:
library;
  • use语句——从标准库内部的另一个库导入revert
use ::logging::log; use ::result::Result; use ::revert::revert;

其中::前缀路径表示从库根开始解析,这里的revert来自sway-lib-std/src/revert.sw。从源码可以看到 option.sw 顶部正是通过use ::revert::revert;这类语句引入依赖。

  • pub enum定义——以pub关键字标记,使Option<T>option外部公开可见:
/// A type that represents an optional value, either `Some(val)` or `None`. pub enum Option<T> { /// No value. None: (), /// Some value of type `T`. Some: T, }
  • impl——为Option<T>实现方法。例如is_some用于判断是否为Some变体:
impl<T> Option<T> { pub fn is_some(self) -> bool { match self { Self::Some(_) => true, _ => false, } } // 其他方法 }

Option库完成编写后,由于Option<T>pub定义,任何 Sway 工程都可以通过use std::option::Option;导入并使用其所有变体与方法。不过正如文档强调的,Option已经包含在标准库的prelude中(见 standard_library.md 的 Standard Library Prelude 一节),因此实际上你永远不需要手动导入它。prelude 的实际定义位于 sway-lib-std/src/prelude.sw,其中明确包含pub use ::option::Option::{self, *};这一行。

库工程的 Forc.toml

与通常还包含tests目录和Cargo.toml的合约工程不同,库只由一个Forc.toml和一个src目录构成。一个典型的库Forc.toml如下:

[project] authors = ["Fuel Labs <contact@fuel.sh>"] entry = "lib.sw" license = "Apache-2.0" name = "my_library" [dependencies]

其中各个字段的含义:

  • name:库的名称,也是它被其他工程导入时使用的名称;
  • entry:库的入口文件,通常为lib.sw
  • authorslicense:工程元信息;
  • [dependencies]:库自身的外部依赖声明。

标准库本身的 sway-lib-std/Forc.toml 正是这样一个工程:name = "std"entry = "lib.sw"license = "Apache-2.0",并带有versiondescriptionkeywords等元数据,而[dependencies]为空——因为标准库不依赖任何外部库。

组织大库:lib.sw 入口与 mod 子模块

对于大型库,官方建议使用一个lib.sw入口文件,把所有子库重新导出(re-export)

mod关键字的作用是注册一个子模块,使其中的条目(如函数、结构体)可以从父库访问。若mod用在顶层,它指向src文件夹中的文件;在其他情况下,它指向以该库命名的文件夹中的文件。

标准库的 sway-lib-std/src/lib.sw 就是这种组织方式的典范,其真实结构如下:

library; pub mod marker; pub mod registers; pub mod flags; pub mod r#str; pub mod primitives; pub mod ops; pub mod raw_ptr; pub mod raw_slice; pub mod slice; pub mod error_signals; pub mod codec; pub mod debug; pub mod constants; pub mod logging; pub mod revert; pub mod assert; pub mod convert; pub mod time; pub mod intrinsics; pub mod iterator; pub mod vec; pub mod bytes; pub mod alloc; pub mod result; pub mod option; pub mod never; pub mod b512; pub mod u128; pub mod primitive_conversions; pub mod math; pub mod alias; pub mod hash; pub mod asset_id; pub mod contract_id; pub mod execution; pub mod call_frames; pub mod context; pub mod external; pub mod tx; pub mod outputs; pub mod address; pub mod identity; pub mod ecr; pub mod vm; pub mod crypto; pub mod string; pub mod r#storage; pub mod block; pub mod inputs; pub mod auth; pub mod asset; pub mod message; pub mod prelude; pub mod low_level_call; pub mod array_conversions; pub mod bytes_conversions; pub mod clone;

注意其中pub mod的写法——这里的pub修饰符让这些子模块对标准库外部也可见,这也是 lib.sw 与文档中简化的mod block; mod storage;示例的差异所在。

lib.sw并列的其他库文件直接放在src文件夹中,比如vm库位于src/vm.sw;而vm库自身又可以有自己的子库evm,位于src/vm/evm.sw。即形成这样的层级:

// src/vm.sw library; mod evm; // ...
// src/vm/evm.sw library; // ...

这正好体现了文档中所说的规则:vm.sw中的顶层mod evm;指向src/vm/文件夹下的evm.sw

使用 Libraries:内部库与外部库

Sway 库根据其位置和导入方式分为两种类型。

内部库(Internal Libraries)

内部库位于工程src目录内,与main.sw同级,或位于src下按规则组织的文件夹中:

$ tree . ├── Cargo.toml ├── Forc.toml └── src ├── internal_lib.sw ├── main.sw └── internal_lib └── nested_lib.sw

由于internal_lib是内部库,在main.sw中导入它需要两步:

  1. mod关键字加上库名,将内部库注册为依赖;
  2. use关键字,以::分隔库名与要导入的条目。
mod internal_lib; // 假设 internal_lib.sw 中的库名为 internal_lib use internal_lib::mint; // 现在本文件中可以直接使用 internal_lib 的 `mint`

外部库(External Libraries)

外部库位于主工程src目录之外,典型目录结构如下:

$ tree . ├── my_project │ ├── Cargo.toml │ ├── Forc.toml │ └─── src │ └── main.sw │ └── external_lib ├── Cargo.toml ├── Forc.toml └─── src └── lib.sw

由于external_libmy_projectsrc目录之外,必须先把它加入my_projectForc.tomldependencies段,通过路径指定依赖,然后才能导入:

[dependencies] external_library = { path = "../external_library" }

依赖添加完成后,按以下两步导入其中的条目:

  1. 确保想导入的条目以pub关键字声明(例如pub fn mint() {});
  2. use关键字选择性导入条目。
use external_library::mint; // 现在本文件中可以直接使用 external_library 的 `mint`

通配符导入:Sway 支持使用*的通配符导入(如use external_library::*;),但文档明确建议尽量使用显式导入,以保持命名空间的清晰。标准库 prelude 本身就是通配符导入的典型应用场景(如 prelude.sw 中的pub use ::storage::storage_key::*;)。

注意:标准库对所有 Forc 工程是隐式可用的,你无需在Forc.toml中手动把std声明为显式依赖。Forc 会自动使用与自身版本匹配的std版本(详见 standard_library.md)。

导入机制的实际验证

仓库中的端到端测试程序为内部库导入提供了真实佐证。例如aliased_imports测试工程中的 foo.sw 和 wiz.sw 都以library;开头声明为库文件,并被主文件通过mod/use机制引用,验证了库文件的导入路径在真实编译流程中是成立的。

参考 Sway 库(sway-libs)

仓库文档提到,sway-libs是一个外部库集合,专为 Fuel 应用开发中常见的 dapp 场景提供开箱即用的实现。几个值得尝试的 Sway 库包括:

  • Binary Merkle Proof:二进制 Merkle 证明实现;
  • Signed Integers:有符号整数实现;
  • Ownership:所有权管理实现。

示例:导入 Ownership 库

Sway 库可以像任何其他外部库一样被导入。以Ownership库为例:

use ownership::Ownership;

导入后,即可在智能合约中使用该库提供的以下基础功能:

  • 声明所有者(declaring an owner)
  • 变更所有权(changing ownership)
  • 放弃所有权(renouncing ownership)
  • 确保某个函数只能由所有者调用(ensuring a function may only be called by the owner)

这类库正体现了 Sway 库设计的核心价值:把 dapp 开发中的通用权限逻辑封装为可复用、可审计的共享代码,避免每个合约重复实现。

总结

Sway 的 Library 程序类型是构建可复用智能合约代码的基础设施:

  1. 定义:任何.sw文件都以library;开头即成为库文件,配合Forc.toml中的nameentry字段确定其身份;
  2. 组织:大型库通过lib.sw入口配合mod关键字注册子模块,pub mod控制对外可见性,形成src文件夹与同名子文件夹两级结构;
  3. 导入:内部库通过mod+use组合引用,外部库需要在Forc.toml[dependencies]中以路径声明,随后用use显式导入(必要时使用*通配符);
  4. 生态:标准库std隐式可用且自带 prelude,社区sway-libs则提供了 Merkle 证明、有符号整数、所有权等开箱即用的参考实现。

掌握这些机制,你就能像标准库 sway-lib-std 一样,把通用逻辑沉淀为可复用的 Sway 库,让智能合约代码更可靠、更高效。

【免费下载链接】sway🌴 Empowering everyone to build reliable and efficient smart contracts.项目地址: https://gitcode.com/GitHub_Trending/sw/sway

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/12 14:22:12

在 Apple Silicon 上高效部署本地大模型:self-llm 项目 MLX-LM 实战指南

在 Apple Silicon 上高效部署本地大模型&#xff1a;self-llm 项目 MLX-LM 实战指南 【免费下载链接】self-llm 《开源大模型食用指南》针对中国宝宝量身打造的基于Linux环境快速微调&#xff08;全参数/Lora&#xff09;、部署国内外开源大模型&#xff08;LLM&#xff09;/多…

作者头像 李华
网站建设 2026/9/12 14:21:21

告别EasyExcel:Apache Fesod如何搞定复杂表头与嵌套列表

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/12 14:20:56

Spring AI (第三章) 自定义拦截器+系统提示词(基础总结)

Spring AI (第三章) 自定义拦截器系统提示词&#xff08;基础总结&#xff09; 文章目录Spring AI (第三章) 自定义拦截器系统提示词&#xff08;基础总结&#xff09;一、章节目的二、拦截器2.1 拦截器是什么2.2 拦截器的作用三、常见内置实现类&#xff08;Spring AI 已经帮你…

作者头像 李华
网站建设 2026/9/12 14:19:14

SpringCloud+Vue构建考研资料商城的架构设计与实践

1. 项目概述与背景考研学习资料商城信息服务平台是一个典型的互联网教育类应用&#xff0c;采用前后端分离架构设计。后端基于SpringBootSpringCloud微服务技术栈构建分布式系统&#xff0c;前端使用Vue.js框架实现响应式用户界面。这种技术组合在当前企业级应用开发中已成为主…

作者头像 李华