{"author":{"address":"0xbdd3203FeD7bC268DC76BFF731E78C73f76053C1","user":"https://learnblockchain.cn/people/17384"},"content":{"body":"# 前言\r\n\r\nSui 区块链是一种高性能的 Layer 1 区块链，它采用了 Move 语言进行智能合约开发。Move 是一种资源导向型编程语言，以安全性和灵活性为核心理念。在 Sui 中，方法的定义和调用具有一定的规则，同时 init 方法作为特殊的初始化逻辑，也有着固定的调用形式和重要意义。本文将详细讲解 Sui Move 方法的定义、调用范围以及 init 方法的用法。\r\n![image.png](https://img.learnblockchain.cn/attachments/2024/12/hTtY8mF7675ad5aed970c.png)\r\n\r\n---\r\n# Move 共学活动：快速上手 Move 开发\r\n为了帮助更多开发者快速了解和掌握 Move 编程语言，**Move 共学**活动由 **HOH 社区**、**HackQuest**、**OpenBuild**、**KeyMap** 联合发起。该活动旨在为新手小白提供一个良好的学习平台，带领大家一步步熟悉 Move 语言，并了解如何将其应用到 Web3 开发中。\r\n\r\n通过与 Move 领域的专业导师们合作，参与者可以快速掌握 Move 语言的基础知识，逐步向更复杂的应用开发进阶。无论是区块链初学者，还是有一定开发经验的工程师，都能从中获益。\r\n\r\n**资源链接：**\r\n- [sui官方文档🚪](https://docs.sui.io/)：获取关于 Sui 链的详细文档，包括开发指南、API 参考等。\r\n- [move学习B站视频🚪](https://www.bilibili.com/video/BV1BMD8Y2EfE/)：通过 B 站的视频教程，跟随导师学习 Move 编程语言的基础与进阶。\r\n- [letsmove仓库🚪](https://github.com/move-cn/letsmove)：这是一个 Move 学习资源的 GitHub 仓库，包含了各种示例代码和教程，帮助开发者掌握 Move 语言。\r\n\r\n\r\n---\r\n\r\n# 一、Move 方法的定义与使用\r\n\r\n在 Move 中，方法的签名通常以 `fun` 关键字开头，其访问修饰符和调用范围严格控制着方法的使用权限。Move 的设计初衷是通过这种严格的控制，保障模块的安全性和代码逻辑的封装性。根据方法签名的不同，调用范围与返回值可能会有所区别。\r\n\r\n以下是 Move 中常见方法定义的签名及其含义：\r\n\r\n| 方法签名                         | 调用范围                   | 返回值 |\r\n| ---------------------------- | ---------------------- | --- |\r\n| `fun call()`                 | 只能模块内调用                | 可以有 |\r\n| `public fun call()`          | 全部合约均能调用               | 可以有 |\r\n| `public entry fun call()`    | 全部合约和 DApp（通过 RPC）均能调用 | 无   |\r\n| `entry fun call()`           | 只能通过 DApp（RPC）调用       | 无   |\r\n| `public(package) fun call()` | 只能当前的模块能调用             | 可以有 |\r\n\r\n\u003e **提示**：调用范围的设计反映了 Move 的安全性理念，例如 `entry fun` 限制只能由外部调用，防止内部逻辑无意中调用关键方法。\r\n\r\n## 1.1 `fun` 方法\r\n\r\n`fun` 方法是最基本的定义方式，这类方法只能在模块内部调用，适用于模块内部的辅助逻辑。例如：\r\n\r\n```\r\nmodule Example {\r\n    fun internal_helper(x: u64): u64 {\r\n        x + 1\r\n    }\r\n}\r\n```\r\n\r\n## 1.2 `public fun` 方法\r\n\r\n`public fun` 方法允许跨模块调用，适合需要被其他模块或合约调用的通用逻辑。例如：\r\n\r\n```\r\nmodule Example {\r\n    public fun add_two_numbers(x: u64, y: u64): u64 {\r\n        x + y\r\n    }\r\n}\r\n```\r\n\r\n## 1.3 `public entry fun` 方法\r\n\r\n`public entry fun` 方法不仅可以被其他模块调用，还可以通过 RPC 被外部 DApp 调用，适合需要对外提供接口的场景。需要注意，这类方法不能有返回值。例如：\r\n\r\n```\r\nmodule Example {\r\n    public entry fun mint(ctx: \u0026mut TxContext) {\r\n        // 铸造逻辑\r\n    }\r\n}\r\n```\r\n\r\n## 1.4 `entry fun` 方法\r\n\r\n`entry fun` 方法只能通过 RPC 被外部调用，且不能被模块内部或其他模块直接调用。它的主要用途是定义与外部交互的特定逻辑。例如：\r\n\r\n```\r\nmodule Example {\r\n    entry fun buy(ctx: \u0026mut TxContext) {\r\n        // 购买逻辑\r\n    }\r\n}\r\n```\r\n\r\n## 1.5 `public(package) fun` 方法\r\n\r\n这种方法签名限制了方法只能在当前模块中调用，但调用权限可以由模块开发者灵活控制。例如：\r\n\r\n```\r\nmodule Example {\r\n    public(package) fun internal_logic() {\r\n        // 内部逻辑\r\n    }\r\n}\r\n```\r\n\r\n\u003e **补充**：对于复杂模块，`public(package)` 方法可以结合模块的辅助功能，使其在内部被高效调用，同时避免暴露不必要的接口。\r\n\r\n# 二、Move 语言中的 `init` 方法\r\n\r\n在 Move 中，`init` 方法是合约模块的初始化逻辑。`init` 方法只能定义为私有，且会在合约部署时自动调用一次，完成模块的初始设置。\r\n\r\n## 2.1 `init` 方法的定义形式\r\n\r\n`init` 方法有两种形式：\r\n\r\n1. `fun init(ctx: \u0026mut TxContext)`\r\n2. `fun init(witness: Struct, ctx: \u0026mut TxContext)`\r\n\r\n### 示例 1：基本的 `init` 方法\r\n\r\n```\r\nmodule Example {\r\n    use sui::tx_context::TxContext;\r\n\r\n    fun init(ctx: \u0026mut TxContext) {\r\n        // 初始化逻辑\r\n    }\r\n}\r\n```\r\n\r\n### 示例 2：带有 `witness` 参数的 `init` 方法\r\n\r\n```\r\nmodule Example {\r\n    use sui::tx_context::TxContext;\r\n\r\n    struct Witness {\r\n        field: u64,\r\n    }\r\n\r\n    fun init(witness: Witness, ctx: \u0026mut TxContext) {\r\n        // 使用 witness 完成初始化逻辑\r\n    }\r\n}\r\n```\r\n\r\n## 2.2 `init` 方法的特点\r\n\r\n* **只能定义为私有**：`init` 方法不需要显式调用，它由 Sui 系统在合约发布时自动执行。\r\n* **自动调用**：当模块被部署到链上时，`init` 方法会被调用一次，用于完成模块的初始化设置。\r\n* **初始化上下文**：`ctx` 参数提供了交易上下文，允许方法执行与 Sui 系统交互的操作。\r\n\r\n## 2.3 使用场景\r\n\r\n`init` 方法常用于：\r\n\r\n* 初始化全局配置或状态。\r\n* 创建模块需要的资源。\r\n* 注册必要的事件。\r\n\r\n例如，一个简单的计数器模块可能会在 `init` 方法中创建初始的计数值：\r\n\r\n```\r\nmodule Counter {\r\n    use sui::tx_context::TxContext;\r\n\r\n    struct Counter {\r\n        value: u64,\r\n    }\r\n\r\n    fun init(ctx: \u0026mut TxContext) {\r\n        let counter = Counter { value: 0 };\r\n        ctx.save(counter);\r\n    }\r\n}\r\n```\r\n\r\n\u003e **扩展**：在实际开发中，开发者可以通过 `init` 方法引入模块的默认行为，例如注册默认的权限模型或者初始化模块的元数据。\r\n\r\n# 三、总结\r\n\r\nSui Move 语言中方法的定义和调用范围通过签名进行严格控制，开发者需要根据业务需求选择合适的签名类型。与此同时，`init` 方法作为模块的初始化逻辑，发挥了重要作用。通过本文的讲解，相信大家能够更好地理解 Sui Move 方法的用法，并灵活应用于实际开发中。\r\n\r\n在使用 Move 的过程中，以下几点建议尤为重要：\r\n\r\n* 根据模块的需求选择合适的调用范围，避免不必要的权限暴露。\r\n* 善用 `init` 方法完成模块的初始化逻辑，确保资源和状态的完整性。\r\n* 对外提供的方法应加入详细的文档和注释，方便模块的维护与迭代。\r\n\r\n未来，随着 Sui 区块链生态的发展，Move 语言的功能和设计模式可能会进一步丰富和优化。例如，可能会引入更加灵活的模块化机制或更安全的权限管理模型。期待大家能在探索中不断提升开发能力，与社区共同推动生态的繁荣！","title":"深入了解 Sui 区块链 Move 语言中的方法与 init 方法"},"history":null,"timestamp":1734015708,"version":1}