Messages Between Contracts

Different contracts can communicate with each other only by sending messages. This example showcases two separate contracts working in tandem:

  • Counter - A simple counter that can increment only by 1.
  • BulkAdder - This contract instructs Counter to increment multiple times.

Click the Deploy button to deploy both contracts. To make the counter reach 5, send the Reach message to BulkAdder by clicking the Send Reach{5} button.

Observe the number of messages exchanged between the two contracts. Each message is processed as a separate transaction. Also note that BulkAdder cannot call a getter on Counter; it must send a query message instead.

Who's Paying for Gas

By default, the original sender is responsible for covering the gas costs of the entire cascade of messages they initiate. This is funded by the original TON coin value sent with the first Reach message.

Internally, this is managed by each message handler forwarding the remaining excess TON coin value to the next message it sends.

Challenge: Try to modify the code to refund the original sender any unused excess gas.
All Examples
import "@stdlib/deploy";

contract ReceiveCoins with Deployable {

    val: Int as int64;

    init() {
        self.val = 0;
    }

    // receive empty messages, these are usually simple TON coin transfers to the contract
    receive() {
        dump("empty message received");
        // revert the transaction if balance is growing over 3 TON
        require(myBalance() <= ton("3"), "Balance getting too high");
    }

    receive("increment") {
        // print how much TON coin were sent with this message
        dump(context().value);
        self.val = self.val + 1;
    }

    receive("refunding increment") {
        // print how much TON coin were sent with this message
        dump(context().value);
        self.val = self.val + 1;
        // return all the unused excess TON coin value on the message back to the sender (with a textual string message)
        self.reply("increment refund".asComment());
    }
 
    get fun balance(): Int {
        return myBalance(); // in nano-tons (like cents, just with 9 decimals)
    }
}