It is sometimes useful to emit events from the contract in order to indicate that certain things happened.
This data can later be analyzed off-chain and indexed by using RPC API to query all transactions sent to the contract.
Consider for example a staking contract that wants to indicate how much time passed before users unstaked for analytics purposes. By analyzing this data, the developer can think of improvements to the product.
One way to achieve this is by sending messages back to the sender using self.reply()
or by sending messages to the zero address. These two methods work, but they are not the most efficient in terms of gas.
The emit()
function will output a message (binary or textual) from the contract. This message does not actually have a recipient and is very gas-efficient because it doesn't actually need to be delivered.
The messages emitted in this way are still recorded on the blockchain and can be analyzed by anyone at any later time.
All Examplesimport "@stdlib/deploy"; message Divide { by: Int as uint32; } contract Errors with Deployable { val: Int as int64; init() { self.val = 0; } // not meeting the condition will raise an error, revert the transaction and all state changes receive("increment") { self.val = self.val + 1; require(self.val < 5, "Counter is too high"); } // any exceptions during execution will also revert the transaction and all state changes receive(msg: Divide) { self.val = 4; self.val = self.val / msg.by; } // advanced: revert the transaction and return a specific non-zero exit code manually // https://ton.org/docs/learn/tvm-instructions/tvm-exit-codes receive("no access") { throw(132); } get fun value(): Int { return self.val; } }