免责声明
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 要求:

  1. 栈顶值和 tx.LockTime 必须同属一类(都是 DAA score,或都是时间戳),否则失败;
  2. 栈顶值不能大于 tx.LockTime;
  3. 当前输入的 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 用小额验证。

下一步

在 testnet 跑一遍 AspNetCheckout,亲手打印 VirtualDaaScore 与 BlockDaaScore:github.com/lifeme2027/NKaspa/tree/main/samples/AspNetCheckout

觉得有用就给 NKaspa / NKaspaDoc 点个 Star。

免责声明
NKaspa 目前是 alpha 版本(0.1.11-alpha),未经安全审计。本文是开发者说明,不是投资或安全审计意见。确认数阈值需按业务风险自选。文中「固定合约时钟」为社区提案,「covenant UTXO 查询」为已合并但未发版的节点能力展望。请先在 testnet 用小额验证。