nearprotocol - 交叉合约调用是原子的吗?
问题描述
以这段代码为例:
#[payable]
pub fn add_liquidity(&mut self, min_liquidity: u128, max_tokens: u128) -> U128 {
let deposit = env::attached_deposit();
let contract_near_balance = env::account_balance();
let user_address = env::predecessor_account_id();
let contract_address = env::current_account_id();
let token_amount = max_tokens;
println!("{}", token_amount);
let initial_liquidity = contract_near_balance;
println!("initial liquidity{}", initial_liquidity);
self.uni_totalsupply = initial_liquidity;
let balance_option = self.uni_balances.get(&user_address);
match balance_option {
Some(_) => {
self.uni_balances.insert(&user_address, &initial_liquidity);
}
None => {
self.uni_balances.insert(&user_address, &initial_liquidity);
}
}
Promise::new(self.avrit_token_id.clone()).function_call(
b"transfer_from".to_vec(),
json!({"owner_id":contract_address, "new_owner_id":"avrit.testnet", "amount": U128(token_amount)}).to_string().as_bytes().to_vec(),
DEPOSIT,
env::prepaid_gas() - GAS_FOR_SWAP,
);
initial_liquidity.into()
}
即使 promise 失败,它会在存储中设置 uni_balances 吗?如何使事务原子化?
解决方案
合约调用不是原子的。为了使 Promise 链具有原子性,需要使用then
在初始 Promise 之后调用的回调。在回调函数中,您可以检查上一个承诺的成功,如下所示:
pub fn check_promise(&mut self) {
match env::promise_result(0) {
PromiseResult::Successful(_) => {
env::log(b"Check_promise successful");
self.checked_promise = true;
}
_ => panic!("Promise with index 0 failed"),
};
}
此时,您可以进行最终状态更改,并且只有在整个事务成功时才会发生。
推荐阅读
- sql - 在ORACLE中显示所有姓名长度为5个字符的员工
- sockets - 如果我从来没有声明过 sin_addr 怎么会是一个联合体?
- python - Pandas:如何在保持列配对的同时按列分组
- python - 正则表达式检测电话号码
- swift - Swift:iBeacon 在 iOS 结束进程之前运行代码
- javascript - Vue.js 无法向 $root 元素发出事件
- c# - 即使在添加清单并提供权限后,MediaCapture 初始化也会失败
- excel - 需要比较两列并将输出提供给第三列
- c# - 如何在 Google Or-Tools 中限制路线持续时间?
- c# - 我能够从 ALM 获取文件夹,但不能从测试中获取 - c#