You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何编写Flow交易向Inventory中的Grocery资源集合添加物品?

解决方案

首先需要修改你的Flow合约,给Inventory资源添加一个用于收纳Grocery物品的方法,再编写对应的交易来完成添加操作。

1. 修改后的合约代码

pub contract Crash{

    pub resource Grocery{
        pub var grocery: String
        pub var units: Int
        pub var price: UFix64

        init(_grocery: String, _units: Int, _price: UFix64) {
              self.grocery = _grocery
              self.units = _units
              self.price = _price
        }
    }

    pub resource interface InventoryPublic{
        pub var items: @{UInt64: Grocery}
        // 新增添加物品的接口声明
        pub fun addGrocery(id: UInt64, item: @Grocery)
    }

    pub resource Inventory: InventoryPublic{
        pub var items: @{UInt64: Grocery}
        init(){
                self.items <- {}
        }

        // 实现添加物品的方法
        pub fun addGrocery(id: UInt64, item: @Grocery) {
            // 可选:防止重复ID覆盖已有物品
            if self.items[id] != nil {
                panic("Grocery with this ID already exists")
            }
            // 将Grocery资源移动到字典中
            self.items[id] <-! item
        }

        destroy(){
            destroy self.items
        }
    }

    pub fun createInventory(): @Inventory{
            return <- create Inventory()
    }

    // 重命名函数使其语义更清晰:创建Grocery资源而非直接添加
    pub fun createGrocery(name: String, nos: Int, price: UFix64): @Grocery{
            return <- create Grocery(_grocery: name,_units : nos, _price: price)
    }

}

2. 添加物品的交易代码

import Crash from 0xf8d6e0586b0a20c7

// 传入物品ID、名称、数量、价格作为交易参数
transaction(groceryId: UInt64, name: String, units: Int, price: UFix64) {
    prepare(acct: AuthAccount) {
        // 借取Inventory的引用(路径需与创建时一致)
        let inventoryRef = acct.borrow<&Crash.Inventory>(from: /storage/Inv1)
                            ?? panic("Inventory not found at /storage/Inv1")

        // 1. 通过合约函数创建Grocery资源
        let newGrocery <- Crash.createGrocery(name: name, nos: units, price: price)
        // 2. 调用Inventory的方法添加物品
        inventoryRef.addGrocery(id: groceryId, item: <- newGrocery)
    }

    execute {
        log("Grocery item added successfully!")
    }
}

关键说明

  • 合约封装:通过在Inventory中添加addGrocery方法,遵循Flow的资源封装原则,避免直接在交易中操作内部集合。
  • 资源所有权:使用<-!操作符将Grocery资源的所有权转移到Inventory的字典集合中,符合Flow的资源安全规则。
  • 路径一致性:交易中借取Inventory的路径必须与创建时的存储路径(/storage/Inv1)保持一致,否则会触发找不到资源的panic。

内容的提问来源于stack exchange,提问作者Allen Chrisso Dhas

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 20:28:12