Scrypto:调用方法时 ResourceCheckFailure

Scrypto: ResourceCheckFailure when calling method

我的组件中有这个方法,它应该在用户发送付款后 return GumBall 令牌:

pub fn buy_gumball(&self, payment: Bucket) -> Bucket {
    self.payments.put(payment.take(self.gumball_cost));
            
    self.gumball_vault.take(1)
}

当我调用那个方法时,我得到一个 ResourceCheckFailure:

> resim call-method [component_address] buy_gumball 10,030000000000000000000000000000000000000000000000000004

Instructions:
├─ DeclareTempBucket
├─ CallMethod { component_address: 02c1897261516ff0597fded2b19bf2472ff97b2d791ea50bd02ab2, method: "withdraw", args: [10, 030000000000000000000000000000000000000000000000000004] }
├─ TakeFromContext { amount: 10, resource_address: 030000000000000000000000000000000000000000000000000004, to: Bid(0) }
├─ CallMethod { component_address: 0268709f61e9f60d5d8b8157b5d4939511f194a9f6cfd8656db600, method: "buy_gumball", args: [Bid(0)] }
├─ DropAllBucketRefs
├─ DepositAllBuckets { account: 02c1897261516ff0597fded2b19bf2472ff97b2d791ea50bd02ab2 }
└─ End { signers: [04005feceb66ffc86f38d952786c6d696c79c2dbc239dd4e91b46729d73a27fb57e9] }
Results:
├─ Ok(None)
├─ Ok(Some(Bid(1)))
├─ Ok(None)
└─ Err(ResourceCheckFailure)
Logs: 0
New Entities: 0

知道我为什么会收到这个吗?

Radix 引擎确保所有存储桶都被 returned、存储在保险库中或在交易结束时销毁。这是为了确保不会因为开发人员忘记将存储桶内容放在某个地方而丢失任何资源。

想象一下,您发送的金额会超过要求的金额。如果 RE 不做这些检查,额外的 XRD 就会丢失。

对于你的情况,我建议 return 将付款桶返回给调用者:

pub fn buy_gumball(&self, payment: Bucket) -> (Bucket, Bucket) {
    self.payments.put(payment.take(self.gumball_cost));

    (self.gumball_vault.take(1), payment)
}

这样一来,如果用户发送的 XRD 多于要求,他们会取回零钱,RE 会很高兴。