从零到一:基于 Sui 和 Navi 协议的 PTB 应用开发教程

  • huahua
  • 更新于 2024-12-11 21:58
  • 阅读 244

在上一篇文章《Task5:move swap》中,我们成功实现了基于 Move 的代币交换智能合约,构建了链上代币池,完成了代币的安全、高效交换,并深入探讨了去中心化金融(DeFi)中代币交换的核心技术点。通过这一任务,我们不仅提升了对 Move 编程语言的掌握,更进一步了解了其在 DeFi 场景中

系列文章目录

Task1:hello move🚪 Task2:move coin🚪 Task3:move nft🚪 Task4:move game🚪 Task5:move swap🚪 Task6:sdk ptb🚪

更多精彩内容,敬请期待!✌️


@TOC


前言

在上一篇文章《Task5:move swap》中,我们成功实现了 基于 Move 的代币交换智能合约,构建了链上代币池,完成了代币的安全、高效交换,并深入探讨了去中心化金融(DeFi)中代币交换的核心技术点。通过这一任务,我们不仅提升了对 Move 编程语言的掌握,更进一步了解了其在 DeFi 场景中的潜力与应用价值。

本篇文章将进入 Task6:sdk ptb,我们将利用 Sui dApp-kit 探索如何通过 SDK 实现链上交互,并完成一个高度定制化的 PTB(Programmable Transaction Blocks) 应用。本任务的目标是使用 dApp-kit 在一个 PTB 内实现以下链上操作:

  1. 存入 Navi Protocol 1 枚 SUI
  2. 借出包含当前时间因子的 USDC,金额按以下公式计算:
    0.112917 当前日期的[月][天][小时]
    例如,2024年11月29日17点,借出的金额为:
    0.112917 USDC
  3. 将借出的等额 USDC 再存入 Navi Protocol

这一过程不仅要求链上操作的顺序性与安全性,还需充分利用 Sui 的 dApp-kit 和 PTB 特性,将所有交互整合在单个 PTB 中完成,实现链上操作的高效与原子性。

通过这一任务,你将掌握以下关键技术点:

  • Sui dApp-kit 的基础用法:如何通过 SDK 调用链上方法,实现与合约的交互;
  • 时间因子的应用:动态生成交易参数,提升智能合约的灵活性与实用性;
  • PTB 的设计与实现:在一个 PTB 内完成复杂链上操作,保障交易的不可分性。

让我们一起探索 Sui dApp-kit 的魅力,解锁链上交互的更多可能性,迈向 Move 开发的新高度,task6视频讲解🚪

image.png


什么是 Sui 链?

Sui 是一个高性能的区块链平台,旨在为去中心化应用提供快速、安全且可扩展的基础设施。它由 Aptos Labs 团队开发,基于新型的共识协议——Narwhal & Tusk。Sui 的设计目标是解决区块链性能瓶颈,提供极高的交易吞吐量和低延迟,适应复杂应用场景的需求。

Sui 链的主要特点:

  1. 高吞吐量与低延迟: Sui 的共识机制允许并行处理大量交易,而无需等待整个网络的全局共识。这种并行化的设计能够实现每秒处理成千上万的交易,极大提高了区块链的吞吐量,并减少交易确认的延迟。

  2. 面向对象的资源管理: Sui 将区块链中的资源视为对象进行管理。这些资源(例如代币、NFT)有独立的标识符,能够被直接跟踪和操作。通过这种方式,Sui 可以在多个节点之间高效并行地处理资源,而不需要处理全局状态,进一步提升性能。

  3. 灵活的交易模型: Sui 提供了灵活且高效的交易模型,支持在多个资源对象之间并行执行交易。这意味着不同用户的交易可以独立且高效地进行,避免了传统区块链的性能瓶颈。

  4. 高效的账户和权限管理: Sui 提供了多样化的账户管理机制,可以应对去中心化应用中复杂的权限需求。无论是个人账户、智能合约账户,还是多签账户,都能灵活配置和管理。


什么是 Move 编程语言?

Move 是专为区块链开发设计的编程语言,最初由 MetaLibra(后来的 Diem)团队开发,后被 Sui 区块链采用。Move 的设计重点是资源的管理、所有权的控制以及类型安全,它特别适用于处理去中心化应用中的资产和数字资源。

Move 语言的主要特点:

  1. 资源类型系统: Move 语言将所有的资源(如代币、NFT、智能合约中的数据等)视为“资源类型”。这些资源在系统中不能被复制或销毁,只能转移或借用。这确保了每个资源的唯一性和安全性,从根本上避免了传统智能合约中的资源丢失和重复转移问题。

  2. 所有权与借用机制: Move 通过严格的所有权和借用机制管理资源。每个资源都有一个唯一的所有者,资源的借用必须显式声明,这种机制避免了“共享资源”时的安全隐患。资源的借用可以确保开发者在不修改资源所有权的前提下共享和操作资源。

  3. 模块化编程: Move 支持模块化的编程结构,每个模块可以包含不同的资源类型和函数。模块化设计使得代码更加清晰、可复用,并有助于提高开发效率和降低代码出错的概率。

  4. 类型安全与可验证性: Move 是一门强类型语言,这意味着开发者必须在编译时明确地定义每个变量和资源的类型。Move 的类型系统能够确保合约中的大部分错误在编译阶段就被发现,从而避免了运行时错误,提高了智能合约的安全性。

Move 语言的示例代码: 以下是一个简单的 Move 合约示例,展示了如何创建和转移一个名为 Coin 的资源:

address 0x1 {
    module CoinModule {
        resource struct Coin has store {
            value: u64,
        }

        public fun create_coin(value: u64): Coin {
            Coin { value }
        }

        public fun transfer_coin(coin: Coin, recipient: address): Coin {
            let new_coin = Coin { value: coin.value };
            // 这里可以执行实际的转账操作
            return new_coin;
        }
    }
}

在这个示例中,Coin 是一个资源类型,包含一个 value 字段,表示代币的值。create_coin 函数用来创建新的 Coin 资源,而 transfer_coin 函数则用于将 Coin 资源转移到指定的账户。


Move 共学活动:快速上手 Move 开发

为了帮助更多开发者快速了解和掌握 Move 编程语言,Move 共学活动由 HOH 社区HackQuestOpenBuildKeyMap 联合发起。该活动旨在为新手小白提供一个良好的学习平台,带领大家一步步熟悉 Move 语言,并了解如何将其应用到 Web3 开发中。

通过与 Move 领域的专业导师们合作,参与者可以快速掌握 Move 语言的基础知识,逐步向更复杂的应用开发进阶。无论是区块链初学者,还是有一定开发经验的工程师,都能从中获益。

资源链接:

  • sui官方文档🚪:获取关于 Sui 链的详细文档,包括开发指南、API 参考等。
  • move学习B站视频🚪:通过 B 站的视频教程,跟随导师学习 Move 编程语言的基础与进阶。
  • letsmove仓库🚪:这是一个 Move 学习资源的 GitHub 仓库,包含了各种示例代码和教程,帮助开发者掌握 Move 语言。

一、项目初始化

1.1 创建项目

使用 DApp-Kit 提供的脚手架工具快速创建项目,不会使用DApp-Kit可以看这篇教程🚪

npm create @mysten/dapp

在提示中选择 react-client-dapp 模板作为开发框架。

855cfd45e5e6e84e3104248a8de8b8be_.png

1.2 安装依赖

进入项目目录后,安装所需的依赖包:

cd my-first-sui-dapp
pnpm i --save navi-sdk
pnpm i

上述命令会安装 navi-sdk Navi 协议交互工具🚪以及项目运行所需的其他依赖

c4e81dc985f2285e4736f86a0c627f8c_.png

随后,打开项目根目录中的 main.tsx 文件,将默认网络配置修改为 mainnet,或者根据需要设置为其他网络:

bfee51b670671c06e79a983e87d35689_.png

二、Navi.tsx 中实现交互逻辑

Navi.tsx 文件是应用的核心组件,主要实现了存款和借款的交互逻辑。

2.1 导入必要的库和组件

