基于法币定价的稳定订阅支付机制
引言
在 ArcBlock 生态中,目前链上还没有发行稳定币(如 USDT)。因此,Dapp 需要使用原生代币 ABT(ArcBlock Token)作为支付手段。然而,ABT 作为非稳定币,其价格存在波动,这为服务的定价和支付带来了挑战。
在去中心化应用(Dapp)中,使用加密货币作为支付手段已成为常见做法。然而,加密货币价格的剧烈波动为定价和支付带来了显著挑战。当服务价格以代币数量表示时,代币价格的波动会导致用户实际支付的法币价值不断变化,既不利于用户形成稳定的支付预期,也给运营方的定价策略带来困扰。
本文介绍了一种基于法币定价的稳定订阅支付机制,该机制以法币(USD)作为基础定价单位,通过实时价格转换将法币价格转换为代币数量,同时通过订阅周期锁定策略平衡价格波动的影响,为用户和运营方提供了更加稳定和可预期的支付体验。

问题分析
加密货币价格波动带来的不确定性
加密货币市场以价格波动剧烈而闻名。以 ABT(ArcBlock Token)为例,其价格可能在短期内出现较大幅度的波动。如果服务价格直接以代币数量表示,用户在不同时间点支付相同数量的代币,实际对应的法币价值可能差异巨大。
这种不确定性给用户带来困扰。用户在订阅服务时,无法准确预估未来需要支付的法币金额,因为代币价格的变化可能导致实际成本大幅波动。对于需要长期订阅的服务,这种不确定性更为明显。
传统定价方式的局限性
传统上,Dapp 的定价方式主要有两种:直接以代币数量定价,或固定代币数量但允许运营方频繁调整。前者导致价格波动问题,后者则需要运营方频繁更新定价,增加了运营成本,同时也可能因调整不及时而出现不公平的情况。
另外,如果定价信息存储在链下或中心化系统中,用户难以验证定价的真实性和一致性,可能存在不同用户看到不同价格的问题。
对用户和运营方的双重挑战
价格波动对用户和运营方都构成了挑战。对用户而言,价格波动使得预算规划变得困难,可能因为代币价格上涨而被迫支付超出预期的费用。对运营方而言,频繁的价格调整不仅增加了运营成本,还可能因为调整滞后而面临收入损失或用户流失的风险。
因此,需要一种既能让用户形成稳定支付预期,又能减少运营方定价调整频率的解决方案。
设计思路
法币定价作为基础
核心思路是以法币(USD)作为定价的基础单位。服务的价格以 USD/DAY 的形式定义和存储,例如某个服务层级(tier)的日定价为 1.5 USD/DAY。这种定价方式与用户日常使用的货币单位一致,便于用户理解和比较。
定价信息存储在链上 NFT 的 data 字段中,确保所有用户看到的价格一致,同时价格变更的透明性和可追溯性也得到保障。
实时价格转换机制
虽然定价以法币为基础,但实际支付仍然使用代币(ABT)。因此需要将法币价格实时转换为代币数量。转换公式简单直接:
ABT数量 = USD价格 / ABT当前价格
例如,如果服务价格为 1.5 USD/DAY,当前 ABT 价格为 0.27 USD,则用户每天需要支付约 5.56 ABT。
价格转换是实时进行的。系统通过外部价格 API(CoinGecko 或 CryptoCompare)获取最新的 ABT 价格,并在用户申请订阅时根据当前价格计算所需支付的 ABT 数量。前端界面也会实时显示基于当前价格的 ABT 支付金额,帮助用户做出决策。
订阅周期锁定策略
为了平衡价格波动的影响,系统引入了订阅周期锁定机制。用户可以选择订阅周期(1 到 30 天),在选定的周期内,系统会按照周期开始时的价格计算 ABT 支付数量,并在整个周期内保持该数量不变。
周期结束后,如果用户继续订阅,系统会根据新的价格重新计算下一个周期的 ABT 支付数量。这样既保证了单个周期内的支付稳定性,又通过周期性的价格重算来适应长期的价格变化。
例如,用户选择 7 天的订阅周期。在第一个周期开始时,如果当前 ABT 价格为 0.27 USD,1.5 USD/DAY 的服务价格对应约 5.56 ABT/DAY,则用户在这 7 天内每天支付 5.56 ABT。如果 7 天后 ABT 价格变为 0.30 USD,下一个周期将按照新价格计算,1.5 USD/DAY 对应 5.00 ABT/DAY。
实现机制
定价流程
定价流程从 Hub Node NFT 的配置开始。每个 Hub Node 在其 NFT 的 data.pricing 字段中定义了不同服务层级(basic、pro、premium、enterprise)的日定价,单位为 USD/DAY。
用户在选择服务时,首先看到的是以 USD/DAY 表示的价格。系统会实时获取当前的 ABT 价格,并计算对应的 ABT 支付数量,在界面上同时显示法币价格和代币数量。
用户选择订阅周期后,系统会根据当前价格和订阅周期计算总支付金额。用户确认并同意支付授权协议后,系统将申请信息提交到 Hub,其中包含订阅周期参数。
ABT 数量计算
ABT 数量的计算在前端实时进行。系统获取当前的 ABT 价格和用户选择的服务层级对应的 USD/DAY 价格,通过简单的除法运算得到 ABT 支付数量。
在 HubDetailDrawer 组件中,ABT 支付数量的计算公式为:
const abtAmount = nodePricing[selectedTierName] / abtPrice.price;
这个计算结果会实时显示在界面上,帮助用户了解需要支付的代币数量。价格数据的具体获取机制和缓存策略将在技术实现要点中详细说明。
周期锁定机制
订阅周期由用户在前端界面中设置,范围为 1 到 30 天。用户在提交申请时,订阅周期参数(subscriptionPeriod)会随申请信息一起发送到 Hub。
Hub 在审核通过后开始扣费。每个周期开始时会根据当前的 ABT 价格重新计算该周期的 ABT 支付数量,并在整个周期内保持该数量不变。周期结束时,如果用户继续订阅,系统会根据新的价格计算下一个周期的支付数量。
支付授权协议中明确说明了这一机制:每个周期将根据当前价格重新计算扣费金额。如果扣费失败或余额不足,入住将自动取消。用户可以随时取消入住并撤回授权,取消将在下一个扣费日生效。
优势分析
对用户的优势
最直接的优势是稳定的支付预期。用户在选择服务时,能够清楚地知道每天需要支付多少法币,不会因为代币价格波动而产生意外成本。虽然代币数量可能会随价格变化而调整,但法币价值保持稳定,符合用户的日常认知和预算规划习惯。
周期锁定机制进一步增强了稳定性。在用户选择的周期内(最长 30 天),支付数量保持不变,用户可以在这个周期内放心使用服务,无需担心价格波动的影响。
此外,法币定价使得不同服务之间的价格比较变得简单直观。用户可以直接比较不同 Hub Node 或不同服务层级的 USD/DAY 价格,而无需考虑代币价格的影响。
对运营方的优势
运营方无需频繁调整定价。由于定价以法币为基础,运营方只需要在必要时调整 USD/DAY 的价格,而无需因为代币价格波动而不断更新定价。这大大降低了运营成本。
周期性的价格重算机制也平衡了价格波动对收入的影响。虽然单个周期内的支付数量锁定,但周期结束后会根据新价格重新计算,避免了因价格长期上涨而导致的收入损失。
定价信息存储在 Hub Node NFT 中,使得价格公开透明,所有用户都可以查询和验证。每个 Hub 可以设置自己的价格,提供不同品质的服务,这种灵活性使得 Hub 运营方能够根据自身服务水平和市场定位制定合适的定价策略。然而,Hub Node NFT 被质押用于提供服务,如果运营方需要修改价格,必须先解除质押,这会导致服务暂时中断。虽然中断时间通常较短,但仍然会对用户体验产生负面影响。因此,基于法币定价的机制减少了价格调整的频率,避免了频繁解除质押和服务中断的问题,这对于维护服务的连续性和用户体验具有重要意义。

