FastX Node
返回控制台 Back to console

合约分层与权限

FastX Node 链上合约的替换边界与角色范围。这是一份说明,不是控制台功能,改这个文件即可更新本页。

判断一个合约能不能换掉,只有一条标准:它自己攒的状态,丢了要不要紧。


一、基础设施层 · 不能替换

节点资产和推荐关系是长生命周期事实,换掉就没了,无法重建。

合约 攒了什么 为什么不能换
FastXNodeNFT 节点资产、生命周期状态、算力、维护期 节点本身就是它。换掉等于所有人的节点作废
ReferralRegistry 账户激活、推荐边、推荐码注册表、节点归因 推荐关系是事实层,链下无法重建
FXNW 固定总量,构造时一次铸完,无任何参数 换合约等于换代币,那是迁移不是替换

二、可迁移层 · 能换,但必须先迁状态

这三个能换,但各自攒了一份丢了要出事的状态。换之前先想清楚这份状态怎么办。

合约 留存状态 不迁的后果
NodeMintGateway mintedOrigins,结算侧的幂等键 新表是空的,旧 originId 重放会重复铸造
MiningSettlement 锚点哈希链,每条锚点链到前一条 新部署从 seq 0、prev 为 0 开始,链断在换合约那一刻。合约没有重置能力,这是设计如此
FXNWClaim 托管的 FXNW、各期 Merkle 根、已领记录 钱留在旧合约;已领记录丢失等于开了重复领取的口子
AICClaim 托管的 FXNW、每个钱包的已领累计额 换之前先 recover 把钱取走;累计额丢了,已经领过的人能按同一张签名再领一次

三、可替换层 · 换掉就换掉

自己只存配置,事实都写在 NFT 和 Registry 上。重连角色、重设配置即可。

合约 自己的状态 说明
NodeSale 各类型售卖配置、已售计数 L1 预售入口
NodeDirectSale 售卖配置、burnBps、treasury、vault USDT / FXNW 直购入口
NodeCompose composeEnabled L2 合成 L3
NodeMaintenance 各类型费率、treasury 维护期写在 NFT 上,不在它这里。开发环境已实际换过一次
NodeComposeVoucher 只有 signer 自己不铸也不记账,originId 唯一性在网关。换掉只需重授网关角色、重设签名者

替换时必须重连的角色

新合约授上,旧合约同时撤掉。不撤旧的,两份合约都能写同一份事实,出问题时分不清来源。

新合约 需要的角色
NodeSale / NodeDirectSale NFT 的 MINTER_ROLE;Registry 的 ATTRIBUTION_RECORDER_ROLE
NodeCompose NFT 的 MINTER_ROLE 和 COMPOSER_ROLE;Registry 的 ATTRIBUTION_RECORDER_ROLE
NodeMintGateway NFT 的 MINTER_ROLE;Registry 的 ATTRIBUTION_RECORDER_ROLE
NodeMaintenance NFT 的 MAINTENANCE_ROLE

各合约的角色与权限范围

所有角色都由 DEFAULT_ADMIN_ROLE 管理。撤销 DEFAULT_ADMIN_ROLE 是唯一不可逆的操作:它没有别的来源,最后一个持有者被撤销后没有人能再授予它。

FastXNodeNFT

角色 能做什么 谁该持有
DEFAULT_ADMIN_ROLE 授撤所有角色、改各类型算力、改元数据 URI、暂停 多签
MINTER_ROLE 铸造节点 各销售与合成合约,不给人
NODE_ADMIN_ROLE 节点管理操作 运营
MAINTENANCE_ROLE 写 maintenanceUntil 仅 NodeMaintenance
COMPOSER_ROLE 消耗节点用于合成 仅 NodeCompose

改各类型算力只影响之后铸造的节点,已铸节点的算力永久固定。

ReferralRegistry

角色 能做什么 谁该持有
DEFAULT_ADMIN_ROLE 授撤角色、改激活签名者与登记费、开关自注册、启停推荐码、暂停 多签
CHANNEL_MANAGER_ROLE 注册 Root 码与渠道码、激活渠道码 运营
ACCOUNT_CODE_REGISTRAR_ROLE 链上登记账户推荐码 仅 registrar worker
ATTRIBUTION_RECORDER_ROLE 记录节点归因 各销售与合成合约

停用推荐码不剪已有的推荐边,只是不能再用它建立新的归属。

NodeSale · NodeDirectSale

角色 能做什么 谁该持有
DEFAULT_ADMIN_ROLE 授撤角色 多签
SALE_OPERATOR_ROLE 改售价与供应上限、改签名者、暂停 多签
TREASURY_ADMIN_ROLE 改收款地址 treasury / vault 多签

NodeDirectSale 的 USDT 与 FXNW 是两条独立通道,各自定价,价格之间没有换算关系。任一价格设为 0 即关闭该通道。

NodeMaintenance

角色 能做什么 谁该持有
DEFAULT_ADMIN_ROLE 授撤角色 多签
MAINTENANCE_OPERATOR_ROLE 改费率、赠送维护期、暂停 运营
TREASURY_ADMIN_ROLE 改收款地址 多签

赠送维护期不收费,直接给算力。

NodeMintGateway

角色 能做什么 谁该持有
DEFAULT_ADMIN_ROLE 授撤角色 多签
GATEWAY_OPERATOR_ROLE 铸造 L2 节点 仅铸造热钱包,别给第二个地址
GATEWAY_ADMIN_ROLE 改每日铸造上限、暂停 多签

每日上限就是铸造热钱包被盗时一天的损失上界。铸造钱包在 NFT 与 Registry 上不应有任何角色。

NodeCompose

角色 能做什么 谁该持有
DEFAULT_ADMIN_ROLE 授撤角色 多签
COMPOSE_OPERATOR_ROLE 开关合成、暂停 运营

NodeComposeVoucher

用户自助合成的入口。合约自己不铸造,它持有 NodeMintGateway 的 GATEWAY_OPERATOR_ROLE,调 mintComposed。每日上限、originId 唯一性、归因全在网关那边,这里不留第二份状态。

角色 能做什么 谁该持有
DEFAULT_ADMIN_ROLE 授撤角色、setSigner、unpause 多签
PAUSER_ROLE pause 运维 EOA

暂停与恢复不对称:运维一笔交易就能停,恢复要多签。熔断时不能等一轮签名。

它在网关上还必须持有 GATEWAY_OPERATOR_ROLE,这是唯一不可或缺的外部依赖,也是部署最容易漏的一步:漏了之后本合约每一项读数都正常,但每一笔赎回都 revert。「合成凭证」那一页把这个检查放在最上面。

暂停凭证合约只挡自助赎回,worker 代铸那条路径不受影响;两条都要停就连网关一起暂停。

AICClaim

AIC 兑换 FXNW 的链上领取。托管 FXNW,按签名里的累计额付款。

角色 能做什么 谁该持有
DEFAULT_ADMIN_ROLE 授撤角色、setSigner、unpause、recover 多签
PAUSER_ROLE pause 运维 EOA

同样是不对称暂停。recover 只能在暂停状态下执行,金额上限合约不管,由多签自己遵守。

MiningSettlement

角色 能做什么 谁该持有
DEFAULT_ADMIN_ROLE 授撤角色 多签
PUBLISHER_ROLE 发布结算锚点 仅结算热钱包

无任何参数,也不能暂停。只能追加,不能改历史;更正靠追加新版本。

FXNWClaim

角色 能做什么 谁该持有
DEFAULT_ADMIN_ROLE 授撤角色 多签
PUBLISHER_ROLE 发布每期 Merkle 根 仅提现热钱包
CLAIM_ADMIN_ROLE 暂停领取 多签

没有提取函数。注资就是向合约地址转 FXNW。停发下一期加暂停,损失上界是一个注资周期。

FXNW

由项目方部署,不在本项目的角色体系内。见文末「关于 FXNW」。


后端签名者

四个合约各自信任一个后端签名地址,角色不同、函数名也不同。「签名者」那一页把四个放在一起,因为一把 key 泄露时要问的是全部四个。

合约 读 写 需要的角色 签的是什么
ReferralRegistry activationSigner setActivationSigner DEFAULT_ADMIN_ROLE 账户激活授权
NodeSale signer setSigner SALE_OPERATOR_ROLE L1 预售购买授权
AICClaim signer setSigner DEFAULT_ADMIN_ROLE AIC 兑换的链上领取
NodeComposeVoucher signer setSigner DEFAULT_ADMIN_ROLE 自助合成凭证

合约只认当前这一个地址,换掉之后旧签名立即作废,没有宽限期。泄露时的顺序是先暂停、再换签名者、最后恢复。

换掉的代价各不相同:AIC 签的是累计额,谁也不会少领;激活和预售的旧授权作废后用户重新取一份即可;凭证作废后重新 GET 一份,originId 不变所以不会重复铸造。

这些角色不预设在多签里。 按钮是灰是亮,取决于当前连接的钱包在链上是否真的持有对应角色;持有就直接发交易,不持有才给出可粘贴的交易数据。项目方不设多签时同样能用。


常量 · 改就要重新部署

这些是编译期常量,没有 setter,构造函数也不收。改动意味着重新部署加公告。

常量 值 位置 含义
REQUIRED_COUNT 100 NodeCompose 合成一个 L3 所需的 L2 数
FXNW_ONLY_NODE_TYPE 2 NodeDirectSale L2 不开放 USDT 通道
MIN_NODE_TYPE / MAX_NODE_TYPE 2 / 3 NodeDirectSale 直购只卖 L2 和 L3
PERIOD 30 天 NodeMaintenance 维护周期
BPS_DENOMINATOR 10000 NodeDirectSale burnBps 的分母

不在这个控制台里的东西

以下参数不是合约状态,本控制台没有、也不应该有它们的写入口。它们是结算账本的版本化参数,由结算侧的命令行工具写入,改动会进入快照哈希,链上留有指纹。

