免责声明
NKaspa 目前是 alpha 版本(0.1.11-alpha),未经安全审计。本文是开发者说明,不是投资或安全审计意见。确认数阈值需按业务风险自选。文中「固定合约时钟」为社区提案,「covenant UTXO 查询」为已合并但未发版的节点能力展望。请先在 testnet 用小额验证。
这是一篇面向 C#/.NET 开发者的短 FAQ:Kaspa 的 DAA score 是什么,用 NKaspa 怎么读出来;确认数在 NKaspa 样例里怎么算、和常见的 blue score 确认有什么不同;lock time 与 sequence 相对锁在 Kaspa 里怎么编码,对应哪些 NKaspa 类型和操作码。代码点对照 NKaspa db56f27(0.1.11-alpha)。NKaspa 是非官方的社区 .NET 库,与 Kaspa 核心团队无隶属关系。
DAA score 是什么(协议层)
什么是 Kaspa DAA score?
DAA score 是衡量网络进度的累计分数,计入蓝块以及被合并且获得奖励的红块,大致随出块速率增长;它被用于升级激活、时间估算和一部分 lock time 条件(Kaspalytics Glossary)。按当前的出块速率,DAA score 大约每秒增加 10(kaspa.news,2026-11-07)。
在 NKaspa 里怎么读到当前的 DAA score?
有三种方式,都返回 ulong:
- 一次性读取:
GetServerInfoAsync()→RpcServerInfo.VirtualDaaScore。 - 订阅推送:
NotifyVirtualDaaScoreChangedAsync(...),回调参数RpcVirtualDaaScoreChanged.VirtualDaaScore(AspNetCheckout 样例的PaymentMonitor就用这个)。 - DAG 信息:
GetBlockDagInfoAsync()的结果RpcBlockDagInfo里也有VirtualDaaScore。
BlockDaaScore 是什么?
它是创建某个 UTXO 的那个区块的 DAA score,字段为 UtxoEntry.BlockDaaScore(ulong)。在脚本里,可以用 KIP-17 内省操作码 OP_TXINPUTDAASCORE(0xc0,NKaspa 构建辅助 ScriptBuilder.TxInputDaaScore())读取被花费 UTXO 的这个值。
Kaspa 确认数:NKaspa 样例怎么算
NKaspa 里确认数怎么算?
NKaspa 本身没有「查询某笔交易确认数」的 API,AspNetCheckout 样例是自己算的。公式在 ConfirmationPolicy.cs:
// currentScore:当前 virtual DAA score;blockDaaScore:UtxoEntry.BlockDaaScore public static ulong Confirmations(ulong currentScore, ulong blockDaaScore) => currentScore > blockDaaScore ? currentScore - blockDaaScore : 0; 也就是「当前 virtual DAA score − 该 UTXO 的 BlockDaaScore」,当前值不领先时记为 0。这是一个深度近似,不是协议定义的唯一确认数。
默认需要 100 个确认是安全值吗?
不是。样例配置 Checkout:RequiredConfirmations 默认 100,README 明确写着这是演示值,不是安全建议。阈值应按你的业务风险自己定,并写进产品规则。
这和 Kaspalytics 说的 blue score 确认一样吗?
不一样。Kaspalytics Confirmations & Finality 给出的公式是「sink blue score − 接受该交易的区块(accepting block)的 blue score」,衡量交易被接受进虚拟选定父链(VSPC)之后的深度,按当前 10 BPS 大约每秒增长 10;NKaspa 样例默认用的是 DAA score 差值。两者尺度不同,没有谁更「正确」,产品需要自己选定一种并写清楚。
AspNetCheckout 能换成 blue score 吗?
可以。Checkout:ConfirmationSource 默认 DaaScore,也可以设为 SinkBlueScore(通过 GetSinkBlueScoreAsync 取当前值)。README 说明这只是粗略距离:BlockDaaScore 是 DAA 尺度,拿 sink blue score 去减它,结果和 DAA 差值不是同一尺度。还要注意一个细节:PaymentMonitor 首次 Connect 时,当前分数仍先取 GetServerInfoAsync 返回的 VirtualDaaScore;之后每次轮询才用 GetSinkBlueScoreAsync 刷新,而且在这个模式下 DAA 推送通知不会更新分数。
想亲手看一看?在 testnet 跑一遍 AspNetCheckout,打印
VirtualDaaScore和BlockDaaScore:github.com/lifeme2027/NKaspa/tree/main/samples/AspNetCheckout(该样例只在 main 分支,不在 0.1.11-alpha 的 NuGet 包内)。
Kaspa lock time:绝对时间锁 Transaction.LockTime
Kaspa 的 lock time 怎么编码?
Transaction.LockTime 是 ulong,按数值分三种情况(Aspectron Time Locks、Kaspalytics Glossary、rusty-kaspa 校验逻辑;NKaspa 常量 ScriptLimits.LockTimeThreshold = 500_000_000_000):
LockTime 值 | 含义 |
|---|---|
0 | 不加锁 |
< 500_000_000_000 | 最小 DAA score |
≥ 500_000_000_000 | Unix 毫秒时间戳 |
阈值与 rusty-kaspa 的 LOCK_TIME_THRESHOLD 一致(brief §12 [S5] 已核)。
CLTV 在 NKaspa 里怎么校验?
OP_CHECKLOCKTIMEVERIFY 在 Kaspa 里是 0xb0。脚本引擎 TxScriptEngine.OpCheckLockTime 要求:
- 栈顶值和
tx.LockTime必须同属一类(都是 DAA score,或都是时间戳),否则失败; - 栈顶值不能大于
tx.LockTime; - 当前输入的
Sequence不能是ulong.MaxValue(即该输入不能已「最终化」)。
构建脚本时,可以用 KIP-17 内省 OP_TXLOCKTIME(0xb5,ScriptBuilder.TxLockTime())把交易的 lock time 压栈。
相对时间锁:TxIn.Sequence
Kaspa 的 sequence 有多大?
NKaspa 里 TxIn.Sequence 是 ulong(64 位),比特币通常是 32 位。和 NBitcoin 的类型对照见仓库 docs/NBitcoin-Mapping.md。
相对锁怎么编码?
按 Aspectron Time Locks:bit 63 置位表示相对锁禁用(ScriptLimits.SequenceLockTimeDisabled = 1UL << 63)。在 OP_CHECKSEQUENCEVERIFY 里,这一位要分两边看:如果栈上的操作数设了这一位,CSV 直接通过、不做任何检查(相当于空操作);如果栈上没设、但当前输入的 Sequence 设了这一位,CSV 校验失败;两边都没设时,才比较低 32 位,栈上的值不能大于输入的值。低 32 位(bits 0–31,无符号 32 位整数)是相对锁的值(ScriptLimits.SequenceLockTimeMask = 0xffffffff)。脚本侧对应 OP_CHECKSEQUENCEVERIFY(0xb1,引擎 OpCheckSequence),内省 OP_TXINPUTSEQ(ScriptBuilder.TxInputSeq(),见 KIP-17)。
CLTV / CSV 的操作码编号和比特币一样吗?
不一样。Kaspa 里 OP_CHECKLOCKTIMEVERIFY = 0xb0、OP_CHECKSEQUENCEVERIFY = 0xb1;比特币里 CLTV 是 0xb1、CSV 是 0xb2(NKaspa OpcodeType.cs 注释也写明了这一点)。从比特币移植脚本时,不要直接照搬字节。
用 DAA score 写「等一段时间再花」
能用 DAA score 写「存满 N 个 DAA 点才能花」吗?
思路上可以:用 OP_TXINPUTDAASCORE 读出被花费 UTXO 的创建 DAA score,再与 CLTV 或数值比较组合,表达「从创建起至少经过 N 个 DAA 点」之类的规则。具体脚本请先在 testnet 上验证。需要提醒的是:DAA score 的增速随出块速率变化,同样的 N 对应的墙钟时间并不固定,见下一节。
展望 A:固定 10 tick/秒的合约时钟(提案)
出块速率上升后,按 DAA 计的时间锁会怎样?
DAA score 与出块速率相关,如果每秒出块数(BPS)上升,「按 DAA 计的一段时间」对应的墙钟时间会变短,长期归属释放这类锁会受影响。据 kaspa.news 2026-11-07《Like clockwork…》报道,Michael Sutton 正在权衡(weighing)一个 KIP 方向:让合约脚本看到的时钟固定在每秒 10 个 tick;讨论中也有人建议保留原始 DAA score 供需要的应用读取。
这是现行规则吗?
不是。这是社区讨论中的提案,尚未成为现行共识规则,也还没有正式的 KIP 编号。不要按「即将上线」或「已激活」来设计合约。
展望 B:rusty-kaspa PR #1152(covenant UTXO 查询)
现在能用 NKaspa 按 covenant id 列 UTXO 吗?
还不能。rusty-kaspa PR #1152 已于 2026-11-03 合并(上海时间 22:24),新增可选的 --covenant-index 和分页 RPC GetUtxosByCovenantIds(按当前 covenant id 精确匹配)。但截至 2026-11-09,rusty-kaspa 最新正式 Release 仍是 v2.1.0(2026-09-22 发布),所以它尚未进入正式节点发版;NKaspa 目前也没有封装这个 RPC。等官方发版后再评估 NKaspa 是否跟进,和本 FAQ 分开排期。
其他
能把本文当作上线真实资金的安全规范吗?
不能。NKaspa 是 alpha、未经审计;确认阈值请按自身风险建模,先在 testnet 用小额验证。
下一步
- 用 C# 连接 Kaspa 节点并发交易(dev.to 教程):英文 · 中文
- AspNetCheckout 收款教程(另稿,待发布)
- covenant 专题(等 PR #1152 随正式版发布后再写)
- NKaspa 源码:github.com/lifeme2027/NKaspa;NKaspaDoc 文档仓库:github.com/lifeme2027/NKaspaDoc
- 外部参考(访问日期 2026-11-09):
在 testnet 跑一遍 AspNetCheckout,亲手打印 VirtualDaaScore 与 BlockDaaScore:github.com/lifeme2027/NKaspa/tree/main/samples/AspNetCheckout
觉得有用就给 NKaspa / NKaspaDoc 点个 Star。
免责声明
NKaspa 目前是 alpha 版本(0.1.11-alpha),未经安全审计。本文是开发者说明,不是投资或安全审计意见。确认数阈值需按业务风险自选。文中「固定合约时钟」为社区提案,「covenant UTXO 查询」为已合并但未发版的节点能力展望。请先在 testnet 用小额验证。
