这是余额不为零的全部地址清单,而不只是头部。它由链上事件构建,而非取自区块浏览器,并与代币的总发行量核对:在所有余额之和与发行量精确到最后一个 wei 相符之前,清单不会发布。
按余额排序。搜索既接受完整地址,也接受地址开头——0x 之后几个字符就够了。
凡是已知的地址都带标注:交易所、流动性池以及 Rainbow 自己的合约。其余地址在任何地方都没有标注——那些是普通钱包。
一个地址的余额,等于全部转入减去全部转出。因此只凭代币的转账记录,就能重建持有者清单及其余额,无需向区块浏览器发出任何一次请求。
代币合约部署于区块 41349994。从那里直到链头,读取全部 Transfer 事件,约三十六万条。这个过程可中断续跑:它一路保存状态,中断后从停下的地方继续,而不是从头再来。
发送方减去金额,接收方加上金额。零地址不进入清单:铸造与销毁都经由它,它并不是持有者。
所有正余额之和必须与合约的 totalSupply() 相符。是精确相符,而不是大致相符:按事件做的算术不会四舍五入,因此出现差额就意味着丢了事件。不相符就不覆盖输出,而是重新跑一遍,把漏掉的补齐。
为什么不用区块浏览器。Blockscout 有现成的清单,但每次只给五十个地址——五万多个地址就是一千多次请求。超过五十次之后它会把你关在门外数小时;更糟的是,它开始返回不完整的结果,却没有任何截断的迹象。我们正是这样丢过 61.5% 的返现总额,之后才把数据源换成节点。这样拼出来的清单会悄无声息地出错——而这比没有清单更糟。而且根本无从校验:区块浏览器不提供任何可以用来核对总数的量。
持有代币和持有质押仓位是两回事,两个集合几乎不重叠:持有者五万多个,质押者约三千个。把全部余额锁进质押的地址余额归零,会从这份清单里消失——那些代币此时记在质押合约名下,而不是某个人名下。
清单里有流动性池、质押合约和金库。它们是地址,不是所有者,把它们和钱包一起算作「持有者」并不正确。因此已知的那些都做了标注——好让人看得见,也能减掉。
反过来也成立:一个交易所地址背后站着成千上万的人。这份清单的行数是地址的数量,不是所有者的数量,不能当作人数来读。
数据会自动更新:首次完整跑完之后,采集器只读取新区块。对外以 /api/holdersall/index.json 以及旁边每份五百行的文件提供。