import {
  Button,
  Container,
  Flex,
  Text,
  Box,
  Heading,
} from "@radix-ui/themes";// 导入 Radix UI 组件
import {
  useCurrentAccount,
  useSignAndExecuteTransaction,
} from "@mysten/dapp-kit"; // 导入 Mysten DApp Kit 钩子
import { Transaction } from "@mysten/sui/transactions"; // Sui 交易类
import { Pool, PoolConfig } from "navi-sdk/dist/types"; // Navi SDK 中的池和池配置类型
import { pool, Sui, wUSDC } from "navi-sdk/dist/address"; // Navi SDK 中的池地址和代币信息
import { borrowCoin, depositCoin } from "navi-sdk/dist/libs/PTB"; // Navi SDK 中的借币和存币函数
import { useState } from "react"; // React 状态管理
  • UI库Radix UI 用于构建美观的界面。
  • DApp-Kit 钩子
    • useCurrentAccount:获取当前连接的钱包地址。
    • useSignAndExecuteTransaction:用于签名和提交 Sui 网络上的交易。
  • Navi SDK:提供与 Navi 协议交互的工具,包括存款和借款函数。
  • useState:React 的状态管理,用于动态显示交易结果或错误信息。

2.2 定义核心交互逻辑

(1) 组件结构和状态管理

export function Navi() {
  // 当前连接的钱包账户
  const account = useCurrentAccount();

  // 交易提交钩子
  const { mutate: signAndExecuteTransaction } = useSignAndExecuteTransaction();

  // 用于存储交易摘要和消息的状态
  const [digest, setDigest] = useState<string>(""); // 存储交易摘要
  const [message, setMessage] = useState<string>(""); // 存储错误或成功消息
  • account:当前连接的钱包账户。
  • digest:存储提交交易后的交易摘要。
  • message:显示交易的成功或失败消息。

(2) 核心函数实现

处理存款和借款逻辑的函数 deposit_borrow_Sui

// 处理存款和借款的异步函数
  const deposit_borrow_Sui = async () => {
    if (!account) {
      setMessage("Please connect your wallet first"); // 如果没有连接钱包,提示用户
      return;
    }

    try {
      const date = new Date(); // 获取当前日期
      const month = date.getMonth() + 1; // 获取月份
      const day = date.getDate(); // 获取日期
      const hour = date.getHours(); // 获取小时

      // 计算借款金额
      const borrow_amount =
        parseFloat(
          `0.${month.toString().padStart(2, "0")}${day.toString().padStart(2, "0")}${hour.toString().padStart(2, "0")}`,
        ) *
        10 ** wUSDC.decimal;
      console.log(borrow_amount);

      const tx = new Transaction(); // 创建新的交易对象
      tx.setSender(account.address); // 设置交易发送者

      // 确保池配置有效
      const suiPool: PoolConfig = pool[Sui.symbol as keyof Pool];
      const wusdcPool: PoolConfig = pool[wUSDC.symbol as keyof Pool];

      if (!suiPool || !wusdcPool) {
        throw new Error("Invalid pool configuration"); // 如果池配置无效,抛出错误
      }

      // 存款 SUI
      const [suiCoin] = tx.splitCoins(tx.gas, [1_000_000_000]); // 分割 SUI 代币
      if (!suiCoin) throw new Error("Failed to split SUI coins"); // 如果分割失败,抛出错误

      await depositCoin(tx, suiPool, suiCoin, 1_000_000_000); // 存款 SUI

      // 借款和存款 USDC
      const [toBorrowCoin] = await borrowCoin(tx, wusdcPool, borrow_amount); // 借款 USDC
      if (!toBorrowCoin) throw new Error("Failed to borrow USDC"); // 如果借款失败,抛出错误

      await depositCoin(tx, wusdcPool, toBorrowCoin, borrow_amount); // 存款 USDC

      // 清除之前的消息
      setMessage("");
      setDigest("");

      // 签名并执行交易
      signAndExecuteTransaction(
        { transaction: tx, chain: "sui:testnet" },
        {
          onSuccess: (result) => {
            console.log("Transaction successful:", result); // 成功时打印结果
            setDigest(result.digest); // 设置交易摘要
          },
          onError: (error) => {
            console.error("Transaction failed:", error); // 失败时打印错误
            setMessage(error.message || "Transaction failed"); // 设置错误消息
          },
        },
      );
    } catch (error) {
      console.error("Error in deposit_borrow_Sui:", error); // 捕获并打印错误
      setMessage(error instanceof Error ? error.message : "An unknown error occurred"); // 设置错误消息
    }
  };

功能解析:

  1. 连接钱包验证:若未连接钱包,直接返回提示信息。
  2. 计算借款金额:通过当前日期动态生成借款值(borrow_amount)。
  3. 设置交易:定义交易发送者,分割 SUI 资产,存款 SUI 并借款 USDC。
  4. 提交交易:调用签名和提交函数,成功时保存摘要,失败时记录错误。

    (3) 界面渲染

return (
    <Container>
      <Box>
        <Heading as="h2">Navi Protocol Task</Heading>
        <Text>
        此任务将向 Navi 协议存入 1 个 SUI,根据当前日期借入 USDC,然后存入等值的 USDC。
        </Text>
        <Flex gap="3" direction={"column"}>
          <Button onClick={deposit_borrow_Sui} variant="solid">开始交易</Button>
          {digest && (
            <Text >Transaction submitted: {digest}</Text> // 显示交易摘要
          )}
          {message && (
            <Text>Error: {message}</Text> // 显示错误消息
          )}
        </Flex>
      </Box>
    </Container>
  );
}

