Robinhood Chain 代币化股票(Stock Tokens)数据集
Robinhood Chain 的招牌资产:把美股/ETF 映射成链上 ERC-20 代币(TSLA、AAPL、 NVDA ……)。本文档记录这套代币是怎么部署/管理的(附证据:交易哈希、合约地 址)、识别规则和置信度、由此建出的表,以及几条可以直接抄的查询。
Robinhood Chain 的招牌资产:把美股/ETF 映射成链上 ERC-20 代币(TSLA、AAPL、
NVDA ……)。本文档记录这套代币是怎么部署/管理的(附证据:交易哈希、合约地
址)、识别规则和置信度、由此建出的表,以及几条可以直接抄的查询。
研究方法:生产 ClickHouse 只读轻量查询(max_threads=2, max_execution_time=90)
- 对候选合约做
eth_call name()/symbol()/decimals()(单次 JSON-RPC batch, 102 个合约 × 3 个方法 = 306 次调用打包成 1 次 HTTP 请求,对节点几乎零负载)。 研究日期:2026-09-25,生产链上高度 72,035,708。
1. 这些代币是怎么发出来的
1.1 单一工厂合约,单一部署者
生产链上现存的 102 个"股票代币"全部由同一个工厂合约创建:
- 工厂合约:
0x4783c67b63de2b358ac5951a7d41f47a38f3c046 - 调用方(部署者 EOA):
0x5516b3451d4d6c9f63353fe7bc9537477ecce000(102/102 次创建调用都来自这个地址;另有 1 次来自0x697e774d60c1a3769f2ed0b919aacf17be0ae553,selector 是标准 UUPSupgradeToAndCall(address,bytes)(0x4f1ef286),即工厂本身是可升级代理,这 1 次是对工厂的一次合约升级,不是创建代币) - 创建方法 selector:
0xb2670cc5(createToken(...),参数签名未逐字节反解, 不影响识别规则)
实锤交易(均可在生产 robinhood.transactions/robinhood.logs 里查到):
| 代币 | 创建区块 | 创建交易 |
|---|---|---|
| TSLA (Tesla) | 34,767 | 0xc4c1c585493272cb137f1039546033e9200c249e82579f77eed26041929e80a8 |
| AAPL (Apple) | 48,276 | 0x5ddd494c3217a5e3ef5b8f32471669c4d09d544354d790e744cd9c39ded5901b |
| NVDA (NVIDIA) | 45,898 | 0xcdb797c54ff55ef4008f254c486cc52d7393a65a6e6fb622c44b0260eecb755f |
两笔交易(TSLA、AAPL)的 from/to/selector 完全一致:
from = 0x5516b345...ecce000,to = 0x4783c67b...f3c046(工厂),
input 前 4 字节 = 0xb2670cc5;transactions.contract_address 为
NULL——代币合约不是这笔交易的顶层创建(to = NULL 的那种),而是工厂内部
CREATE/CREATE2 出来的,所以只能从工厂发出的事件里拿到代币地址。
1.2 工厂发出的 TokenCreated 事件
每次创建都在工厂地址上产生 1 条日志,topic0 = 0xd9b0c6a1c0de228715ad0fa09f3259686ee84f8cc675e03ef7e47a9cdafa76d6,1 个未解
出具体含义的 indexed 参数(topic1,不是地址形状,可能是内部 id 或
symbol 的哈希——没有查证,这里不猜),data 是标准 ABI 编码的
(address token, string name, string symbol):
data (TSLA 创建事件, 十六进制, 已按 32 字节分段):
000000000000000000000000322f0929c4625ed5bad873c95208d54e1c003b2d -- token 地址
0000000000000000000000000000000000000000000000000000000000000060 -- name 的偏移量
00000000000000000000000000000000000000000000000000000000000000a0 -- symbol 的偏移量
0000000000000000000000000000000000000000000000000000000000000019 -- name 长度 = 25
5465736c6120e280a220526f62696e686f6f6420546f6b656e00... -- "Tesla • Robinhood Token"
0000000000000000000000000000000000000000000000000000000000000004 -- symbol 长度 = 4
54534c4100... -- "TSLA"代币合约自己在同一笔交易里还会发 2 条日志(topic0 = 0x1cf3b03a... 携带一个地址型参数,topic0 = 0xc7f505b2... 携带值 1 —
后者和 OpenZeppelin Initializable 的 Initialized(uint8) 形状吻合,说明代币
合约本身是可初始化的(代理/克隆)实现,但没有逐字节核对具体是哪个开源库版
本,同样不过度声称)。
1.3 命名规律 + 代币属性
-
命名:
"<公司/资产名> • Robinhood Token"(中间是 U+2022 项目符号),symbol= 真实的美股/ETF ticker(TSLA、AAPL、NVDA、MSFT、AMZN、GOOGL、META、COIN、ORCL、INTC、AMD、MU、BA、ARM、XOM……)。 -
不止"单一股票":102 个里有少数是 ETF,例如
WEEK= "Roundhill Weekly T-Bill ETF",走的是完全相同的工厂/事件/命名路径。本数据 集不把 ETF 排除在外,stock_tokens表按行如实记录,不做"这个其实不算 股票"的静默改写。 -
decimals()对全部 102 个代币做了eth_call,结果全部是 18(不是假 设值——见下方 money-safety 说明)。 -
name()存在事后改名的情况:102 个里有 4 个的当前name()和 创建时TokenCreated事件里的name不一致(symbol均未变):代币地址 创建时 name 当前 name 0xc93a8c...5099fRoundhill Weekly T-Bill ETF Roundhill Weekly T-Bill ETF • Robinhood Token 0xc583c6...cea1ccD-Wave Quantum • Robinhood Token D-Wave Quantum Inc. Common Stock • Robinhood Token 0xf9b46d...f1a2d5Exxon Mobil • Robinhood Token ExxonMobil Holdings Corporation • Robinhood Token 0x4a0e65...fae35eea(SPCX)SpaceX • Robinhood Token Space Exploration Technologies Corp. Class A Common Stock • Robinhood Token 这是目前唯一观察到的"类企业行动"迹象(更规范的展示名称替换),没有看到 拆股/合股(split)迹象——
erc20_transfers里没有任何脱离正常 mint/transfer/burn 模式的批量再分配。是否存在更早期、本研究窗口之外的拆 股,未验证,不下结论。
1.4 铸造 / 赎回
- 铸造(
from= 零地址):97/102 个代币出现过铸造,共 1,367 笔,其中 1,367 笔里绝大多数的to都是同一个地址0xcfaece2151502da2a21d47234ae1f08618a60a94(这就是发行方/托管方地址)。 示例:TSLA 首次铸造0x66c9dd9bc1e983dee62b8d61499594b61ccde1f60fc8a7617e7a616fe3a4191e(区块 143,822,铸造 0.1 TSLA 给该地址)。 - 赎回销毁(
to= 零地址):37/102 个代币出现过销毁,共 171 笔,主要from是另一个地址0xa8553db0049fc6843c0d00d0efc08d31848e3c74(和铸造地 址不同——推测是"发行"与"赎回处理"分别由两个角色地址执行,未向 Robinhood 官方核实,仅基于链上行为归纳)。 - 5/102 个代币截至研究时还没有任何转账(刚创建、尚未启用交易)。
- 这 97 个有活动的代币累计转账 25,373,473 笔——印证"招牌资产"级别的量。
1.5 未识别的伴生事件(如实标注不确定性)
统计全部 102 个代币合约日志的 topic0 分布:Transfer
(0xddf252ad...) 和一个每次 Transfer 都伴生 1 条、次数完全相等
(均为 26,129,631)的未识别事件 0x37e7f0db430edc9dd31bc66f25f8449353aa0818f503b906747dd8f286cd3802
同时出现,含义未解码(推测可能与投票权快照/checkpoint 类的 ERC20 扩展有关,
但没有验证,不作为结论);Approval (0x8c5be1e5...) 342,848 次;另有 6 种
仅出现 1~8 次的稀有事件(0x2205df45...、0xa274116f...、0x0030cda6...、
0xe28b7053...、0xa45f47fd...、0x9e87fac8...),形状上像是权限
(role/ownership)或升级相关的管理事件,同样未逐个解码,不在此确认是否为
"暂停"(pause)——本研究没有找到确凿的 pause 事件证据,也没有证据证明不存
在,如实标注为未知。
2. 识别规则与置信度
规则:{db}.logs 里 address = 0x4783c67b63de2b358ac5951a7d41f47a38f3c046
且 topic0 = 0xd9b0c6a1c0de228715ad0fa09f3259686ee84f8cc675e03ef7e47a9cdafa76d6
的每一条日志,其 ABI 解出的 token 字段地址即为一个股票/ETF 代币。
置信度:HIGH。三条独立线索在生产数据上互相印证、完全收敛到同一批 102 个地址:
- 按转账笔数排序的高频 ERC-20 代币榜单里,除
WETH/USDG/VIRTUAL等明 显的通用资产外,其余全部匹配 "• Robinhood Token" 命名。 - 对候选地址做
eth_call name()/symbol(),102/102 都匹配该命名规律,symbol都是可识别的真实美股/ETF ticker。 - 102/102 都能追溯到同一个工厂合约 + 同一个部署者 EOA 发出的
TokenCreated事件。
decimals 只在 eth_call decimals() 真正成功时才写入(102/102 目前都是
18),失败或没有配置 RPC_URL 时保持 NULL 而不是假设 18——对应
stock_tokens.confidence 字段:high(三线索齐全 + decimals 已验证)/
medium(decimals 本轮未验证)/ needs_review(eth_call 失败,或
creator 按 created_tx_hash 反查 transactions 未命中,需要人工复核)。
creator 同理只在反查命中时才写入,未命中时保持 NULL 而不是零地址——零
地址在本数据集里是 mint/burn 哨兵值,写成 creator 会伪造出一个"零地址部
署"的假身份。
3. 表
DDL:schema/clickhouse/derived/007_stock_tokens.sql。
刷新脚本:scripts/derived/refresh_stock_tokens.sh
(纯 Python 标准库实现,同 scripts/qa/check_clickhouse.py 的约定,不复用
indexer 自己的 Rust ClickHouse/RPC 客户端)。
{db}.stock_tokens(ReplacingMergeTree(version),ORDER BY address): 注册表。address/symbol/name/decimals/created_block/created_tx_hash/factory/creator/mint_address/burn_address/detection_rule/confidence/notes。refresh_stock_tokens.sh registry幂等刷新:重跑只是新增一个version,FINAL会折叠。{db}.stock_token_daily_activity(ReplacingMergeTree(version),ORDER BY (token, day)):按天的铸造/销毁/转账笔数+金额+当日活跃地址数。 只由refresh_stock_tokens.sh daily对已收尾的日子(默认日终 2 小时 之后)从{db}.erc20_transfers FINAL重新聚合写入,避免把还在增长的当天 数据当成最终值。金额是链上原始UInt256,换算成人类可读数值用stock_tokens.decimals,同docs/queries.md§1.4 的约定,不在表里存浮点。{db}.stock_token_holder_balances(VIEW,非物化):某代币当前持仓 = 收到的 - 发出的(Int256,排除零地址两端),每次查询都基于erc20_transfers FINAL现算,天然不受重组/去重影响,代价是全表扫描更 慢——按单个代币查最合适(见下面例 1/例 4),如果"一次查所有代币的持仓人" 变成高频路径,应该改成按stock_token_daily_activity的思路做增量物化。
4. 本地验证
生产只读研究数据即验证依据(见上文历次查询结果的原始数字)。此外在本地
ClickHouse scratch 库上用真实链上数据跑了一遍完整链路(stocktok_scratch_wt31
库,验证后已 DROP DATABASE 清理):
- 用真实节点 RPC 回填两段真实区块(
34,760–34,790覆盖 TSLA 创建、143,818–144,215覆盖 TSLA 从铸造到销毁的完整生命周期 铸造→转账→转账→销毁 4 笔真实转账,from/to与生产环境的mint_address/burn_address完全一致)。 refresh_stock_tokens.sh registry(带RPC_URL)正确解出 TSLA 一行,decimals=18、confidence=high、mint_address/burn_address与生产 全量统计的两个地址完全一致;不带RPC_URL重跑时decimals正确保持NULL、confidence降为medium(money-safety 的 fail-closed 路径); 重跑两次FINAL计数仍是 1(幂等)。refresh_stock_tokens.sh daily --date 2026-06-22正确算出mint_count=1, burn_count=1, transfer_count=2, unique_holders=3,金额 均为100000000000000000(0.1 TSLA @ 18 位小数),和真实的 4 笔转账逐笔 对得上。- 对当天(还没收尾)跑
daily会被拒绝并非零退出,确认"未收尾的日子拒绝 计算"这条 fail-closed 规则生效。
5. 示例查询
假设已执行 sed 's/{db}/robinhood/g' 建表。
例 1:持仓地址数最多的股票代币 Top 10
SELECT hex(token) AS token_hex, count() AS holder_count
FROM robinhood.stock_token_holder_balances
GROUP BY token
ORDER BY holder_count DESC
LIMIT 10;例 2:TSLA 最近 30 天每日铸造/销毁
SELECT day, mint_count, toString(mint_volume) AS mint_volume_raw,
burn_count, toString(burn_volume) AS burn_volume_raw
FROM robinhood.stock_token_daily_activity FINAL
WHERE token = unhex('322f0929c4625ed5bad873c95208d54e1c003b2d') -- TSLA
AND day >= today() - 30
ORDER BY day;例 3:当前注册表,标出哪些还需要人工复核
SELECT symbol, name, decimals, confidence, notes
FROM robinhood.stock_tokens FINAL
ORDER BY confidence != 'needs_review' ASC, symbol;例 4:某只股票代币按 decimals 换算后的历史转账(人工查看用,非记账)
SELECT block_number, hex(tx_hash) AS tx_hash_hex, hex(`from`) AS from_hex, hex(`to`) AS to_hex,
toString(amount) AS amount_raw,
amount / pow(10, (SELECT decimals FROM robinhood.stock_tokens FINAL WHERE address = t.token LIMIT 1)) AS amount_approx
FROM robinhood.erc20_transfers t FINAL
WHERE is_deleted = 0 AND token = unhex('af3d76f1834a1d425780943c99ea8a608f8a93f9') -- AAPL
ORDER BY block_number DESC
LIMIT 50;例 5:昨天发生过赎回(销毁)的股票代币
SELECT s.symbol, a.burn_count, toString(a.burn_volume) AS burn_volume_raw
FROM robinhood.stock_token_daily_activity a FINAL
INNER JOIN robinhood.stock_tokens s FINAL ON s.address = a.token
WHERE a.day = yesterday() AND a.burn_count > 0
ORDER BY a.burn_count DESC;