Appearance
外部消息
在项目配置中必须显式启用外部消息支持。如果不启用,编译将失败。
外部消息是那些没有发送者的消息,任何人都可以发送。外部消息是与链下系统集成或进行合约常规维护的好工具。处理外部消息与处理内部消息不同。在本节中,我们将介绍如何处理外部消息。
外部消息与内部消息的不同
外部消息与内部消息在以下方面不同:
合约自己支付燃气费用
处理内部消息时,通常由发送者支付燃气费用。处理外部消息时,合约支付燃气费用。这意味着你需要在外部消息中小心燃气费用的使用。你应该始终测试合约的燃气费用,并验证一切是否按预期工作。
消息必须手动接受
外部消息不会自动接受。你需要手动接受它们。这是通过调用 acceptMessage
函数完成的。如果你不调用 acceptMessage
函数,消息将被拒绝。这样做是为了防止外部消息的垃圾邮件。
消息接受前的 10k 燃气限制
10k 燃气是一个非常小的限制,Tact 本身在到达你的代码之前就可以消耗大量燃气。你应该始终测试合约的燃气使用情况,并验证一切是否按预期工作。
外部消息的 10k 燃气限制基于我们为整个区块链的 gas_limit 字段设置的参数。你可以参考这里:
消息接受后的无限燃气使用
在你接受燃气后,合约可以使用任意多的燃气。这样做是为了允许合约进行任何类型的处理。你应该始终测试合约的燃气使用情况,并验证一切是否按预期工作,避免可能耗尽合约余额的漏洞。
没有可用的上下文
处理外部消息时,上下文和发送者函数不可用。这是因为外部消息没有可用的上下文。这意味着你不能在外部消息中使用上下文和发送者函数。你需要仔细测试你的合约,以确保它不使用上下文和发送者函数。
启用外部消息支持
要启用外部消息支持,请在项目配置文件中启用它:
json
{
"options": {
"external": true
}
}
外部接收器
外部接收器的定义与内部接收器相同,但使用 external
关键字而不是 receive
:
solidity
contract SampleContract {
external("Check Timeout") {
// 检查合约超时
require(self.timeout > now(), "Not timeouted");
// 接受消息
acceptMessage();
// 超时处理
self.onTimeouted();
}
}