概念
挖矿与出块
任何人都能用普通 CPU 出 Ksana 区块。运行一个节点,配上出块者账户和比特币出资钱包,用 Argon2id 挖矿,你出的区块、你写进比特币的数据,都会为你挣来 KSA。
出块对任何人开放:不用质押,不用注册,也不用谁许可。出块者就是一个 ksana-node:它收集操作、执行操作、求解工作量证明,并出钱把自己区块的数据写进比特币,以此挣得 KSA。主网还没有上线,所以现在挖矿要在公开 signet 上进行。运行节点一页有逐步的设置说明。
出块者需要什么
- 一个节点和 bitcoind:带
--producer <account>运行的ksana-node,这个账户接收你的奖励;节点连接同一网络上的 bitcoind(以-txindex启动),并连上对等节点。 - 一把出资密钥:
--btc-funding-key-file,一把单独的密钥,它的 Taproot 地址里存着支付结算的比特币。在 signet 和主网上,节点还需要--btc-funding-wallet:同一个 bitcoind 里的一个仅观察(watch-only)钱包,用来列出出资地址上的币,因为扫描 signet 的整个 UTXO 集要 30 到 50 秒。 - 一个 CPU 核心:
ksana-node只用一个线程挖矿。
出资密钥是可选的。没有它,节点照样出包含路径 B 操作的区块,由其他出块者把这些区块的数据写进比特币,并拿走携带者报酬。如果没有人这么做,积压上限会在 6 个比特币区块后让路径 B 停下(见工作原理)。
你出的每个区块都按同样的步骤来:选定锚定块,即你的比特币链顶之下 ANCHOR_DEPTH 个比特币区块处;合并 DAG 的其他顶端;放入这个区块必须强制收录的路径 C 条目,接着是一个解锁条目,再按费率放入路径 B 操作;执行;求解工作量证明;如果区块带有结算,签署结算;最后把区块广播给对等节点。区块深度达到 2 块后,结算才发往比特币。
Argon2id 工作量证明
工作量证明是对 Borsh 编码的区块头做 Argon2id(RFC 9106)运算,内存 2 MiB,一遍,一个通道。盐是 ksana-pow 后接链 ID,所以为一个网络算出的工作量在另一个网络上毫无用处;32 字节的输出按小端序读成一个数,不得超过区块的目标值。区块哈希,也就是区块的标识,仍是区块头的 sha256d。
在普通 CPU 的一个核心上,一次哈希约 1 毫秒;用 JavaScript 验证一个区块头约 13 毫秒,所以浏览器可以自己检查区块。同步繁忙的一年的区块头,约耗一个核心 1.7 小时。
为什么选 Argon2id:
- 不用 SHA-256。 比特币的 ASIC 算力可以租来压垮一条独立的 SHA-256 链,普通电脑也没法参与。
- 不用 RandomX。 验证一个区块头要 33 毫秒和 256 MB 内存(或者常驻 2 GB),浏览器也没有实际可行的办法运行它。
- 不用合并挖矿。 每个合并挖矿的区块头,都得连带一个比特币区块头、一笔 coinbase 交易和一条 Merkle 分支,共 700 到 900 字节,一起写进比特币。
- 不用权益证明。 Ksana 的安全来自比特币和算力,持有 KSA 不应决定谁来出块。
Argon2id 并非只有 CPU 能挖。在 2 MiB 下,它的速度受内存带宽限制,GPU 的内存带宽是普通 CPU 的 10 到 30 倍,估计它在单位成本算力上的优势也是这个量级:远小于 ASIC 在 SHA-256 上的优势,但不是零,也还没有实测。主网上线前,内存和遍数可能会按实测的 GPU 优势重新调整。
难度
难度每个区块调整一次,算法是 Bitcoin Cash 的 aserti3-2d,以创世块为锚点、按 DAA 分数计算:目标是每 5 秒一个单位的 DAA 分数,半衰期 7,200 秒。算力变化 10 倍,约需 10,000 个区块才能消化;空闲的链,难度会漂移约 20%。
| 网络 | 最低难度(POW_LIMIT_BITS) |
含义 |
|---|---|---|
| 主网 | 0x1f00ffff |
每块约 65,536 次哈希:要每 5 秒出一块,约需 13 个核心 |
| signet、devnet | 0x207fffff |
比特币 regtest 最容易的目标值 |
创世配置可以从更高的难度起步:signet 创世的 bits 为 0x1f068db8,预期每块约 10,000 次哈希,是按它的两个种子节点各用一个核心定的。
区块的时间戳必须晚于它选定链上前 11 个区块的中位数,最多比接收节点的时钟超前 15 秒,且最多比它锚定的比特币区块的时间超前 4 小时。最后这条规则让私挖的链无法用编造的时间换取大幅的难度优惠;它也意味着,如果比特币超过约 4 小时没有出块,快轨就会暂停。
两速难度
出块者没有东西可收录时,既没有操作,也没有解锁条目,就出一个空块,而空块的难度更高。有条目的区块之后的第一个空块权重为 12;选定链上每多一个连续的空块,权重翻一倍,最高到 120:12、24、48、96,然后是 120。权重为 w 的区块必须满足小 w 倍的目标值,给 DAA 分数加 w,并占 w 个奖励槽。所以空闲的链大约每 1、2、4、8 分钟出一块,之后每 10 分钟一块。
一旦有操作进入条目池,出块者就丢下空块模板,按正常目标值挖一个权重为 1 的区块:第一笔操作只需等大约一个普通区块,也就是 5 秒。父块相同的空块和非空块有相同的 bits,所以其他一切都不变。
为什么空块的权重更大:
- 每个区块头都要写进比特币,索引器和最终性都需要它们全部。与固定的权重 12 相比,连续加倍让空闲的一天从约 1,440 个区块头(约 26 KB)减少到约 144 个(约 2.6 KB)。
- 禁止空块代价更高。 奖励会促使矿工出难度所允许的最便宜的有效区块,那样他们就会改用自转账填满区块,字节数约为空块的 70 倍。
- 上限与比特币对齐。 权重到 120 时,空闲的链仍大约每个比特币区块出一个区块头,所以最终性可以逐块推进。
- 奖励两头都公平。 权重为 w 的区块挣 w 个槽,所以空块和非空块单位时间的期望奖励相同,出空块和打断连续空块都不会多挣。
GHOSTDAG
几乎同时找到的区块都会保留:一个区块最多指定 10 个父块,由 GHOSTDAG 给 DAG 排序。K = 16 限定一个蓝块在它自己的过去和未来之外最多能有几个蓝块;超出的区块,也就是太久没被其他区块看见的,是红块。红块的条目照样执行,路径 B 手续费照样发放,但拿不到出块奖励。
一个区块的合并集最多容纳 128 个区块,包括它的选定父块,并且只收蓝分数比其选定父块低不超过 720(MERGE_DEPTH,按 5 秒一块约一小时)、选定链又经过它合并深度根的区块。这让每项检查都贴近链顶,因此从旧区块分叉出去的长侧链永远无法被合并。
选定父块和主链都按链工作量来定:一个区块的祖先中蓝块的工作量,加上它自己的工作量。把区块自己的工作量算进去,对空闲的链很重要。不这样的话,在一个诚实的重空块还在被挖的时候,矿工可以扣住一串廉价的权重 1 区块,然后一起公布,把诚实的那个区块变成红块。
结算成本
区块带有结算时,结算的比特币手续费由这个区块的出块者支付。一对提交与揭示交易约 265 vB,载荷每字节再加四分之一 vbyte,另加揭示交易 P2A 输出的 240 聪;在 regtest 上,一对普通的交易实测提交交易 154 vB、揭示交易 209 vB,载荷 390 字节。即使网络空闲,也大约每两个比特币区块就要发一对,因为发放奖励的解锁条目也是一个条目,它所在的区块就需要在比特币上有区块体。在空闲的 signet 上,全网每天 62 到 72 对,按 2 sat/vB 每对约 1,000 聪。
批量结算默认开启:前一笔结算还在等确认时,区块把自己的区块体留给下一笔结算,所以繁忙的链大约每个比特币区块发一笔结算。--no-settlement-batching 让每个带区块体的区块都自带结算:其中的操作能更快获得最终性,代价是付更多的比特币手续费。
结算只花已确认的输出,从不互相花费,所以每个比特币区块里你最多能出资的结算笔数,等于你出资地址上已确认输出的个数。--funding-pool-target(默认 64)会把最大的输出拆成每份至少 100,000 聪,保持这么多个输出;设为 0 则不拆分。
手续费策略
这些参数是你自己的策略,决定你的节点为它发出的每笔比特币交易付多少:结算、救援、补发、拆分和加速。
| 选项 | 默认值 | 作用 |
|---|---|---|
--settlement-conf-target |
3 | bitcoind 的 estimatesmartfee 所用的比特币区块数;比特币上有一条较轻的竞争链时改为下一个区块 |
--settlement-feerate |
2 sat/vB | 下限,bitcoind 给不出估计时也按它支付 |
--max-settlement-feerate |
100 sat/vB | 上限 |
--revenue-address |
无 | 配合 --hot-wallet-cap-sat(1,000,000 聪):只要出资地址仍保有不低于这个上限的余额,结算找零就付到这里 |
你的节点发出的一对交易,如果以低于当前费率的费率等了 2 个比特币区块,就会得到一笔子交易(CPFP):它花掉揭示交易的 P2A 输出和一个出资输出,把这对交易一起拉到当前费率;如果费率再涨,会有一笔出价更高的子交易替换它。如果一笔结算怎么也确认不了,其他节点会用自己的资金救援它,按主链决定的次序轮流进行。
signet 的两个种子节点以 --settlement-feerate 2 --min-block-interval-ms 1000 --funding-pool-target 0 运行,并使用一个仅观察的出资钱包;它们完整的命令行见仓库里的 signet/ksana-signet.sh。
出块者的收益
你出的每个区块,解锁时付给你它奖励槽里出块者的那份;如果区块是你自己携带的,携带者的 5% 也归你。你还能拿到它的路径 B 手续费(别人携带时拿一半);作为携带者,对于你的结算最先把数据写进比特币的其他区块,你还能拿到每槽的 5% 和路径 B 手续费的一半。一切都要等数据写进比特币后才发放;分配和解锁的细节见 KSA 与奖励。