Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
挖矿盗窃问题
1)问题描述: FNFN当前代码存在挖矿盗窃问题:假设A矿工为正常矿工,而B矿工为恶意矿工(偷窃矿工),当A矿工首先计算出POW的工作量证明的HASH,并打包BLOCK后广播全网,而B矿工收到该BLOCK后,将奖励地址改为自已的地址,然后重新打包广播全网,这样就会存在一个分叉,即A矿工打包的BLOCK一个分支,B矿工打包的BLOCK一个分支,两个BLOCK的前一个BLOCK都是同个BLOCK,由于工作量证明的计算中未包括矿工奖励地址的指纹,则其它节点较验B矿工的BLOCK,也能通过(后面描述能较验通过的原因),所以就形成分叉链,后面看那个子链连接的更长,则那个子链就获胜,相应的矿工也得到奖励。偷窃矿工有一定的机率偷窃成功,而他的成本很低,只需简单更换后就能广播全网。
2)窃取原理: FNFN代码是通过CBlock::GetSerializedProofOfWorkData这个函数来收集计算工作量证明的数据,而该函数收集数据包括:nVersion、nType、nTimeStamp、hashPrev、vchProof,vchProof数据包括:nWeight、nAgreement、nAlgo、nBits、nNonce,收集的数据未包含矿工奖励地址信息,偷窃矿工只需要将BLOCK中的奖励交易(txMint)的接收地址更换为偷窃矿工的地址,然后重新计算奖励交易的较验数据和BLOCK的较验数据,就可以广播全网,而其它节接收到该BLOCK后,也能较验通过。
3)BTC的防盗窃的方法: BTC中计算工作量证明的数据包括:nVersion、hashPrevBlock、hashMerkleRoot、nTime、nBits、nNonce(参见CBlockHeader::SerializationOp函数),其中hashMerkleRoot为BLOCK中的交易数据Merkle树HASH,而BTC的BLOCK中的交易列表中的第一个交易就是奖励交易,包含了矿工地址,所以hashMerkleRoot就有矿工地址的指纹信息,偷窃矿工将无法将奖励地址更换为自已的地址(更换后hashMerkleRoot值就会改变,导致工作量证明HASH也会变),则无法盗窃奖励。
解决方案:
1)解决挖矿盗窃问题的方法:
在vchProof数据中增加矿工奖励的地址,即vchProof数据包括:nWeight、nAgreement、nAlgo、nBits、destMint、nNonce,在较验中增加对矿工奖励的地址的较验,即if (proof.destMint != block.txMint.sendTo),这样即可以保持当前GetWork的流程,也能防止挖矿盗窃问题。在GetWork命令中需要增加spent和privkey参数,即与SubmitWork命令中的spent和privkey参数相同。
2)防止盗窃原理:
由于vchProof数据中增加矿工奖励的地址,则计算工作量证明HASH中有矿工奖励地址的指纹,偷窃矿工要将奖励地址更换为偷窃矿工的地址,并且需要同时更换vchProof数据中增加矿工奖励的模板ID,从而导致计算工作量证明HASH会发生变化,可能不会满足小于难度目标HASH;如果偷窃矿工不更换奖励交易的地址,而在交易表中增加或删除交易方式来捣乱BLOCK,由于交易表修改,则需要重新计算BLOCK的较验数据,即vchSig,计算vchSig需要使用私钥签名,而偷窃矿工没有该BLOCK的合法矿工的私钥,所以无法签名,则在对BLOCK签名较验时会出错,其它合法节点则认为该BLOCK是非法BLOCK,如果偷窃矿工使用自已的私钥签名,由于较验BLOCK的签名是使用奖励的地址来较验(block.txMint.sendTo.VerifyBlockSignature(block.GetHash(), block.vchSig);),并且偷窃矿工不能更换奖励交易的地址为自已的地址(更换后较验proof.destMint 时失败),所以偷窃矿工使用自已的私钥签名也是无法较验通过的。所以在vchProof数据中增加矿工奖励的地址,可以防止挖矿盗窃问题。