MultiversX智能合约项目架构设计技能Skill multiversx-project-architecture

此技能专注于 MultiversX 区块链智能合约的项目架构设计,提供生产级别的文件夹结构、模块组合模式和开发最佳实践。适用于开始新项目、重构现有合约或构建多合约系统,提高开发效率和代码可维护性。关键词:MultiversX, 智能合约, 项目架构, 区块链开发, 模块化设计, 智能合约开发, 生产级结构, 多合约系统。

智能合约 0 次安装 0 次浏览 更新于 3/21/2026

name: multiversx-project-architecture description: MultiversX 智能合约的生产级项目结构模式。用于开始新的合约项目、重构现有项目或构建具有共享代码的多合约系统。

MultiversX 项目架构

MultiversX 合约的生产测试文件夹结构和模块组合模式。

单合约结构

对于业务逻辑约 1000 行的合约:

my-contract/
├── Cargo.toml
├── src/
│   ├── lib.rs              # #[contract] trait — 仅包含特质组合 + 初始化/升级
│   ├── storage.rs           # 所有 #[storage_mapper] 定义
│   ├── views.rs             # 所有 #[view] 端点
│   ├── config.rs            # 管理员配置端点
│   ├── events.rs            # #[event] 定义
│   ├── validation.rs        # 输入验证辅助函数
│   ├── errors.rs            # 静态错误常量
│   └── helpers.rs           # 纯业务逻辑函数
├── meta/
│   ├── Cargo.toml
│   └── src/main.rs
├── wasm/
│   ├── Cargo.toml
│   └── src/lib.rs
└── tests/
    └── integration_test.rs

多合约工作空间结构

对于具有多个交互合约的协议:

my-protocol/
├── Cargo.toml               # [workspace] 成员
├── common/                   # 所有合约共享的crate
│   ├── Cargo.toml
│   ├── constants/
│   │   ├── Cargo.toml
│   │   └── src/lib.rs       # 协议范围内的常量
│   ├── errors/
│   │   ├── Cargo.toml
│   │   └── src/lib.rs       # 共享错误常量
│   ├── structs/
│   │   ├── Cargo.toml
│   │   └── src/lib.rs       # 共享数据类型
│   ├── math/
│   │   ├── Cargo.toml
│   │   └── src/math.rs      # 共享数学模块特质
│   └── events/
│       ├── Cargo.toml
│       └── src/lib.rs       # 共享事件定义
├── contract-a/               # 第一个合约
│   ├── Cargo.toml
│   ├── src/
│   │   ├── lib.rs
│   │   ├── storage/
│   │   │   └── mod.rs        # 本地 + 代理存储
│   │   ├── cache/
│   │   │   └── mod.rs        # 基于Drop的缓存
│   │   ├── views.rs
│   │   ├── config.rs
│   │   ├── events.rs
│   │   ├── validation.rs
│   │   └── helpers/
│   │       └── mod.rs
│   ├── meta/
│   ├── wasm/
│   └── tests/
├── contract-b/
│   └── ...                   # 相同结构
└── proxy-definitions/        # 可选:共享代理特质
    ├── Cargo.toml
    └── src/lib.rs

lib.rs 模式:仅特质组合

主合约文件应仅组合模块 — 无业务逻辑:

#![no_std]

multiversx_sc::imports!();

pub mod cache;
pub mod config;
pub mod events;
pub mod helpers;
pub mod storage;
pub mod validation;
pub mod views;

#[multiversx_sc::contract]
pub trait MyContract:
    storage::StorageModule
    + config::ConfigModule
    + views::ViewsModule
    + events::EventsModule
    + validation::ValidationModule
    + helpers::HelpersModule
    + common_math::SharedMathModule
{
    #[init]
    fn init(&self, /* 参数 */) {
        // 仅初始化逻辑
    }

    #[upgrade]
    fn upgrade(&self) {
        // 仅升级迁移逻辑
    }

    #[endpoint]
    fn main_operation(&self) {
        // 委托给 helpers/validation
        self.validate_payment(&payment);
        let mut cache = cache::StorageCache::new(self);
        self.process_operation(&mut cache, &payment);
        // cache 销毁并提交
    }
}

errors.rs 模式

使用 pub static 字节字符串引用以实现高效的 gas 消耗错误消息:

pub static ERROR_NOT_ACTIVE: &[u8] = b"Contract is not active";
pub static ERROR_INVALID_AMOUNT: &[u8] = b"Invalid amount";
pub static ERROR_UNAUTHORIZED: &[u8] = b"Unauthorized";
pub static ERROR_NOT_SUPPORTED: &[u8] = b"Not supported";
pub static ERROR_INSUFFICIENT_BALANCE: &[u8] = b"Insufficient balance";
pub static ERROR_ZERO_AMOUNT: &[u8] = b"Amount must be greater than zero";

