共计 6623 个字符,预计需要花费 17 分钟才能阅读完成。
- Merged mining 合并挖矿; 联合挖矿
- Aux 辅助
注意: 这个标准由 Namecoin 使用,但是新的合并挖掘数据可能会提出一个新的 BIP 来代替它,使用基于 p2pool 合并挖掘的东西。
内容
- 术语
- 辅助工作量证明块
- merkle 分支
- 合并挖矿 coinbase
- 人造山楂树
- 例子
- 笔记
术语
Auxiliary Proof-of-Work (POW)
a.k.“AuxPOW”。这就是合并挖掘存在的方式; 这是两个区块链之间的关系,一个区块链信任另一个区块链的工作,并接受 AuxPOW 区块。
Merged Mining
在多个链上使用一个区块链所做的工作的行为,使用辅助 POW。
Auxiliary Blockchain
altcoin 接受在交替链上所做的工作,并将其作为在自己的链上有效的工作。必须修改客户端应用程序才能接受辅助 POW。
Parent Blockchain
实际挖矿工作发生的区块链。这个链不需要知道辅助 POW 逻辑,因为提交给这个链的 AuxPOW 块仍然是有效的块。
Parent Block
不要与“前一个块”混淆。这是一个为父区块链构造的块(即 prev_block 散列指向父区块链上的前一个块)。该块的头部是辅助区块链中的 AuxPOW 块的一部分。
AuxPOW Block
这是一种与标准区块链块类似的新型块,但有两个重要区别。首先,块头的哈希不满足区块链的难度级别(因此,如果被一个简单的客户端解释为不满足难度级别,那么将被抛出)。其次,它还有额外的数据元素,表明创建这个块的矿工实际上在父区块链上进行了挖掘活动(散列),并且该工作满足辅助区块链的难度级别,这就是为什么应该接受这个块。
Aux proof-of-work block
这是用来证明对辅助区块链的功。在 vinced 的原始实现中,它是通过调用父区块链客户机 (bitcoind) 上的 getworkaux RPC 方法生成的,然后通过将其作为 getauxblock 的第二个参数传递给辅助链客户机 (namecoind) 来提交工作。
当在“块”网络消息中接收一个 Aux 工作验证块时,接收到的数据与标准块类似,但是在 nonce 和 txn_count 元素之间插入了额外的数据。下表中,阴影行与标准块定义相同:
Field Size | Description | Data type | Comments | |
---|---|---|---|---|
4 | version | uint32_t | ||
32 | prev_block | char[32] | ||
32 | merkle_root | char[32] | ||
4 | timestamp | uint32_t | ||
4 | bits | uint32_t | ||
4 | nonce | uint32_t | ||
? | coinbase_txn | txn | 位于父块中的 Coinbase 事务,将 AuxPOW 块链接到其父块 | |
32 | block_hash | char[32] | parent_block 头的散列 | |
? | coinbase_branch | merkle branch | merkle 分支将 coinbase_txn 链接到父块的 merkle_root | |
? | blockchain_branch | Merkle branch | merkle 分支将这个辅助区块链连接到其他的区块链,当在合并了多个辅助链的挖掘设置中使用时 | |
80 | parent_block | Block header | 父块头 | |
? | txn_count | var_int | ||
? | txns | tx[] |
coinbase_branch merkle 分支, 因为块中的 coinbase 事务是第一个事务(如果使用比特币作为父链, 即散列在下面的例子中# 7),branch_side_mask 总是都是 0, 因为分支总是会散列哈希的“右边”工作。
当只处理一个辅助区块链时,blockchain_branch 链接是不需要的,它被表示为 5 个字节的零 (解释为一个一个字节的 var_int,表示一个零的 branch_length,以及一个 32 位(4 字节) 的 branch_side_mask)。
注意,
block_hash 元素是不需要的,因为您有完整的 parent_block 头元素,可以从中计算散列。当前的 Namecoin 客户端没有检查这个字段的有效性,因此有些 AuxPOW 块使用 little-endian,有些使用 big-endian。
Merkle Branch
假设 Alice 创建了一个 Merkle 树,它的根元素是公开可用的。例如:
现在她想向 Bob 证明一个给定的 hash(#10)是树的一部分,但是 Bob 没有完整的树(只有公共根; 散列# 0)。
- Alice 可以向 Bob 发送她最初用来生成树的所有散列(散列 #7-#14,总共有 7 个额外的散列),因此 Bob 可以构建整个树来验证根是相同的,但是这需要大量的数据。
- 相反,她可以给 Bob 提供 #9、#3 和#2 哈希值(从树的每一层都有一个哈希值,从#10 返回到根)。在 Bob 不知道树的结构的情况下,Alice 还必须告诉 Bob 应用散列的顺序(因为散列(#9,#10)== #4,而散列(#10,#9)!= #4)。
- 因此,Alice 告诉 Bob“left, left, right”来指示 #9、#3 和#2 分别是哪个操作数。它可以被编码为位掩码,并且只占用很少的数据来传输。因此,Alice 没有向 Bob 传输 7 个哈希值,而是传输了 3 个哈希值和一个位掩码。如果 merkle 树变得更大,数据节省就会更加明显。
这是整体的前提,特别是对于 AuxPOW 协议,它被称为“merkle branch”(因为它是 merkle 树的一个通路),并被传输如下:
Field Size | Description | Data type | Comments | |
---|---|---|---|---|
? | branch_length | var_int | 组成分支的哈希数 | |
? | branch_hash[] | char[32] | 分支中的单个散列; 重复分支长度次数 | |
4 | branch_side_mask | int32_t | 位掩码 merkle 哈希函数的哪一侧的 branch_hash 元素应该继续。0 表示在右边,1 表示在左边。它等于这个 merkle 分支的 merkle 树最宽级别内的起始散列的索引。 |
备注:
branch_hash[] 个长度和 branch_side_mask 的长度是一致的。
首先使用第一个 branch_hash, branch_side_mask 的最小有效位决定它的 hash 位置。然后将第二个 branch_hash 应用于 branch_side_mask 的第二个最小有效位,以此类推。对于 Alice 的例子,branch_length 是 3,散列的顺序是 #9 #3 #2,branch_side_mask 是 0b011 = 3(等于 merkle 树中最宽级别的 #10 的索引)。
联合挖矿 coinbase
在父块中的 coinbase 事务的 scriptSig 中插入其中一个头部。
Field Size | Description | Data type | Comments | |
---|---|---|---|---|
4 | magic | char[4] | 0xfa、0xbe、’m’、’m'(仅当脚本开始后超过 20 个字节时才需要; 可选的其他) | |
32 | block_hash | char[32] | 链 merkle 分支的 AuxPOW 块头 / 根的散列 | |
4 | merkle_size | int32_t | 在辅助工作 merkle 树的条目数。(必须是 2 的幂) | |
4 | merkle_nonce | int32_t | Nonce 用于计算索引到辅助工作 merkle 树; 你还是把这个值设为零为好 |
这个包含 44 个字节的字符串是 coinbase 脚本的一部分,这意味着矿工在创建 coinbase 之前构造了 AuxPOW 块。
Aux work merkle tree
如果您只是挖掘一个辅助链并使用 getauxblock,那么您不必担心这个问题—只需将 coinbase 中的 merkle 树散列设置为由 getauxblock 提供的 aux 链块的散列,merkle 大小为 1,merkle nonce 为 0。如果你开采了不止一个,这个就有点坏了。它使用以下算法将链 ID 转换为 merkle 树底部的一个槽,其中链的块哈希必须槽:
unsigned int rand = merkle_nonce;
rand = rand * 1103515245 + 12345;
rand += chain_id;
rand = rand * 1103515245 + 12345;
slot_num = rand % merkle_size
其思想是,您可以增加 merkle_nonce,直到您挖掘的链不会与相同的槽发生冲突。问题是这不起作用; 因为它只是将 merkle_nonce 派生的一个数字添加到 chain_id,如果两个链冲突为一个 nonce,那么它们仍然会冲突为所有可能的 nonces。
- [1]新实现: 请选择您的 chain_id,这样就不会与现有的链冲突,需要尽可能小的 merkle_size 值,或者使用更好的算法来计算链的槽 id。
一旦知道了 merkle 树中不同链的位置,按照 getauxblock 提供的方法将每个链的块散列的字节倒转(这样开始的字节就会移动到末尾,等等),并插入到适当的槽中,用任意数据填充未使用的槽。现在像往常一样构建 merkle 树,取初始行中的每一对值,并对它们进行双 SHA-256 哈希,得到新的哈希行,重复这个过程,直到只有一个哈希。最后一个散列是 merkle 根。在将其插入 coinbase 之前,您需要再次反转这个字节。如果没有使用 getauxblock 来获得块散列,可以跳过第一次反转,但是在将最终的 merkle 根添加到 coinbase 时,仍然需要反转它。
aux 工作证明还需要一个 merkle 分支,其构建过程如下: 查找块的散列在 merkle 树中的位置,并添加构建 merkle 树时使用的散列值。现在添加对结果进行散列的值。一直这样做,直到你到达根。merkle 树本身从来不包括在 merkle 枝。如果您只有一个 aux 链,则可以将其完全空出来。(似乎也不需要反转这些散列。)
例子
这是 Namecoin 链中高度为 19200 的 AuxPOW 块(第一个允许 AuxPOW 身份验证的块)。它的散列是 d8a7c3e01e1e95bcee015e6fcc7583a2ca60b79e5a3aa0a171eddd344ada903d,并且只有一个 Namecoin 事务(coinbase 将 50 个 NMC 发送到矿工的地址)。被用作工作证明的父块的哈希值比当时 Namecoin 的难度目标小,但比特币的目标则不同:
0000000000003d47277359fb969c43e3c7e7c0306a17f6444b8e91e19def03a9 — parent block hash
000000000000b269000000000000000000000000000000000000000000000000 — Namecoin difficulty target
00000000000009ee5d0000000000000000000000000000000000000000000000 — Bitcoin difficulty target
因此,这个 AuxPOW 块在 Namecoin 区块链中是有效的,但在比特币区块链中无效(您将发现没有一个以 3d47277359fb969c 开头的散列的比特币块。如果是,那么它就在 4a59b7deb5c4e01b 之后,因为这是使用的前 vious_block 散列)
Block Header:
01 01 01 00 // Version
36 90 9a c0 7a 16 73 da f6 5f a7 d8 28 88 2e 66 c9 e8 9f 85 46 cd d5 0a 9f b1 00 00 00 00 00 00 // Previous block hash
0f 5c 65 49 bc d6 08 ab 7c 4e ac 59 3e 5b d5 a7 3b 2d 43 2e b6 35 18 70 8f 77 8f c7 dc df af 88 // Merkle root
8d 1a 90 4e // Timestamp
69 b2 00 1b // Bits
00 00 00 00 // Nonce
Parent Block Coinbase Transaction:
01 00 00 00 // Version
01 // TxIn Count
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // Previous Out
00 00 00 00 00 00 00 00 00 00 00 00 00 00 ff ff ff ff
35 // Script size
04 5d ee 09 1a 01 4d 52 2c fa be 6d 6d d8 a7 c3 e0 1e 1e 95 bc ee 01 5e 6f cc 75 83 a2 ca 60 b7 // Script
9e 5a 3a a0 a1 71 ed dd 34 4a da 90 3d 01 00 00 00 00 00 00 00
ff ff ff ff // Sequence Number
01 // TxOut Count
60 a0 10 2a 01 00 00 00 // Amount
43 // Script Size
41 04 f8 bb e9 7e d2 ac bc 5b ba 11 c6 8f 6f 1a 03 13 f9 18 f3 d3 c0 e8 47 50 55 e3 51 e3 bf 44 // Script
2f 8c 8d ce e6 82 d2 45 7b dc 53 51 b7 0d d9 e3 40 26 76 6e ba 18 b0 6e ae e2 e1 02 ef d1 ab 63
46 67 ac
00 00 00 00 // Lock Time
Coinbase Link:
a9 03 ef 9d e1 91 8e 4b 44 f6 17 6a 30 c0 e7 c7 e3 43 9c 96 fb 59 73 27 47 3d 00 00 00 00 00 00 // Hash of parent block header
05 // Number of links in branch
05 0a c4 a1 a1 e1 bc e0 c4 8e 55 5b 1a 9f 93 52 81 96 8c 72 d6 37 9b 24 72 9c a0 42 5a 3f c3 cb // Hash #1
43 3c d3 48 b3 5e a2 28 06 cf 21 c7 b1 46 48 9a ef 69 89 55 1e b5 ad 23 73 ab 61 21 06 0f 30 34 // Hash #2
1d 64 87 57 c0 21 7d 43 e6 6c 57 ea ed 64 fc 18 20 ec 65 d1 57 f3 3b 74 19 65 18 3a 5e 0c 85 06 // Hash #3
ac 26 02 df e2 f5 47 01 2d 1c c7 50 04 d4 8f 97 ab a4 6b d9 93 0f f2 85 c9 f2 76 f5 bd 09 f3 56 // Hash #4
df 19 72 45 79 d6 5e c7 cb 62 bf 97 94 6d fc 6f b0 e3 b2 83 9b 7f da b3 7c db 60 e5 51 22 d3 5b // Hash #5
00 00 00 00 // Branch sides bitmask
Aux Blockchain Link:
00 // Number of links in branch
00 00 00 00 // Branch sides bitmask
Parent Block Header:
01 00 00 00 // Version
08 be 13 29 5c 03 e6 7c b7 0d 00 da e8 1e a0 6e 78 b9 01 4e 5c eb 7d 9b a5 04 00 00 00 00 00 00 // Previous block hash
e0 fd 42 db 8e f6 d7 83 f0 79 d1 26 be a1 2e 2d 10 c1 04 c0 92 7c d6 8f 95 4d 85 6f 9e 81 11 e5 // Merkle root
9a 23 90 4e // Timestamp
5d ee 09 1a // Bits
1c 65 50 86 // Nonce
Transactions:
01 // Tx Count
01 00 00 00 // Version
01 // TxIn Count
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // Previous Out
00 00 00 00 00 00 00 00 00 00 00 00 00 00 ff ff ff ff
08 // Script size
04 69 b2 00 1b 01 01 52 // Script
ff ff ff ff // Sequence number
01 // TxOut Count
00 f2 05 2a 01 00 00 00 // Amount
43 // Script size
41 04 89 fe 91 e6 28 47 57 5c 98 de ea b0 20 f6 5f df f1 7a 3a 87 0e bb 05 82 0b 41 4f 3d 80 97 // Script
21 8e c9 a6 5f 1e 0a e0 ac 35 af 72 47 bd 79 ed 1f 2a 24 67 5f ff b5 aa 6f 96 20 e1 92 0a d4 bf
5a a6 ac
00 00 00 00 // Lock Time
Notes
https://bitcointalk.org/index.php?topic=51069.0
本文由 Rebase 社区的 River 进行整理和翻译:
原文链接:https://en.bitcoin.it/wiki/Merged_mining_specification