export default Navi; // 导出组件

三、集成到 App.tsx

App.tsx 文件中引入 Navi.tsx 并渲染:

image.png 通过运行项目,你可以看到用户界面中包含了一个简单的交互按钮,用于触发 SUI 和 USDC 的存款与借款操作。

四、运行项目

在项目根目录下运行以下命令启动开发服务器:

pnpm dev

启动后,按下键盘上的 "o" 键并回车,即可自动打开应用界面:

bfdf5e04fea498fa2b28ccaf8f1aaced_.png

当前 DApp 已连接到一个主网账户,该账户余额超过 1 SUI,确保后续交互顺利进行。

dca6251b320b64581080ecd6f66b0dc6_.png

点击页面中的 交易按钮,DApp 将完成交互并向 navi 中存入 1 SUI。 此时,控制台会输出交易过程中的时间因子(例如:112917),如下图所示:

2185331ef4f53ab33757843369f85602_.png

交易完成后,前端界面将显示交易的哈希值。请将该哈希值复制下来,并通过 suivision浏览器🚪查询交易详情:

6823089c0dfa7fe2d04bc032324495ef_.png

在浏览器中可以看到交易的执行状态为 成功,这表明 PTB 中设计的三个操作均已顺利完成:

2c8a0febcee2c8ca6696a88e3ff7cd0a_.png

温馨提示: 别忘了最后将存入的 1 SUI 取回哟!你可以前往 navi 官网🚪 完成提现操作。

通过上述步骤,你已成功完成 Task6 的开发任务!🎉 恭喜你完成了基于 Sui 的 Programmable Transaction Blocks(PTB) 实践项目!👏


总结

通过本次基于 Sui 的 Programmable Transaction Blocks(PTB) 实践项目,我们完整体验了从项目初始化到实现核心交互逻辑的全过程。借助 DApp-KitNavi SDK,我们成功开发了一款能够动态存取资产并与 Sui 网络交互的 DApp,学习了如何通过 PTB 设计灵活的链上操作流程,同时熟悉了 React 前端开发的基本框架以及与区块链协议交互的常见模式。项目中涵盖了账户验证、动态数据处理、交易创建与提交等关键环节,并在实际操作中积累了调试与优化的经验。此外,Navi 协议的存款和借款操作也进一步加深了对 DeFi 场景中资产管理的理解。通过这一实践,不仅强化了对 Sui 链上功能的认识,更为后续开发复杂的去中心化应用打下了坚实基础。如果你有任何疑问或建议,欢迎在评论区留言交流!🌹

下一步,我们将继续完成 Move 共学活动 的后续任务,期待与你一起学习更多区块链开发的精彩内容!🚀


更多精彩内容,欢迎关注系列文章目录! 我们在探索 Move 的道路上共同成长,不见不散! 🎉

点赞 0
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
huahua
huahua
0xbdd3...53C1
感谢您抽出时间阅读或观看这个简介,制作不易,感谢关注!如果您有任何问题或建议,请随时与我联系。谢谢!v:HHHHHH_1223