用法:

require!(amount > 0u64, ERROR_ZERO_AMOUNT);

这比内联字符串字面量更 gas 高效,因为编译器会去重静态引用。

events.rs 模式

将事件定义为单独的模块特质:

#[multiversx_sc::module]
pub trait EventsModule {
    #[event("deposit")]
    fn deposit_event(
        &self,
        #[indexed] caller: &ManagedAddress,
        #[indexed] token: &TokenId,
        amount: &BigUint,
    );

    #[event("withdraw")]
    fn withdraw_event(
        &self,
        #[indexed] caller: &ManagedAddress,
        #[indexed] token: &TokenId,
        amount: &BigUint,
    );
}

validation.rs 模式

集中所有输入验证:

#[multiversx_sc::module]
pub trait ValidationModule: crate::storage::StorageModule {
    fn validate_payment(&self, payment: &Payment<Self::Api>) {
        self.require_token_supported(&payment.token_identifier);
        self.require_amount_positive(payment.amount.as_big_uint());
    }

    fn require_token_supported(&self, token: &TokenId<Self::Api>) {
        require!(self.supported_tokens().contains(token), ERROR_NOT_SUPPORTED);
    }

    fn require_amount_positive(&self, amount: &BigUint) {
        require!(amount > &BigUint::zero(), ERROR_ZERO_AMOUNT);
    }
}

何时创建公共工作空间 crate

信号 操作
相同结构体在 2+ 个合约中使用 移动到 common/structs/
相同数学函数在 2+ 个合约中使用 移动到 common/math/
相同错误消息跨合约 移动到 common/errors/
相同事件定义 移动到 common/events/
协议常量(精度、限制) 移动到 common/constants/

工作空间 Cargo.toml

[workspace]
members = [
    "contract-a",
    "contract-a/meta",
    "contract-b",
    "contract-b/meta",
    "common/structs",
    "common/math",
    "common/errors",
    "common/constants",
    "common/events",
]

公共 crate Cargo.toml:

[package]
name = "common-structs"
version = "0.0.0"
edition = "2024"

[dependencies.multiversx-sc]
version = "0.64.0"

SDK 标准模块(multiversx-sc-modules

SDK 提供的可重用模块。在 Cargo.toml 中导入并在合约特质中继承。

[dependencies.multiversx-sc-modules]
version = "0.64.0"
模块 目的 导入路径
only_admin 仅管理员访问控制(所有者可以添加/移除管理员) multiversx_sc_modules::only_admin
pause 可暂停合约模式(#[endpoint] pause / unpause multiversx_sc_modules::pause
default_issue_callbacks 标准 ESDT 代币发行/设置角色回调 multiversx_sc_modules::default_issue_callbacks
esdt 代币发行、铸造、燃烧通过统一的 issue_token multiversx_sc_modules::esdt
governance DAO 提案、投票和执行 multiversx_sc_modules::governance
bonding_curve 代币定价与绑定曲线公式 multiversx_sc_modules::bonding_curve
token_merge NFT/SFT 合并和拆分 multiversx_sc_modules::token_merge
subscription 循环支付订阅 multiversx_sc_modules::subscription
staking 基础质押逻辑与奖励 multiversx_sc_modules::staking
features 合约能力的功能标志 multiversx_sc_modules::features
users 用户ID映射(地址到数字ID) multiversx_sc_modules::users
ongoing_operation 长运行操作检查点 multiversx_sc_modules::ongoing_operation
claim_developer_rewards 领取累积的开发者奖励 multiversx_sc_modules::claim_developer_rewards
dns MultiversX DNS herotag 注册 multiversx_sc_modules::dns

用法示例:

#[multiversx_sc::contract]
pub trait MyContract:
    multiversx_sc_modules::only_admin::OnlyAdminModule
    + multiversx_sc_modules::pause::PauseModule
    + multiversx_sc_modules::default_issue_callbacks::DefaultIssueCallbacksModule
{
    #[endpoint]
    fn admin_action(&self) {
        self.require_caller_is_admin();
        self.require_not_paused();
        // ...
    }
}

命名约定

项目 约定 示例
合约 crate kebab-case liquidity-pool
模块文件 snake_case storage.rs, helpers.rs
存储键 camelCase "totalSupply", "feeRate"
错误常量 SCREAMING_SNAKE ERROR_INVALID_AMOUNT
模块特质 PascalCase StorageModule, ValidationModule
端点名称 snake_case fn deposit_tokens(&self)
视图名称 camelCase(ABI) #[view(getBalance)]