TON Solidity不使用await如何在首次调用请求中获取返回值3
TON 合约异步调用问题解答
结论
在TON官方推荐的普通合约开发规范下,无法实现首次调用Ping合约的run接口就获取到返回值3。
现有代码执行流程说明
两次调用返回结果不一致的问题,完全符合TON异步合约的执行逻辑:
- 首次调用
Ping.run接口时:- 合约先执行
update方法,向Pong合约异步发送get调用请求,该请求不会阻塞当前交易执行 - 此时
tmp变量还是初始值0,run方法直接返回1 + 0 = 1,本次交易执行结束 - 本次交易上链完成后,网络才会将
get请求转发给Pong合约执行,Pong返回结果后触发Ping的onGet回调,将tmp赋值为2
- 合约先执行
- 第二次调用
Ping.run接口时,tmp已经被回调赋值为2,所以返回1 + 2 = 3
特殊实现方案(不推荐生产使用)
如果硬要实现首次调用就返回3,可以使用await同步调用语法,但是TON官方明确说明该特性仅为debots设计,普通合约使用风险自担:
注意:该特性专为debots设计,普通合约使用需自行承担风险
修改后的run方法示例:
function run(address pong, uint a) public view returns(uint) { uint b = await IPong(pong).get(a); tvm.accept(); return a + b; }
异步区块链环境合约开发核心逻辑
TON是典型的异步架构区块链,跨合约调用默认全是异步消息模式,开发时需要遵循以下核心逻辑:
- 单次合约交易执行过程中,所有外发的跨合约调用消息,只会在本次交易完全执行结束后才会被网络转发、目标合约才会处理,不会阻塞当前交易的执行流程
- 跨合约调用的回调函数,和发起调用的原交易是完全独立的两个交易,只会在目标合约处理完请求并返回响应后才会触发
- 单次交易执行过程中,无法拿到本次交易内新发起的异步调用的返回结果,所有依赖跨合约返回值的业务逻辑,要么放到回调函数中执行,要么拆分交易步骤,等回调执行完成后再发起后续调用
- 同步
await语法虽然可以把跨调用响应合并到当前交易流程,但会带来交易超时、Gas消耗不可控等风险,普通生产环境合约不建议使用
内容的提问来源于stack exchange,提问作者ilyar
相关产品推荐
相关产品推荐