公平性保障
链上存储的定价信息确保了价格的一致性。所有用户从同一个链上 NFT 读取价格信息,不会出现不同用户看到不同价格的情况。
价格转换基于公开的价格 API,用户可以验证价格来源和计算的正确性。系统优先使用 CoinGecko API 获取价格,失败时回退到 CryptoCompare API,确保价格数据的可靠性。
周期锁定机制对所有用户一视同仁。每个用户在各自的订阅周期内享受价格锁定,周期结束后统一按照新价格重新计算,保证了公平性。
技术实现要点
价格获取机制
价格获取分为前端和后端两个层面。后端提供 /api/manage/hub-network/abt-price API 接口,从外部价格服务获取 ABT 价格。系统优先使用 CoinGecko API,如果请求失败或超时,则自动回退到 CryptoCompare API。每个 API 请求设置 5 秒超时,避免长时间等待。
后端使用 LRU 缓存机制,缓存时间为 60 秒。在缓存有效期内,直接返回缓存的价格数据,减少对外部 API 的调用频率,提高响应速度并降低 API 调用成本。
前端使用 Jotai 的异步 atom(abtPriceState)管理价格状态。价格数据同样具有缓存机制,每分钟自动刷新一次。如果价格获取失败,系统会使用缓存中的旧价格,确保界面能够正常显示。
转换计算
价格转换计算在前端实时进行。当用户选择服务层级时,系统获取对应的 USD/DAY 价格和当前的 ABT 价格,通过除法运算得到 ABT/DAY 数量:
const abtAmountPerDay = usdPricePerDay / abtPrice;
计算结果显示在界面上,帮助用户了解需要支付的代币数量。计算精度保留到小数点后 4 位,确保足够的精度。
对于订阅周期的总支付金额,系统会根据日价格和周期天数进行计算,但实际支付时每个周期会根据当时的市场价格重新计算,确保支付金额反映实际的市场价格。
锁定逻辑
订阅周期的锁定逻辑在 Hub 端实现。用户提交申请时,订阅周期参数随申请信息一起发送到 Hub。Hub 在审核通过后开始扣费流程。
每个周期开始时会根据当前的 ABT 价格计算该周期的支付数量,并在整个周期内保持不变。周期结束时间由 Hub 根据订阅开始时间和周期天数计算得出。
如果用户在周期中途取消订阅,取消操作将在下一个扣费日生效,当前周期的费用仍然需要支付,保证了运营方的收入稳定性。
总结
基于法币定价的稳定订阅支付机制通过将定价单位从代币转换为法币,结合实时价格转换和订阅周期锁定策略,有效解决了加密货币价格波动带来的定价和支付问题。
这一机制既保证了用户能够形成稳定的支付预期,又减少了运营方的定价调整频率,同时通过链上存储和公开的价格 API 确保了价格的透明性和公平性。在实际应用中,该机制已经得到了验证,为用户和运营方都带来了更好的体验。
需要说明的是,这是一个临时方案。在不久的将来,ArcBlock 将推出稳定币。当稳定币可用后,当前的机制可以很平滑地过渡到使用稳定币进行支付。由于定价已经以法币(USD)为基础,只需要将支付代币从 ABT 切换为稳定币即可,无需改变定价逻辑和用户界面,实现了向后兼容和无缝迁移。此外,系统还支持用户选择使用稳定币支付,或者继续使用 ABT 支付,在使用 ABT 支付时系统会执行自动兑换,为用户提供了灵活的支付选择。