BCH和BTC最大的区别应该就是区块扩容的了,首先来看区块
位于/src/primitives/
节点将新交易收集到块中,将它们散列到哈希树中,并扫描nonce值以使块的哈希值满足工作量证明要求。 当他们解决工作证明时,他们将块广播给每个人,并且块被添加到块链中。 块中的第一个事务是一个特殊的事务,它创建一个由块的创建者拥有的新硬币。
注释部分和btc是一样的,结构也是一样的
btc的区块 https://blog.csdn.net/m0_37847176/article/details/81874834
class CBlockHeader {
public:
// header
int32_t nVersion;
uint256 hashPrevBlock;
uint256 hashMerkleRoot;
uint32_t nTime;
uint32_t nBits;
uint32_t nNonce;
CBlockHeader() { SetNull(); }
ADD_SERIALIZE_METHODS;
template <typename Stream, typename Operation>
inline void SerializationOp(Stream &s, Operation ser_action) {
READWRITE(this->nVersion);
READWRITE(hashPrevBlock);
READWRITE(hashMerkleRoot);
READWRITE(nTime);
READWRITE(nBits);
READWRITE(nNonce);
}
void SetNull() {
nVersion = 0;
hashPrevBlock.SetNull();
hashMerkleRoot.SetNull();
nTime = 0;
nBits = 0;
nNonce = 0;
}
bool IsNull() const { return (nBits == 0); }
uint256 GetHash() const;
int64_t GetBlockTime() const { return (int64_t)nTime; }
};
下面来CBlock
class CBlock : public CBlockHeader {
public:
// network and disk
std::vector<CTransactionRef> vtx;//交易
// memory only
mutable bool fChecked;
CBlock() { SetNull(); }
CBlock(const CBlockHeader &header) {
SetNull();
*((CBlockHeader *)this) = header;
}
ADD_SERIALIZE_METHODS;
template <typename Stream, typename Operation>
inline void SerializationOp(Stream &s, Operation ser_action) {
READWRITE(*(CBlockHeader *)this);
READWRITE(vtx);
}
void SetNull() {
CBlockHeader::SetNull();
vtx.clear();
fChecked = false;
}
CBlockHeader GetBlockHeader() const {
CBlockHeader block;
block.nVersion = nVersion;
block.hashPrevBlock = hashPrevBlock;
block.hashMerkleRoot = hashMerkleRoot;
block.nTime = nTime;
block.nBits = nBits;
block.nNonce = nNonce;
return block;
}
std::string ToString() const;
};
描述区块链中到另一个节点的位置,这样如果另一个节点没有相同的分支,它就可以找到最近的公共中继。 它越靠后,叉子就越远
struct CBlockLocator {
std::vector<uint256> vHave;
CBlockLocator() {}
CBlockLocator(const std::vector<uint256> &vHaveIn) { vHave = vHaveIn; }
ADD_SERIALIZE_METHODS;
template <typename Stream, typename Operation>
inline void SerializationOp(Stream &s, Operation ser_action) {
int nVersion = s.GetVersion();
if (!(s.GetType() & SER_GETHASH)) READWRITE(nVersion);
READWRITE(vHave);
}
void SetNull() { vHave.clear(); }
bool IsNull() const { return vHave.empty(); }
};
emmm…没有区块的大小说明,不科学,找找
在src/globals.cpp中声明
uint64_t nMaxBlockSize = DEFAULT_MAX_BLOCK_SIZE;
然后在src/consensus/consensus.h
/** 1MB */
static const uint64_t ONE_MEGABYTE = 1000000;
/** The maximum allowed size for a transaction, in bytes */
static const uint64_t MAX_TX_SIZE = ONE_MEGABYTE;
/** The minimum allowed size for a transaction, in bytes */
static const uint64_t MIN_TX_SIZE = 100;
/** The maximum allowed size for a block, before the UAHF */用户激活硬分叉前最大限制是1M
static const uint64_t LEGACY_MAX_BLOCK_SIZE = ONE_MEGABYTE;
/** Default setting for maximum allowed size for a block, in bytes */
static const uint64_t DEFAULT_MAX_BLOCK_SIZE = 32 * ONE_MEGABYTE;
一笔交易最大是1M,最小是100b
可以查询一下看看
parallels@parallels-vm:~$ bitcoin-cli getexcessiveblock
{
"excessiveBlockSize": 32000000
}
所以最大区块大小是32M
然后来看BTC的区块限制,应该是这个,在miner.cpp
/** Default for -blockmaxweight, which controls the range of block weights the mining code will create **/
static const unsigned int DEFAULT_BLOCK_MAX_WEIGHT = 3,000,000;
/** Default for -blockmaxsize, which controls the maximum size of block the mining code will create **/
static const unsigned int DEFAULT_BLOCK_MAX_SIZE = 750,000;
/** The maximum allowed size for a serialized block, in bytes (only for buffer size limits) */
static const unsigned int MAX_BLOCK_SERIALIZED_SIZE = 4,000,000;
BlockAssembler::BlockAssembler(const CChainParams& _chainparams)
: chainparams(_chainparams)
{
// Block resource limits区块资源限制
// If neither -blockmaxsize or -blockmaxweight is given, limit to DEFAULT_BLOCK_MAX_*
// If only one is given, only restrict the specified resource.
// If both are given, restrict both.
nBlockMaxWeight = DEFAULT_BLOCK_MAX_WEIGHT;//3M
nBlockMaxSize = DEFAULT_BLOCK_MAX_SIZE;//750k
bool fWeightSet = false;
if (mapArgs.count("-blockmaxweight")) {
nBlockMaxWeight = GetArg("-blockmaxweight", DEFAULT_BLOCK_MAX_WEIGHT);
nBlockMaxSize = MAX_BLOCK_SERIALIZED_SIZE;
fWeightSet = true;
}
if (mapArgs.count("-blockmaxsize")) {
nBlockMaxSize = GetArg("-blockmaxsize", DEFAULT_BLOCK_MAX_SIZE);
if (!fWeightSet) {
nBlockMaxWeight = nBlockMaxSize * WITNESS_SCALE_FACTOR;
}
}
// Limit weight to between 4K and MAX_BLOCK_WEIGHT-4K for sanity:
nBlockMaxWeight = std::max((unsigned int)4000, std::min((unsigned int)(MAX_BLOCK_WEIGHT-4000), nBlockMaxWeight));
// Limit size to between 1K and MAX_BLOCK_SERIALIZED_SIZE-1K for sanity:
nBlockMaxSize = std::max((unsigned int)1000, std::min((unsigned int)(MAX_BLOCK_SERIALIZED_SIZE-1000), nBlockMaxSize));
// Whether we need to account for byte usage (in addition to weight usage)
fNeedSizeAccounting = (nBlockMaxSize < MAX_BLOCK_SERIALIZED_SIZE-1000);
}
为什么是4k和1k呢,这是给coinbase预留的内存大小,因为一个区块肯定会有coinbase交易。
从上面的代码来看,nBlockMaxSize可以是1k到4M-1K大小的,不是我们所熟知的1M大小的限制
所以1M的限制在那里呢,我看下挖矿的代码, 貌似发现了
/** The maximum allowed size for a block excluding witness data, in bytes (network rule) */
static const unsigned int MAX_BLOCK_BASE_SIZE = 1000000;
从注释看是,除见证数据之外的块的最大允许大小,在源码中查找可以在main.cpp的CheckBlock中找到这个常量的使用
// Size limits
if (block.vtx.empty() || block.vtx.size() > MAX_BLOCK_BASE_SIZE || ::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS) > MAX_BLOCK_BASE_SIZE)
return state.DoS(100, false, REJECT_INVALID, "bad-blk-length", false, "size limits failed");
所谓的区块大小限制应该是针对区块中的交易的
所以算起来是带上隔离见证数据的话,区块大小能达到4M