Skip to main content

Message

In Everscale, smart-contracts communicate between each other and with non-blockchain applications by means of an asynchronous message passing.

Technically, a message is a data structure encoding one of the following:

  • desired function call at a destination smart-contract, optionally attaching some coins.
  • event log record to signal external observers about some significant state being reached

A message consists of: header and body. The header contains the information about the sender, receiver, value as well as the information required by the validator to apply the message to the block. The message body, in turn, comprises the payload of VM instructions that are necessary for the execution of the smart contract.

There are three types of messages on Everscale:

Inbound external message - a message sent from outside onto the Everscale blockchain. It can be sent by any actor outside the blockchain. So-called messages from nowhere. Inbound external messages initiate changes to the blockchain’s state. It is important to mention that external messages can not be value-bearing. They can only declare intent to transfer value to another account.

Internal message: a message sent from one contract to another. Like an inbound external message, it updates the blockchain's state. Only internal messages can be value-bearing.

Outbound external message: aka event - a message that can be emitted by a smart contract. Off-chain participants can subscribe to events within the Everscale network and receive them.

pub struct Message {
header: CommonMsgInfo,
init: Option<StateInit>,
body: Option<SliceData>,
body_to_ref: Option<bool>,
init_to_ref: Option<bool>,
}

The last two fields body_to_ref and init_to_ref are used only for serialization purpose, hence not considered in this document.

Message Header

Any message has a message header: a data-structure defining, among other things, the message type and source and destination addresses.

The message header defines its type. It is described by the following enumeration:

pub enum CommonMsgInfo {
IntMsgInfo(InternalMessageHeader),
ExtInMsgInfo(ExternalInboundMessageHeader),
ExtOutMsgInfo(ExtOutMessageHeader),
}

Internal Message

Within Everscale blockchain, smart-contracts communicate with each other by exchanging messages. Messages sent by smart-contracts are called internal.

They are opposed to external messages that are sent by off-chain applications to smart-contracts.

The message header of an internal message is defined as follows:

pub struct InternalMessageHeader {
pub ihr_disabled: bool,
pub bounce: bool,
pub bounced: bool,
pub src: MsgAddressIntOrNone,
pub dst: MsgAddressInt,
pub value: CurrencyCollection,
pub ihr_fee: Grams,
pub fwd_fee: Grams,
pub created_lt: u64,
pub created_at: UnixTime32,
}

InternalMessageHeader fields

FieldDescription
ihr_disabledIHR routing protocol disabled, always true
bounceShould the answer message be generated in case of an error
bouncedIs this message was auto-generated by error handling
srcMessage source address
dstMessage destination address
valueAmount of coins attached to the message
ihr_feeIHR fee amount, always 0
fwd_feeMessage delivery fee amount
created_ltMessage creation logic time
created_atMessage creation time in Epoch

Some clarifications:

  • bounced flag is set when the message itself was auto-generated as a result of an error. If the message with bounced flag leads to an error itself, the next bounced message will not be generated.
  • value is measured in Nano Evers (10910^{-9})
  • reated_lt is a monotonically increasing counter, thanks to this field, each new generated message is unique, even if the message payload is the same. The message creation logic time is also used to guarantee order of delivery. We do not dive deep into this question, because it is protocol-level details.

External Message

External messages are created outside of the blockchain and get sent through specially distinguished validator nodes called DApp Servers2.

External message header is defined as follows:

pub struct ExternalInboundMessageHeader {
pub src: MsgAddressExt,
pub dst: MsgAddressInt,
pub import_fee: Grams,
}
  • Fields src and dst are source and destination addresses.
  • Field import_fee should have been the value paid to the validator for processing an external message. But in the current node, this field is not used. Hence, the fee is not paid. We reported this issue to the developers.
  • The source address for an external message is always set to AddrNone.
pub enum MsgAddressExt {
AddrNone,
AddrExtern(MsgAddrExt),
}

The second variant AddrExtern is not supported currently.

Events

Event can be considered as a log record. It is used to signal external observers of reaching some significant state in a smart-contract.

Usually, observers are external non-blockchain applications that constantly monitor blockchain state3. Other smart-contracts are not able to catch events.

pub struct ExtOutMessageHeader {
pub src: MsgAddressIntOrNone,
pub dst: MsgAddressExt,
pub created_lt: u64,
pub created_at: UnixTime32,
}
pub enum MsgAddressIntOrNone {
None,
Some(MsgAddressInt)
}
  • Transaction Executor automatically assigns the source address src to be equal to the smart-contract address emitting the event.
  • The destination address dst may contain any identifier. It is included for easier integration with off-chain applications, i.e. applications can monitor emitted events based on their destination address, and consume only those events destined to their custom identifier.
  • Fields created_lt, created_at defines the logical creation time and epoch creation time.

Reference


  1. In the current protocol implementation, not all validator nodes process external messages. This is subject to change in the future protocol versions
  2. For example, by sending GraphQL requests to the DApp-server