Leo 中 Finalize 语法的重大更新

Leo 中 Finalize 语法的重大更新

在 Leo 编程语言中,Finalize 是一种机制,用于在智能合约执行结束时对合约状态进行最终的处理和清理。这种方法确保合约在完成所有操作后,能够正确地更新和持久化状态,并执行任何必要的清理工作。

但是在最新的 Leo 代码中 Finalize 语法已经废弃了,这里在最新的 Testbeta 网络中得到了验证。Async/Await 机制用于替代传统的 Finalize 方法,以简化和优化智能合约的状态更新和清理过程。这种方式通过异步编程模型,使代码更易读、更高效,并且避免了传统 Finalize 方法中的一些局限性。

Leo 中的 Async/Await

概念介绍

  • Async:定义一个异步函数,该函数可以包含异步操作。异步函数不会立即执行,而是返回一个 Future 对象,当需要结果时,可以等待该 Future 完成。

  • Await:用于等待异步函数的执行,直到异步操作完成,并返回结果。

主要优点

  1. 简化代码结构Async/Await 使异步代码看起来像同步代码一样,减少了回调地狱和复杂的状态管理。

  2. 提高性能:通过异步编程模型,可以在等待异步操作完成时,执行其他任务,提高合约的执行效率。

  3. 避免 Finalize 局限:直接在合约执行过程中处理状态更新和清理,避免了 Finalize 方法的额外复杂性。

Finalize 和 Async/Await 在实际使用中的区别

  • 旧版本的 Finalize 语法

program test1.aleo {

    // 示例映射数据以存储全局状态
    mapping data: u32 => u32; 

    // 执行链上逻辑的异步过渡
    transition main(public x: u32) -> u32 {
    
        // 链下逻辑:根据输入 x 计算一个值
        let off_chain_result: u32 = compute_off_chain(x);

        // 链上逻辑:使用链下结果更新全局状态
        return off_chain_result then finalize (off_chain_result));
        
    }

    // 异步函数以 finalize 更新链上的全局状态
    finalize main (off_chain_result: u32) {
    
        // 将 off_chain_result 值加到 x_1
        let x_1: u32 = off_chain_result + 2u32;

        // 将 off_chain_result 值加到 x_2
        let x_2: u32 = off_chain_result + 5u32;

        // 条件语句:检查 x_1 是否大于 x_2
        // 如果是,则将 x_1 输出,否则将 x_2 输出到映射 (data)
        let final_value: u32 = (x_1 > x_2) ? x_1 : x_2;

        // 设置映射中的值
        Mapping::set(data, 0u32, final_value);
    }

    // 链下函数,根据输入 x 计算一个值
    function compute_off_chain(x: u32) -> u32 {
    
        // 简单计算:将输入值加倍
        return x * 2u32;
        
    }
}
  • 最新的 Async/Await 语法

program test1.aleo {

    // 示例映射数据以存储全局状态
    mapping data: u32 => u32; 

    // 执行链上逻辑的异步过渡
    async transition main(public x: u32) -> (u32, Future) {
    
        // 链下逻辑:根据输入 x 计算一个值
        let off_chain_result: u32 = compute_off_chain(x);

        // 链上逻辑:使用链下结果更新全局状态
        return (off_chain_result, finalize_update(off_chain_result));
        
    }

    // 异步函数以 finalize 更新链上的全局状态
    async function finalize_update(off_chain_result: u32) {
    
        // 将 off_chain_result 值加到 x_1
        let x_1: u32 = off_chain_result + 2u32;

        // 将 off_chain_result 值加到 x_2
        let x_2: u32 = off_chain_result + 5u32;

        // 条件语句:检查 x_1 是否大于 x_2
        // 如果是,则将 x_1 输出,否则将 x_2 输出到映射 (data)
        let final_value: u32 = (x_1 > x_2) ? x_1 : x_2;

        // 设置映射中的值
        Mapping::set(data, 0u32, final_value);
        
    }

    // 链下函数,根据输入 x 计算一个值
    function compute_off_chain(x: u32) -> u32 {
    
        // 简单计算:将输入值加倍
        return x * 2u32;
        
    }
}

关键概念

  1. 异步函数和过渡:

    • 异步函数可以定义为异步运行。这些函数返回一个 Future,表示将来某个时间点将执行的代码。

    • 异步过渡是特殊类型的异步函数,可以调用它们来在区块链上执行状态更改。

  2. Futures:

    • Future 是表示将来某个时间点可用值的对象。在 async/await 语法中,函数不直接返回值;它们返回 Futures。

Async/Await 语法规则

  1. 调用异步函数:

    • 只能在异步过渡内部调用异步函数。

    • 异步函数不能直接返回值;它们返回一个 Future。

  2. 异步过渡:

    • 不能在条件块内调用异步过渡。

    • 异步过渡调用返回一个可选值,并且必须返回一个单一的 Future。

    • 异步过渡调用生成的 Future 不能被返回。

  3. 处理 Futures:

    • Future 可以传递给异步函数调用,必须等待它。

    • 所有 Futures 必须由异步函数调用消费或作为输出返回。

总结

Leo 语言通过引入 Async/Await 机制,简化了智能合约中异步操作的编写和管理过程。相比传统的 Finalize 方法,Async/Await 提供了一种更自然、更高效的方式来处理状态更新和清理,提高了代码的可读性和执行效率。

希望这些解释和示例能够帮助你更好地理解和使用 Leo 中的 Async/Await 特性。如果有具体问题或需求,请随时进一步讨论或提供详细信息。

Aleo 官方链接: