gpt4 book ai didi

rust - NEAR 跨合约调用异常如何处理?

转载 作者:行者123 更新时间:2023-12-03 11:35:23 32 4
gpt4 key购买 nike

如何在合约之间的异步调用链中捕获和处理异常?
假设我的事务发起了以下调用:

contractA.run()
-> do changes in contractA
-> calls contractB.run()
-> do changes in contractB
-> then calls another method on contractA: contractA.callback()
* callback() crashes
在 Promise 中发生异常后,NEAR 不会回滚过去 Promise 中发生的更改。我也没有在 near-sdk 中看到任何处理异常的方法。 .
一个想法是返回错误而不是抛出异常并创建一堆私有(private)函数来更新错误值后的状态并添加/释放互斥锁。然而,这并不能解决有时我们无法控制的问题,例如在外部智能合约中(例如,如果 contractB.do 在上面的示例中会出现 panic )。

最佳答案

捕获异常的唯一方法是对生成异常的 Promise 进行回调。
在解释的场景中,contractA.callback()不应该崩溃。您需要足够仔细地构建合约以避免回调失败。大多数情况下是可以做到的,因为您控制回调的输入和附加的气体量。如果回调失败,则类似于在异常处理代码中出现异常。
另请注意,您可以确保 callbackcontractA.run() 中附加了足够的气体后,已正确安排.如果不是这种情况,例如您没有足够的气体连接到 run ,回调和其他promise的调度将失败,整个状态来自run更改被回滚。
但是有一次run完成,状态从 run 更改 promise 和callback必须仔细处理。
我们在 lockup 有几个地方允许回调失败的合约:https://github.com/near/core-contracts/blob/6fb13584d5c9eb1b372cfd80cd18f4a4ba8d15b6/lockup/src/owner_callbacks.rs#L7-L24
还有大部分回调不会失败的地方:https://github.com/near/core-contracts/blob/6fb13584d5c9eb1b372cfd80cd18f4a4ba8d15b6/lockup/src/owner_callbacks.rs#L28-L61

指出在某些情况下合约不想依赖其他合约的稳定性,例如当流量为 A --> B --> A --> B .在这种情况下 B无法将回调附加到提供给 A 的资源.对于这些场景,我们正在讨论添加一个特定构造的可能性,该构造是一个原子并且一旦它被删除就具有解析回调。我们称之为 Safe : https://github.com/nearprotocol/NEPs/pull/26

编辑

What if contractB.run fails and I will like to update the state in contractA to rollback changes from contractA.run?


在这种情况下 contractA.callback()仍然被调用,但它有 PromiseResult::Failed对于它的依赖 contractB.run .
所以 callback()可以修改 contractA的状态还原更改。
例如,锁定合约实现的回调以处理从权益池合约中退出: https://github.com/near/core-contracts/blob/6fb13584d5c9eb1b372cfd80cd18f4a4ba8d15b6/lockup/src/foundation_callbacks.rs#L143-L185
如果我们调整名称以匹配示例:
锁仓合约( contractA )试图从质押池( run() )中提取资金( contractB ),但由于最近取消质押,资金可能仍被锁定,因此提取失败( contractB.run() 失败)。
回调被调用( contractA.callback()),它检查 promise ( contractB.run)是否成功。由于提款失败,回调将状态恢复到原始状态(恢复状态)。
实际上,它稍微复杂一些,因为实际的序列是 A.withdraw_all -> B.get_amount -> A.on_amount_for_withdraw -> B.withdraw(amount) -> A.on_withdraw

关于rust - NEAR 跨合约调用异常如何处理?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62987417/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com