参数 生效时机
分母下限系数 k 次日结算日起,不追溯
日产率 同上
解锁天数 同上
L2 内盘合成价 立即,可指定生效时刻

本控制台唯一的写路径是钱包签名。它不写数据库,也不调用后端的写接口。


部署顺序

只讲第二阶段这九个合约。FastXNodeNFT、ReferralRegistry、NodeSale 已经在主网跑了三个月,不在部署范围内,它们是新合约要挂上去的既有事实层。

思路是:用部署钱包一把部完,角色和参数全部到这个控制台里配,最后再把最高权限交出去。 这样部署当天不需要每一步都走多签,但代价是有一段窗口期,那把 EOA 私钥掌握全系统。窗口多长由你决定,最后一步必须有截止日期。

部署前必须定死的

这些没有 setter,改就得重新部署:

项 定在哪 说明
usdt / nodeNFT / referralRegistry / fxnw 地址 各合约构造参数,immutable 部署顺序对了就自然对
FXNW 的地址 同上 由项目方提供,见下一节

treasury 和 vault 有 setter,可以事后改,但改到正式地址之前不要开卖,否则钱已经进了部署钱包。

顺序

  1. 拿齐前置:项目方给出 FXNW 地址;定好 treasury 与 vault 的正式地址;准备好铸造热钱包与结算热钱包的地址(可以先留空)。
  2. 部署 Phase B:NodeMaintenance、MiningSettlement。
  3. 部署 Phase C:NodeMintGateway、NodeCompose、NodeDirectSale、FXNWClaim。
  4. 部署 AICClaim 与 NodeComposeVoucher。两者都要 setSigner 指到后端对应的签名 key,都要把 PAUSER_ROLE 授给运维 EOA。
  5. 授合约之间的角色,用 GrantMiningPhaseCRoles 脚本:NFT 的 MINTER_ROLE 给网关、合成、直购;COMPOSER_ROLE 给合成;MAINTENANCE_ROLE 给维护费合约;Registry 的 ATTRIBUTION_RECORDER_ROLE 给前三个。这些地址要合约部出来才知道,所以只能这一步做。
  6. 把网关的 GATEWAY_OPERATOR_ROLE 授给 NodeComposeVoucher。 网关的 admin 在 Phase C 脚本里已移交多签,所以这一笔由多签执行。漏了它,凭证合约读什么都正常,每一笔赎回都 revert。
  7. 在控制台配业务角色:GATEWAY_OPERATOR_ROLE 给铸造热钱包,只给这一个;PUBLISHER_ROLE 给结算与提现热钱包。铸造钱包在 NFT 与 Registry 上不应有任何角色。
  8. 在控制台配参数:直购的两种币价与上限、burnBps、维护费率、每日铸造上限、合成开关。
  9. 开卖前把 treasury 与 vault 改到正式地址,在合约总览里读回确认。
  10. 最后交权:每个合约的 DEFAULT_ADMIN_ROLE 从部署钱包迁到多签,在授权与撤销那一档做。先授多签、在界面上确认多签确实持有、再撤 EOA。顺序护栏会挡住反过来的操作,但挡不了「一直没做」。

窗口期的那把钥匙

第 2 步到第 9 步之间,部署钱包的私钥能铸 NFT、改价格、改收款地址、授撤任何角色。它在这段时间就是全系统最高价值的密钥,按这个等级保管。第 9 步不是「稳定之后再说」,给它一个日期。

关于 FXNW(不由本项目部署)

FXNW 由项目方部署,矿池打多少、什么时候打,都不影响本项目的部署与运行。合约只把它当一个 ERC20 地址收下。

矿池那个钱包没有任何合约引用它,它只是项目方存币的地方。真正要看的是 FXNWClaim 的余额够不够 outstandingAmount,这两个数在合约总览里都能读到。

本项目对那个代币有三条要求,送审的 FastXNetworkToken 三条都满足(ERC20 + ERC20Burnable,无 decimals() override,无转账钩子):

要求 为什么 送审版本
精度 18 直购价、提现金额、界面显示都按 18 位算 未 override,取 OpenZeppelin 默认 18
有公开的 burn(uint256) NodeDirectSale 收到 FXNW 后按 burnBps 销毁自己那一份,没有就每笔直购都失败 继承 ERC20Burnable
转账不收手续费 直购先整额收进合约,再精确拆分销毁与进 vault;到账少于预期会算错 未 override _update / _transfer

送审版本另外没有 mint、没有暂停、没有黑名单,构造完供应量固定,不存在管理员冻结本项目合约的路径。

总量与分配不由代币强制。 构造函数只接收一个 initialSupply 和一个 recipient,全额铸给它。7 亿矿池、3 亿金库那个拆分是项目方部署后自己转出去的,链上没有约束。因此不要假设读到的 totalSupply 一定是 10 亿。

拿到地址后,在合约总览的 FXNW 那一行核对 symbol 与 decimals,精度不是 18 会显著标出。

提现开放之前,FXNWClaim 不需要有钱;注资就是往合约地址转 FXNW,按期注即可。