Skip to content

Commit 2b8b5f2

Browse files
Allow block signing pubkey in OP_RETURN output
1 parent 547632a commit 2b8b5f2

File tree

1 file changed

+10
-2
lines changed

1 file changed

+10
-2
lines changed

src/validation.cpp

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3572,7 +3572,7 @@ bool CheckBlock(const CBlock& block, BlockValidationState& state, const Consensu
35723572
{
35733573
// These are checks that are independent of context.
35743574
const bool IsPoS = block.IsProofOfStake();
3575-
LogPrint(BCLog::NET, "%s: block=%s is %s with type=%i\n", __func__, block.GetHash().ToString(), IsPoS ? "proof of stake" : "proof of work", CBlockHeader::GetAlgo(block.nVersion) == -1 ? !IsPoS : CBlockHeader::GetAlgo(block.nVersion));
3575+
LogPrint(BCLog::VALIDATION, "%s: block=%s is %s with type=%i\n", __func__, block.GetHash().ToString(), IsPoS ? "proof of stake" : "proof of work", CBlockHeader::GetAlgo(block.nVersion) == -1 ? !IsPoS : CBlockHeader::GetAlgo(block.nVersion));
35763576

35773577
if (block.fChecked)
35783578
return true;
@@ -5756,12 +5756,20 @@ bool CheckBlockSignature(const CBlock& block)
57565756
//LogPrintf("%s : coinbase cbtxin.scriptSig = %s\n", __func__, HexStr(cbtxin.scriptSig));
57575757
//LogPrintf("%s : cbtxin.scriptSig.size() = %u, vchPubKey = %s\n", __func__, cbtxin.scriptSig.size(), HexStr(vchPubKey));
57585758
pubkey = CPubKey(cbtxin.scriptSig.end()-CPubKey::COMPRESSED_SIZE, cbtxin.scriptSig.end());
5759-
if (whichType == TxoutType::PUBKEYHASH || whichType == TxoutType::WITNESS_V0_KEYHASH) { // this code could be removed in the future to allow block signing with any arbitrary pubkey
5759+
if (whichType == TxoutType::PUBKEYHASH || whichType == TxoutType::WITNESS_V0_KEYHASH) { // we need to ensure the signing pubkey belongs to the original staker so that the coinstake TX cannot be used by someone else to create a different block
57605760
if (Hash160(pubkey) != uint160(vSolutions[0])) {
57615761
return error("%s : pubkey used for block signature (%s) does not correspond to first output", __func__, HexStr(pubkey));
57625762
}
57635763
} else
57645764
return error("%s : unable to verify pubkey belongs to first output of type=%s", __func__, GetTxnOutputType(whichType));
5765+
} else if ((fProofOfStake && block.vtx[1]->vout.size() > 2) || (!fProofOfStake && block.vtx[0]->vout.size() > 1)) { // check for pubkey in OP_RETURN output - this can be any arbitrary pubkey as it will be covered by the coinstake TX signature hash
5766+
for (const CTxOut& out : block.vtx[fProofOfStake]->vout) {
5767+
if (out.scriptPubKey.size() == 35 && out.scriptPubKey[0] == OP_RETURN && out.scriptPubKey[1] == CPubKey::COMPRESSED_SIZE) { // output of CScript() << OP_RETURN << ToByteVector(signingPubKey)
5768+
//LogPrintf("%s : OP_RETURN out.scriptPubKey = %s\n", __func__, HexStr(out.scriptPubKey));
5769+
//LogPrintf("%s : out.scriptPubKey.size() = %u\n", __func__, out.scriptPubKey.size());
5770+
pubkey = CPubKey(out.scriptPubKey.begin()+2, out.scriptPubKey.end()); // skip OP_RETURN and pushdata length byte
5771+
}
5772+
}
57655773
} else { // we don't know where the pubkey is or how to parse it
57665774
return error("%s : unable to find pubkey to validate block signature", __func__);
57675775
}

0 commit comments

Comments
 (0)