Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

项目规划与架构设计

本节介绍如何从零开始规划一个基于 Sui 的全栈去中心化应用(dApp)。我们将从需求分析出发,完成技术选型、目录结构设计和开发流程规划,为后续的 Move 合约开发与前端集成打下基础。

需求分析

在开始编码之前,明确项目需求是最重要的一步。以 Hero NFT 游戏为例:

用户故事

  • 作为用户,我可以连接钱包到应用
  • 作为用户,我可以创建一个英雄(Hero)并装备武器(Weapon)
  • 作为用户,我可以查看自己拥有的英雄列表
  • 作为用户,我可以查看最近被铸造的所有英雄

功能拆解

功能模块链上(Move)链下(前端/SDK)
英雄铸造new_hero 函数交易构造 + 签名
武器铸造new_weapon 函数交易构造 + 签名
装备管理equip_weapon / unequip_weaponUI 交互 + PTB 调用
英雄列表HeroRegistry 共享对象RPC 查询 + 渲染
我的英雄getOwnedObjects 过滤

技术选型

技术栈概览

┌──────────────────────────────────────────────────┐
│                  全栈 DApp 架构                     │
├──────────────────────────────────────────────────┤
│                                                    │
│  智能合约层    Sui Move                             │
│  集成测试层    TypeScript + @mysten/sui SDK         │
│  前端 UI 层   React + @mysten/dapp-kit             │
│  钱包连接层    Slush Wallet / Suiet / Sui Wallet   │
│                                                    │
└──────────────────────────────────────────────────┘

核心依赖

技术用途
合约Sui Move链上逻辑、对象模型
SDK@mysten/sui交易构造、RPC 调用、BCS 编码
前端框架React + ViteUI 渲染、路由管理
dApp 工具包@mysten/dapp-kit钱包连接、hooks、查询
脚手架@mysten/create-dapp快速初始化项目

为什么选择 Sui?

  • 对象所有权模型:NFT 天然适合 Sui 的所有权语义
  • 并行执行:独立的 owned object 交易可并行处理
  • PTB(可编程交易块):一笔交易内完成铸造+装备的原子操作
  • Move 类型安全:编译期保证资源安全

目录结构设计

my-dapp/
├── move/                          # Move 合约
│   └── hero/
│       ├── Move.toml              # 包配置
│       ├── sources/
│       │   └── hero.move          # 核心合约
│       └── tests/
│           └── hero_tests.move    # 单元测试
├── typescript/                    # TypeScript 集成
│   ├── src/
│   │   ├── helpers/               # 交易构造辅助函数
│   │   │   ├── mintHero.ts
│   │   │   └── mintWeapon.ts
│   │   └── tests/
│   │       └── e2e.test.ts        # 端到端测试
│   ├── package.json
│   └── tsconfig.json
├── app/                           # React 前端
│   ├── src/
│   │   ├── components/
│   │   │   ├── HeroesList.tsx     # 英雄列表组件
│   │   │   ├── HeroCard.tsx       # 英雄卡片组件
│   │   │   ├── CreateHeroForm.tsx # 创建英雄表单
│   │   │   └── OwnedObjects.tsx   # 我的英雄
│   │   ├── App.tsx
│   │   └── main.tsx
│   └── package.json
└── README.md

开发流程

推荐的开发顺序

1. 设计数据模型(Move 结构体)
      │
      ▼
2. 实现核心合约逻辑
      │
      ▼
3. 编写 Move 单元测试
      │
      ▼
4. 发布到 localnet/testnet
      │
      ▼
5. 编写 TypeScript 集成辅助函数
      │
      ▼
6. 编写端到端测试
      │
      ▼
7. 搭建 React 前端
      │
      ▼
8. 集成钱包 + 调用合约
      │
      ▼
9. 测试 + 部署

Move.toml 配置示例

[package]
name = "hero"
edition = "2024"

[addresses]
hero = "0x0"

初始化前端项目

cd app
npm create @mysten/dapp
# 选择模板,填写项目名称
cd <app-name>
pnpm install
pnpm run dev

数据模型设计原则

设计 Move 结构体时需要考虑的关键问题:

1. Owned vs Shared

类型适用场景示例
Owned Object单一用户拥有,不需要并发访问Hero、Weapon
Shared Object全局状态,需要多方读写HeroRegistry

2. 能力(Abilities)选择

// key + store:可转让的 NFT
public struct Hero has key, store {
    id: UID,
    name: String,
    stamina: u64,
    weapon: Option<Weapon>,
}

// key + store:能力凭证(Cap 后缀)
public struct AdminCap has key, store {
    id: UID,
}

// copy + drop:事件
public struct HeroCreated has copy, drop {
    hero_id: ID,
    creator: address,
}

3. 注册表模式

使用共享对象追踪全局状态:

public struct HeroRegistry has key {
    id: UID,
    ids: vector<ID>,
    counter: u64,
}

fun init(ctx: &mut TxContext) {
    transfer::share_object(HeroRegistry {
        id: object::new(ctx),
        ids: vector[],
        counter: 0,
    });
}

小结

项目规划是全栈 dApp 开发的第一步。关键要点:

  • 从用户故事出发,明确链上/链下的职责划分
  • 采用 Move 合约 → TypeScript SDK → React 前端的三层架构
  • 合理组织目录结构,保持模块清晰
  • 先设计数据模型,再实现逻辑——Move 的类型系统会帮你在编译期发现问题
  • 遵循 “合约优先” 的开发顺序,确保链上逻辑正确后再构建前端