首页 > 解决方案 > 交叉合约调用是原子的吗?

问题描述

以这段代码为例:

    #[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 吗?如何使事务原子化?

标签: nearprotocol

解决方案


合约调用不是原子的。为了使 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"),
        };
    }

此时,您可以进行最终状态更改,并且只有在整个事务成功时才会发生。


推荐阅读