TON 区块链是基于消息的—要与其他合约通信和部署新合约,您需要发送消息。
Tact 中的消息通常使用内置Struct SendParameters
组成,它由以下部分组成:
现场 类型 说明 弹跳 Bool
bounce
- if set to true
(default) then the message will be bounced back to the sender if the receiver contract doesn’t exist or wasn’t able to process the message.到 地址
TON 区块链中的内部接收器 地址
。 值 Int
。value
in TON - the amount of TON you want to send with the message. This value is used to cover gas fees on the receiver side.模式 Int
。一个 8 位值,用于配置发送信息的方式,默认值为 0 0 0 。 参见:消息模式
。 身体 [Cell ?
][单元格] [可选][选项]信息正文作为[单元格
][单元格] 代码 [Cell ?
][单元格] [可选][opt] 合同的初始代码(编译后的字节码) 数据 [Cell ?
][单元格] [可选][选项]合同的初始数据(合同的init ()
函数 的参数)
字段 code
和 data
被称为 初始包 ,用于部署新合约。
发送简单回复
最简单的信息是对接收信息的回复,返回信息的所有多余值:
self . reply ( "Hello, World!" . asComment ()); // asComment converts a String to a Cell with a comment
发送信息
如果需要更高级的逻辑,可以直接使用 send ()
函数和 SendParameters
Struct 。
事实上,前面使用 . reply ()
的示例可以通过调用下面的send ()
函数来实现:
// bounce is set to true by default
to : sender (), // sending message back to the sender
value : 0 , // don't add Toncoins to the message...
mode : SendRemainingValue | SendIgnoreErrors , // ...except for ones received from the sender due to SendRemainingValue
body : "Hello, World" . asComment (), // asComment converts a String to a Cell with a comment
另一个示例是向指定的 Address
发送一条信息,信息的值
为 1 1 1 TON,body
为带有 String
"Hello, World!"
的注释:
let recipient : Address = ...;
let value : Int = ton ( "1" );
// bounce is set to true by default
mode : SendIgnoreErrors , // will send the message despite any errors
body : "Hello, World!" . asComment (),
可选标记 SendIgnoreErrors
表示即使在发送信息过程中发生错误,也会继续发送下一条信息。发送阶段的任何错误都不会导致事务逆转 。
发送打字信息
要发送二进制键入信息,可以使用以下代码:
let recipient : Address = ...;
let value : Int = ton ( "1" );
// bounce is set to true by default
mode : SendIgnoreErrors , // don't stop in case of errors
body : SomeMessage { arg1 : 123 , arg2 : 1234 }. toCell (),
部署合约
要部署一个合约,你需要用 initOf
计算它的地址和初始状态,然后在初始化信息中发送它们:
let init : StateInit = initOf SecondContract ( arg1 , arg2 );
let address : Address = contractAddress ( init );
let value : Int = ton ( "1" );
// bounce is set to true by default
mode : SendIgnoreErrors , // don't stop in case of errors
body : "Hello, World!" . asComment (), // not necessary, can be omitted
外发信息处理
TON 区块链上的每笔交易都由 多个阶段 组成。 出站报文在[计算阶段][计算]中进行评估,但***不在该阶段发送。 在[计算阶段][compute]中列出的所有操作,如外向消息或[储备请求](/ref/core-advanced#nativereserve),都会在[操作阶段][phases]中执行。
由于所有值都是在[计算阶段][compute]中计算的,所有费用都是在计算结束前计算的,而且在[操作阶段][phases]中出现异常时不会恢复交易,因此向外发送信息可能会因操作费 或转发费 不足而失败,不会出现跳转。
请看下面的例子:
// This contract initially has 0 nanoToncoins on the balance
contract FailureIsNothingButAnotherStep {
// And all the funds it gets are obtained from inbound internal messages
// 1st outbound message evaluated and queued (but not sent yet)
value : ton ( "0.042" ), // plus forward fee due to SendPayGasSeparately
mode : SendIgnoreErrors | SendPayGasSeparately ,
// 2nd outbound message evaluated and queued (but not sent yet, and never will be!)
mode : SendRemainingValue | SendIgnoreErrors ,
在那里,第二条信息实际上不会被发送:
[计算阶段][计算]结束后,计算合约的剩余价值 R \mathrm{R} R 。
在出站信息处理过程中,假设入站信息中提供了足够的价值,第一条信息会在余额上留下 R − ( 0.042 + f o r w a r d _ f e e s ) \mathrm{R} - (0.042 + \mathrm{forward\_fees}) R − ( 0.042 + forward_fees ) nanoToncoins 。
处理第二条信息时,合约会尝试发送 R \mathrm{R} R 纳米通币 ,但发送失败,因为剩余的金额已经较少。