solidityeverscale

How to get the value 3 on the first request without await?


In this case, if there was an opportunity to use await, then there would be no reason to create a question, but await is not recommended to be used in contracts:

Note: This feature was designed to be used in debots, in usual contracts use it at your own risk. https://github.com/tonlabs/TON-Solidity-Compiler/blob/master/API.md#synchronous-calls

Pong.sol

pragma ton-solidity ^0.51.0;

contract Pong {
    function get(uint b) external responsible returns (uint) {
        return b + 1;
    }
}

Ping.sol

pragma ton-solidity ^0.51.0;

interface IPong {
    function get(uint b) external responsible returns (uint);
}

contract Ping {
    uint public result;
    uint public tmp;

    function run(address pong, uint a) public view returns(uint) {
        update(pong, a);
        tvm.accept();
        return a + tmp;
    }

    function update(address pong, uint a) internal pure {
        IPong(pong).get{callback: Ping.onGet}(a);
    }

    function onGet(uint b) external {
        tvm.accept();
        tmp = b;
    }
}

Run.bash

#!/usr/bin/env bash

set -o errexit

tondev se reset

rm -fr *.abi.json *.tvc

# Deploy Pong Contract
tondev sol compile Pong.sol
tondev contract deploy Pong --value 1000000000
pongAddress=$(tondev contract info Pong | grep Address | cut -d':' -f3 | cut -d' ' -f1)
echo "$pongAddress"

# Deploy Ping Contract
tondev sol compile Ping.sol
tondev contract deploy Ping --value 1000000000
pingAddress=$(tondev contract info Ping | grep Address | cut -d':' -f3 | cut -d' ' -f1)
echo "$pingAddress"

# Run
tondev contract run Ping run --input "pong:$pongAddress,a:1" | grep value0
# value0:0x0000000000000000000000000000000000000000000000000000000000000001
tondev contract run Ping run --input "pong:$pongAddress,a:1" | grep value0
# value0:0x0000000000000000000000000000000000000000000000000000000000000003

The purpose of the question is to understand how to get the value 3 on the first request, if possible. If not, then a more extensive explanation of how to develop contracts in the conditions of an asynchronous blockchain.


Solution

  • You can do this in asynchronous style more simply (without callback and await).

    I changed the code of your contracts:

    pragma ton-solidity ^0.51.0;
    
    interface IPing {
        function onGet(uint b) external;
    }
    
    contract Pong {
        function get(uint b) external {       
            IPing(msg.sender).onGet(b + 1);        
        }
    }
    
    pragma ton-solidity ^0.51.0;
    
    interface IPong {
        function get(uint b) external;
    }
    
    contract Ping {
        uint public tmp;
    
        function run(address pong, uint a) public  { 
            IPong(pong).get(a);
            tvm.accept();
            tmp = a + tmp;        
        }
    
        function onGet(uint b) external {
            tvm.accept();
            tmp = b + tmp;
        }
    }
    

    Now call a little changed this Run.bash

    #!/usr/bin/env bash
    
    set -o errexit
    
    tondev se reset
    tondev network default se
    rm -fr *.abi.json *.tvc
    
    # Deploy Pong Contract
    tondev sol compile Pong.sol
    tondev contract deploy Pong --value 1000000000
    pongAddress=$(tondev contract info Pong | grep Address | cut -d':' -f3 | cut -d' ' -f1)
    echo "$pongAddress"
    
    # Deploy Ping Contract
    tondev sol compile Ping.sol
    tondev contract deploy Ping --value 1000000000
    pingAddress=$(tondev contract info Ping | grep Address | cut -d':' -f3 | cut -d' ' -f1)
    echo "$pingAddress"
    
    # Run
    tondev contract run Ping run --input "pong:$pongAddress,a:1" &> /dev/null
    tondev contract run-local Ping tmp | grep tmp
    # tmp:0x0000000000000000000000000000000000000000000000000000000000000003
    
    tondev contract run Ping run --input "pong:$pongAddress,a:1" &> /dev/null
    tondev contract run-local Ping tmp | grep tmp
    # tmp:0x0000000000000000000000000000000000000000000000000000000000000006
    

    A bit of my philosophy, why it is better: the contracts must works without waiting. So callbacks and awaits, it is not good. Callbacks are very useful in debots, and it can take place there because debots running on your device. But it is another story…