研究代码,处于早期脚手架阶段。 本仓库实现了
PROJECT_SPEC.md以及spec/下规范文档所 指定的协议。按照本项目的代币模型,代币不具有任何外部货币价值,本系统 也不是受监管的赌博产品。参见 LICENSE。
cardtable 是一个面向 Bitcoin SV(Genesis 升级之后)的多人纸牌游戏协议,
具有交易原生、点对点、非托管的特性。每一个游戏事件都是一笔经过签名的 BSV
交易;每一个游戏状态都是一个已承诺的 UTXO,它有一个协作型后继分支和一个
超时默认后继分支;每一种失败模式都解析为一个确定性的链上后果,而不是依赖
人工运营层面的判断。
首个生产目标:In-Between(Acey-Deucey)。
| 文件 | 作用 |
|---|---|
PROJECT_SPEC.md |
实施构建规范;编码标准;项目结构;构建顺序;禁止事项清单 |
spec/ |
按方面划分的协议规范(状态机、交易类型、脚本模板、超时规则、恢复规则、序列化、排序、纸牌协议、线路协议、对手方发现) |
spec/test-vectors/ |
将每个实现绑定到完全一致行为的权威输入/输出向量 |
docs/adr/ |
架构决策记录,涵盖在不确定性下做出的每一项设计选择 |
- 客户端: TypeScript(strict 模式)、React 18、Vite、Zustand、Dexie、Web Crypto、BSV TypeScript SDK
- 后端: Go 1.22+、WebSocket 中继、Aerospike、Kafka、BSV Go SDK
- 不在范围内: 链下支付网络、二层 rollup、替代性脚本扩展、用于游戏状态的 Postgres/Redis、ORM、GraphQL、由服务器托管的游戏状态。每一次状态转换都在链上进行。
- 规范 + protocol-types — 编写
spec/以及protocol-types包 - 状态引擎 + 脚本模板 — 确定性规则 + BSV 脚本构造
- 公开信息原型 — 不含隐藏牌的桌面流程
- 隐藏单张牌 — 熵的承诺/揭示、加密的纸牌 UTXO
- 多张牌 In-Between — 完整游戏、预签名的回退图、对局记录重放
- 对抗性加固 — 全部 14 个命名场景 + 确定性重放
在本次提交时,本仓库处于 Phase 0(仅有骨架)。后续提交将依次填充 每个阶段。
cardtable/
├── PROJECT_SPEC.md, README.md, LICENSE
├── spec/ # 协议规范(协议行为的权威来源)
├── packages/ # 共享的 TypeScript 包
│ ├── protocol-types/
│ ├── state-engine/
│ ├── script-templates/
│ └── crypto-cards/
├── apps/ # 可运行的服务
│ ├── client-web/ # React + Vite 浏览器客户端
│ ├── relay-go/ # Go WebSocket 中继
│ ├── indexer-go/ # Go 索引器服务
│ └── spv-service-go/ # Go SPV 证明 / 区块头服务
├── tests/ # 跨包测试与对抗性测试
├── tools/ # 模拟器、对局记录校验器
└── docs/ # 架构说明、ADR、运维手册
空的子目录会用一个 .gitkeep 文件保持被追踪状态,直到对应阶段将其填充。
- 依据 BSV 共识与 Genesis 升级之后的操作码集合进行构建。 仅使用 BSV TypeScript / Go SDK。
- 在 BSV Genesis 升级之后,Script 是图灵完备的。 时间锁位于交易层级(
nLockTime、输入的nSequence);任何 cardtable 模板都不使用脚本内的时间锁操作码。 - 代币不具有外部价值。 本系统不是受监管的赌博产品。
- 零虚构。 每一个数字、论断和技术陈述都可追溯到某个来源,否则就被标记 为一项假设并附带可追踪的责任项。
- 无隐性假设。 隐藏的假设即为缺陷;必须在文档表面明确声明。
# 1. 安装
pnpm install
# 2. 在本地运行全部 TS + Go 测试套件(离线)
pnpm ci # 工作区构建 + 测试
(cd apps/relay-go && go test -v ./...) # Go 测试套件
# 3. 在本地运行中继
(cd apps/relay-go && go build -o ../../bin/relay ./cmd/relay)
./bin/relay --addr :8080 --ws-addr :8081 \
--game 00000000000000000000000000000000000000000000000000000000000000aa \
--start-height 100
# 4. 对运行中的中继执行一整轮心智扑克(mental poker)
CARDTABLE_RUN_LIVE=1 \
CARDTABLE_RUN_FULL_ROUND=1 \
CARDTABLE_WS_URL=ws://localhost:8081/ws \
CARDTABLE_GAME_ID=00000000000000000000000000000000000000000000000000000000000000aa \
pnpm --filter @cardtable/integration-tests test
# 5. 或使用 Docker
docker compose up --build relay # 本地构建
docker run -p 8080:8080 -p 8081:8081 \
ghcr.io/prof-faustus/cardtable-relay:latest # 已发布的多架构镜像浏览器客户端:
(cd apps/client-web && pnpm vite build && pnpm vite preview --port 4173)
# 然后打开 http://localhost:4173 并点击 “Connect to relay”录制一份对局记录并离线校验它:
node ./tools/transcript-recorder/dist/index.js \
--ws ws://localhost:8081/ws \
--game-id 00000000000000000000000000000000000000000000000000000000000000aa \
--out ./session.jsonl
node ./tools/transcript-verifier/dist/index.js \
--transcript ./session.jsonl \
--game-id 00000000000000000000000000000000000000000000000000000000000000aa
# 或使用 Go 侧的审计工具:
(cd apps/relay-go && go build -o ../../bin/indexer ./cmd/indexer)
./bin/indexer --transcript ./session.jsonl \
--game-id 00000000000000000000000000000000000000000000000000000000000000aa快速上手流程在 Linux/macOS 以及 CI 中可直接使用。在 Windows 主机上会遇到 几个环境上的怪癖;应用以下方法后,所有测试套件即可通过:
-
pnpm install报错UNABLE_TO_VERIFY_LEAF_SIGNATURE—— 这是由企业 TLS 检查对 npm registry 重新签名所致。通过 Node 的系统 CA 标志信任 Windows 根证书库(Node ≥ 22):$env:NODE_OPTIONS = "--use-system-ca" pnpm install
在执行
pnpm install/build/test时保持设置NODE_OPTIONS=--use-system-ca。 -
go test ./...报告... contains a virus or potentially unwanted software并失败 —— 这是主机杀毒软件(例如 Norton/Defender)将刚刚链接 生成的 Go*.test.exe二进制文件隔离所产生的误报(通常由pkg/wire测试二进制文件触发)。代码本身没有问题。使用-trimpath构建测试二进制 文件即可——它对链接产物的改动足以避开该启发式检测——并将其设为默认:go env -w GOFLAGS=-trimpath go test ./... # 现在一条命令即可全绿
一次冷启动的完整重链接(先
go clean -testcache再go test ./...)在 杀毒软件同时扫描每个新二进制文件时,仍可能间歇性地使一个时序敏感的测试 (internal/spv/TestHTTPHeightSource_TracksLatest,一个 2 秒的 HTTP 轮询 截止期限)出现偶发失败。热重跑是稳定的。要彻底消除该问题,请在杀毒软件中 为 Go 的临时目录添加文件夹排除项(用go env -w GOTMPDIR=C:\Users\<you>\go-tmp设定一个稳定的目录并排除该文件夹)。 -
端口
8081已被占用 —— 在运行 WSL 的机器上,wslrelay.exe会绑定127.0.0.1:8081。请在另一个端口上运行中继,并让集成测试指向该端口:.\bin\relay.exe --addr :8092 --ws-addr :8091 ` --game 00000000000000000000000000000000000000000000000000000000000000aa --start-height 100 $env:CARDTABLE_WS_URL = "ws://127.0.0.1:8091/ws"
live-full-round集成测试与在线浏览器冒烟测试都各自需要一个全新的中继 (中继在内存中保存对局状态,因此复用的座位会发生冲突)。请在两次运行之间 重启中继。
完整通读 PROJECT_SPEC.md 以及 spec/ 下按方面划分的规范文档。然后查看
STATUS.md 了解当前阶段以及尚存的实质性缺口。测试与其代码放在一起:
packages/*/__tests__/、apps/relay-go/**/_test.go,以及位于
tests/integration/ 和 tests/browser-smoke/ 下的跨系统测试套件。