跳转到内容

外部信息

外部信息是没有发件人的信息,世界上任何人都可以发送。 外部信息是与链外系统集成或对合约进行一般维护的良好工具。 处理外部信息与处理内部信息不同。 本节将介绍如何处理外部信息。

外部信息有何不同

外部消息不同于内部消息,其方式如下:

合约自行支付gas使用费

在处理内部信息时,发件人通常会支付gas使用费。 在处理外部信息时,合同支付gas使用费。 这意味着您需要谨慎使用外部信息中的 gas 。 您应该经常测试合约的gas使用情况,并确认一切正常。

信息必须手动接收

外部信息不会自动接收。 您需要手动接受它们。 这是通过调用 acceptMessage 函数实现的。 如果不调用 acceptMessage 函数,信息将被拒绝。 这样做是为了防止外部信息垃圾消息。

接受信息前的 10k gas 限值

10k gas 是一个非常小的限制,而 Tact 本身在到达你的代码之前就已经消耗了相当数量的 gas 。 您接受 gas 后,合约可以随意使用 gas 。 这样做是为了允许合约进行任何类型的处理。 您应该经常测试合约的 gas 使用情况,并验证一切正常,避免出现可能耗尽合约余额的漏洞。

接受消息后未限定的gas使用

您接受 gas 后,合约可以随意使用 gas 。 这样做是为了允许合约进行任何类型的处理。 您应该经常测试合约的 gas 使用情况,并验证一切正常,避免出现可能耗尽合约余额的漏洞。

暂无可用上下文

处理外部消息时,contextsender 两个函数不可用。 这是因为外部信息没有上下文。 这意味着您不能在外部信息中使用 contextsender 函数。 您需要仔细测试您的合约,确保它没有使用 contextsender 函数。

启用外部信息支持

要启用外部信息支持,请在项目配置文件中启用:

{
"options": {
"external": true
}
}

外部接收器(External receivers)

外部接收器的定义方式与内部接收器相同,但使用“external”关键字而不是“receive”关键字:

contract SampleContract {
external("Check Timeout") {
// Check for contract timeout
require(self.timeout > now(), "Not timeouted");
// Accept message
acceptMessage();
// Timeout processing
self.onTimeouted();
}
}