工程
为什么每个余额都必须来自复式记账账本
2026年7月27日 · 9 分钟阅读 · Coreza
每个银行系统里都有一张表,回答着产品中最重要的问题:这位客户有多少钱?把可靠核心与脆弱核心区分开的设计决策,在于这个数字是被存储的——一个由某人更新的字段——还是被推导的——一个仅可追加账本的求和结果。这听起来像实现细节,实际上却是“能够证明自己余额的系统”与“只能声称自己余额的系统”之间的差别。
这是金融科技核心系统中影响最深远的架构决策,而它在演示中几乎不可见。两个产品在屏幕上可以看起来一模一样,其中一个就地更新余额字段,另一个则从复式记账账本推导每个余额。差别会在之后浮现——在对账断裂中、在没人能解释的客服工单中、在审计中。
复式记账在工程语境下意味着什么
复式记账已有五个世纪的历史,但在银行后端它不是会计形式主义——它是由数据库强制执行的不变量。每一笔资金流动都是一笔至少包含两条分录的交易:一个账户被借记,另一个被贷记,分录之和为零。资金从不因一条 UPDATE 语句而被创造或销毁;它只在账户之间移动,而移动本身就是记录。
客户余额因此是一个投影:账本中触及该账户的所有分录之和。为了性能可以缓存,没问题——但它始终可以重算,而重算结果才是真相。一旦缓存与账本出现分歧,以账本为准,而分歧本身就是需要调查的信号。
零和不变量带来一个任何存储型余额设计都无法提供的属性:整个系统是可校验的。把每个账户的每条分录加总——客户钱包、手续费收入、服务商清算账户、暂记账户——总和为零。任何丢钱的 bug、竞态或部分失败都会破坏这个等式并因此变得可检测,通常当天即可发现。
存储型余额如何漂移
余额字段设计的失效模式并不戏剧化,而是由日常生产流量造成的缓慢漂移:
- 并发:两笔提现在同一时刻读取同一余额,双双通过校验,双双写入。没有账本,就没有关于余额本应是多少的记录。
- 重试与部分失败:支付服务商超时,客户端重试,入账落了两次——或者在“更新余额”与“记录交易”之间发生崩溃,让两者永久不一致。
- 手工操作:一名支持工程师用一条直接的 UPDATE 解决了投诉。客户满意了;凭空出现的钱没有来源,任何报表都永远无法解释它。
- 手续费与舍入:手续费在一处计算、在另一处收取,汇率换算在两侧以不同方式舍入——一分钱的零头日积月累,成为真实的差异。
账本强加给你的规则——每一条都是好规则
承诺采用推导型余额,会给核心系统的其余部分带来纪律。这些约束在第一天显得严苛,到第三年就会证明它们正是系统保持正确的原因:
- 金额用最小单位的整数表示——分、satoshi、wei——绝不使用浮点数。二进制浮点无法精确表示 0.10;一套必须加总为零的账本,不能建立在“几乎能对上”的数字之上。
- 分录不可变:已入账的分录从不编辑或删除。错误按银行一贯的方式纠正——用一条冲正分录,让错误与更正同时留在记录上。
- 幂等性:每个操作都携带一个键,重试的请求只会入账一次。账本让重复变得可见;幂等性防止重复发生。
- 原子性:借记、贷记与业务状态变更要么一起提交,要么都不提交。没有任何代码路径会在账本交易之外更新余额——包括管理性调整,它们成为普通的、可归属的分录,而不是无声的覆写。
对账:向外部世界证明
内部不变量证明系统与自身一致,对账则证明系统与现实一致。金融科技核心与外部各方持有头寸——银行通道、卡处理机构、区块链网络——每一方都保存着自己的真相版本。每日对账把每份服务商对账单和每个链上头寸与账本中对应的账户逐一比对,并强制解释每一笔差异:在途清算、尚未入账的服务商手续费,或者一笔真正的断裂——当天就会得到暂记分录和责任人。
对账是这套架构收回成本的地方。有了复式记账账本,一笔断裂是一次有边界的搜索:它出现的那一天、触及的账户、涉及的分录。而在存储型余额下,同样的调查要从一个没有历史的数字开始——这也是为什么余额字段系统里未对平的差异往往被一笔勾销,而不是被解决。
加密资产让赌注更高。链上余额是公开的:任何人都可以把您控制的钱包与您展示给客户的余额进行比对。自托管若没有每日与链对账的账本,就是一笔等着被公司外部的人发现的差异。
审计人员和监管机构究竟会问什么
受监管的金融科技公司迟早会面对同一个问题的某个版本:证明客户余额是正确的。务实的答案是一条证据链——每个余额都从仅可追加的账本推导而来;账本加总为零;每天与每个外部头寸对账;一份不可篡改、以哈希链相连的审计日志记录着每笔流动由谁发起、来自哪台设备、经过谁的审批。
建立在存储型余额之上的团队用取证来回答这些问题——在最糟糕的时刻、顶着期限,从应用日志和服务商导出的数据里重建历史。拥有账本的团队用一条查询来回答。审计不会创造这个要求;它只是揭示架构是否从一开始就满足了它。
对任何核心银行平台都该做的测试
如果您正在评估一个平台——或审视自己构建的那个——这些问题五分钟就能问完,而答案很难作假:
- 客户屏幕上的数字从哪里来?如果答案是余额字段而不是账本投影,其余一切都只是装饰。
- 能否在不产生账本分录的情况下改动余额?要特别追问管理工具和客服流程——无声的 UPDATE 就藏在那里。
- 金额是否端到端都是最小单位的整数,包括加密侧?
- 请出示昨天的对账:每家服务商、每条链、每笔差异都有解释。拿不出来的平台,就是没有在做。
- 记账错误如何更正?唯一的好答案是一条冲正分录,归属到具体的人,并经过审批流程。
Coreza 的立场
Coreza 建立在这套设计的严格版本之上:每个余额——法币与加密——都从复式记账账本推导而来;金额在系统各处都是最小单位的整数;已入账分录不可变,更正通过冲正分录完成并经双人复核审批;每个实例每天与每家已接入的服务商、每条运行中的链对账。审计日志仅可追加并以哈希链相连,记录每笔流动的何人、何时与何地。
这一切在产品演示中都看不到,而这正是本文的意义所在:账本是核心银行平台中无法靠看界面来评估的那一部分。这套核心的一个版本自 2024 年起在一家受监管的欧洲金融科技公司处理着真实客户与真实资金——上面那五个问题,我们建议您拿去问任何平台,包括我们自己的。