Sui区块链开发指南:使用borrow模块模拟对象引用

Sui区块链开发指南:使用borrow模块模拟对象引用

sui Sui, a next-generation smart contract platform with high throughput, low latency, and an asset-oriented programming model powered by the Move programming language sui 项目地址: https://gitcode.com/gh_mirrors/su/sui

理解Sui中的对象引用机制

在Sui区块链上,所有数据都以对象的形式存在。开发者通过Move语言编写智能合约时,经常需要操作这些链上对象。Sui API提供了丰富的功能来操作对象,其中大多数API函数都要求以引用的方式传递对象。

对象使用方式对比

按值使用对象意味着你拥有该对象的完全控制权:

  • 可以销毁对象(如果具备相应功能)
  • 可以包装对象(如果具有store能力)
  • 可以将对象转移到其他地址

按引用使用对象则受到更多限制,因为你不拥有对象本身,而是通过模块定义的逻辑来操作对象引用。引用分为两种类型:

  1. 可变引用(&mut):可以修改对象内容,但不能销毁或转移
  2. 不可变引用(&):仅提供对对象数据的只读访问

可编程交易块(PTB)中的引用限制

当前Sui的可编程交易块存在一个重要限制:无法使用交易命令返回的对象引用。虽然可以使用输入对象、PTB创建的对象或按值返回的对象作为后续交易命令的引用,但如果交易命令返回的是引用,则不能在后续调用中使用这个引用。

borrow模块的解决方案

Sui框架内置的borrow模块巧妙地解决了这个问题。它通过以下机制实现了安全的对象引用模拟:

  1. Referent对象:包装需要引用的目标对象
  2. Borrow实例:采用"热土豆"模式(hot potato pattern),确保对象在同一PTB中被取用后必须归还
  3. 安全保证:通过Borrow对象的结构设计,确保归还的对象与取出的对象完全一致

实现原理分析

Borrow对象定义为:

struct Borrow { 
    ref: address, 
    obj: ID 
}

这种设计确保了:

  • Borrow实例不能被丢弃或存储
  • 必须在同一交易中消费Borrow实例
  • 归还的对象必须与原始Referent实例匹配
  • 无法用其他对象替换Referent中的原始对象

实际应用示例

考虑一个资产管理场景,我们有两个模块:

资产定义模块

module asset_module {
    struct Asset has key, store {
        // 资产数据
    }

    public fun use_asset(asset: &Asset) {
        // 使用资产的逻辑
    }
}

资产管理模块(使用borrow模块改造后):

module asset_manager {
    struct AssetManager has key {
        asset: Referent<Asset>,
    }

    public fun get_asset(manager: &mut AssetManager): (Asset, Borrow) {
        borrow::borrow(&mut manager.asset)
    }

    public fun return_asset(
        manager: &mut AssetManager,
        asset: Asset,
        b: Borrow) {
            borrow::put_back(&mut manager.asset, asset, b)
    }
}

PTB中的调用流程

在可编程交易块中,完整的调用流程如下:

// 初始化PTB
const txb = new TransactionBlock();
// 加载资产管理器
const assetManager = txb.object(assetManagerId);
// 获取资产和Borrow实例
const [asset, borrow] = txb.moveCall({
    target: "0xaddr1::asset_manager::get_asset",
    arguments: [assetManager],
});
// 使用资产
txb.moveCall({
    target: "0xaddr2::asset_module::use_asset",
    arguments: [asset],
});
// 归还资产
txb.moveCall({
    target: "0xaddr1::asset_manager::return_asset",
    arguments: [assetManager, asset, borrow],
});

设计考量与最佳实践

  1. 侵入性设计:使用Referent需要对现有代码结构进行较大调整,应在设计初期就考虑是否采用此方案

  2. 未来兼容性:Sui计划在未来支持PTB中的原生引用,设计时应考虑如何平滑过渡

  3. API设计影响

    • Referent模型强制使用可变引用
    • 按值返回对象可能影响API设计
    • 需要谨慎设计模块逻辑和对象暴露方式
  4. 安全性验证:确保所有使用borrow模块的代码路径都正确归还了对象

总结

Sui的borrow模块为当前PTB中的引用限制提供了有效的解决方案,虽然需要一定的设计调整,但能够确保对象使用的安全性。开发者在使用时应充分理解其工作机制,并考虑未来可能的功能演进。随着Sui生态的发展,更自然的引用模式支持将进一步提升开发体验。

sui Sui, a next-generation smart contract platform with high throughput, low latency, and an asset-oriented programming model powered by the Move programming language sui 项目地址: https://gitcode.com/gh_mirrors/su/sui

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

平钰垚Zebediah

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值