Universal createMessage
In FunC, you had to compose message cells manually and regularly face code like:
cell m = begin_cell()
.store_uint(0x18, 6)
.store_slice(sender_address)
.store_coins(50000000)
.store_uint(0, 1 + 4 + 4 + 64 + 32 + 1 + 1)
.store_uint(0x178d4519, 32)
.store_uint(query_id, 64)
...
.end_cell();
send_raw_message(m, 0);
In Tolk, you use a high-level function — and it's even more gas-effective:
val reply = createMessage({
bounce: true,
value: ton("0.05"),
dest: senderAddress,
body: RequestedInfo { ... }
});
reply.send(SEND_MODE_REGULAR);
Key features of createMessage
- Supports extra currencies
- Supports
stateInit
(code+data) with automatic address computation - Supports different WorkChains
- Supports sharding (formerly splitDepth)
- Integrated with auto-serialization of
body
- Automatically detects body ref or not
- More efficient than handwritten code
The concept is based on union types
There is a huge variety of interacting between contracts. When you explore FunC implementations, you notice that:
- sometimes, you "send to an address (slice)"
- ... but sometimes, you "build the address (builder) manually"
- sometimes, you compose
StateInit
from code+data - ... but sometimes, you already have
StateInit
as a ready cell - sometimes, you send a message to basechain
- ... but sometimes, you have the
MY_WORKCHAIN
constant and use it everywhere - sometimes, you just attach tons (msg value)
- ... but sometimes, you also need extra currencies
- etc.
How can we describe such a vast variety of options? The solution is union types!
Let's start exploring this idea by looking at how extra currencies are supported.
Extra currencies: union
When you don't need them, you just attach msg value as tons:
value: someTonAmount
When you need them, you attach tons AND extra currencies dict:
value: (someTonAmount, extraDict)
How does it work? Because the field value
is a union:
// how it is declared in stdlib
type ExtraCurrenciesDict = dict;
struct CreateMessageOptions<TBody> {
...
/// message value: attached tons (or tons + extra currencies)
value: coins | (coins, ExtraCurrenciesDict)
That's it! You just attach tons OR tons with extra, and the compiler takes care of composing this into a cell.