跳到主要内容

高负载钱包

在短时间内处理大量信息时,需要使用名为 "Highload Wallet "的特殊钱包。在很长一段时间里,Highload Wallet V2 是 TON 的主要钱包,但使用时必须非常小心。否则,您可能会锁定所有资金

随着 Highload Wallet V3的问世,这一问题已在合约架构层面得到解决,而且耗 gas 量更少。本章将介绍 Highload Wallet V3 的基础知识和需要记住的重要细微差别。

高负载钱包 v3

该钱包专为需要以极高的速度发送交易的用户设计。例如,加密货币交易所。

向 Highload v3 发送的任何给定外部报文(传输请求)都包含:

  • 顶层 cell 中的签名(512 位)--其他参数位于该 cell 的 ref 中
  • 子钱包 ID(32 位)
  • 作为 ref 发送的消息(将被发送的序列化内部消息)
  • 报文的发送模式(8 位)
  • 复合查询 ID - 13 位 "位移 "和 10 位 "位数",但 10 位位数只能到 1022,而不是 1023,而且最后一个可用的查询 ID(8388605)是为紧急情况保留的,通常不应使用
  • 创建于, 或消息时间戳
  • 超时

超时作为参数存储在 Highload 中,并与所有请求中的超时进行核对,因此所有请求的超时都是相同的。信息到达 Highload 钱包时的时间不应早于超时时间,或在代码中要求 created_at > now() - timeout。出于重放保护的目的,查询 ID 的存储时间至少为超时时间,最长可能为 2 * 超时时间,但不应期望其存储时间超过超时时间。子钱包 ID 会与钱包中存储的 ID 进行核对。内部 ref 的哈希值与签名一起与钱包的公钥进行核对。

Highload v3 只能从任何给定的外部信息中发送 1 条信息,但它可以通过一个特殊的操作码将信息发送给自己,这样就可以在调用内部信息时设置任何操作 cell ,从而有效地使 1 条外部信息可以发送多达 254 条信息(如果在这 254 条信息中还有另一条信息发送到 Highload 钱包,那么发送的信息数量可能会更多)。

一旦所有检查都通过,Highload v3 将始终存储查询 ID(重放保护),但由于某些情况,包括但不限于以下情况,可能无法发送信息:

  • 包含状态初始(如有需要,可使用特殊操作码发送此类信息,以便在高负载钱包向自身发送内部信息后设置操作 cell )
  • 余额不足
  • 无效的报文结构(包括外部输出报文--只有内部报文可以直接从外部报文发送)

Highload v3 绝不会执行包含相同 query_id created_at 的多个外部请求--当它忘记任何给定的 query_id 时,created_at 条件将阻止此类信息的执行。这实际上使 query_id created_at 成为 Highload v3 传输请求的 "主键"。

在迭代(递增)查询 ID 时,像递增普通数字一样,先迭代位数,然后再迭代位移,这样会更省钱(从花费的 TON 数来看)。到达最后一个查询 ID 后(请记住紧急查询 ID - 见上文),您可以将查询 ID 重置为 0,但如果 Highload 的超时时间尚未过去,则重放保护字典将满,您必须等待超时时间过去。

高负载钱包 V2

危险

建议使用 Highload wallet v3。

该钱包专为需要在短时间内发送数百笔交易的用户设计。例如,加密货币交易所。

它允许你在一次智能合约调用中发送多达 254 个交易。它还使用了一种略有不同的方法来解决重放攻击,而不是 seqno,所以你可以同时多次调用这个钱包,甚至在一秒钟内发送数千个交易。

局限性

注意,在处理高负载钱包时,需要检查并考虑以下限制。

  1. 存储容量限制。 目前,合约存储容量应小于 65535 个 cell 。如果 old_queries 的大小超过此限制,将在 ActionPhase 中抛出异常,事务将失败。 失败的事务可以重放。
  2. gas 限制。 目前, gas 限制为 1'000'000 GAS 单位,这意味着一个 tx 中可清理的 旧查询次数是有限制的。如果过期查询次数较多,合约就会卡住。

这意味着不建议设置过高的过期日期: ,过期时间跨度内的查询次数不应超过 1000 次。

此外,一次交易中清理的过期查询次数应低于 100 次。

如何

您还可以阅读 Highload Wallet Tutorials 一文。

钱包源代码: