以下文档资源信息是博主基于量子链修改后总结。
主要修改内容在chainparams.cpp
源码文件中。
关于比特币家族的新的币种修改方法主要有以下几点
创世块
创世块时间戳
私钥地址的开头
块分割的魔法四字节
难度、出块时间
币的总量
欲挖币数量
算法难度是指,在哈希的过程中,哈希后的值匹配的格式命中难度。
例:0
必须匹配 0
,f
匹配任意字符。
因此,算法难度取决于哈希匹配格式中 0
的数量,0
越多,匹配命中率越低,即算法难度高。
在 Qtum
中使用了两种共识机制的算法,分别是 PoW 工作量证明
与 PoS 权益证明
此处将两者的算法难度分离,以更好的让官方 Qtum
实施预挖。
consensus.powLimit = uint256S("0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
consensus.posLimit = uint256S("00000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
创世块是指整个区块中的第一个块。
// 创建创世块函数原型
// @params: nTime 发起时间 (Unix 时间戳)
// @params: nNonce 创世块的合理随机数 该随机数得到的结果必须符合协议的难度
// @params: nBits
// @params: nVersion 版本号
// @params: genesisReward 创世块奖励
static CBlock CreateGenesisBlock(uint32_t nTime, uint32_t nNonce,
uint32_t nBits, int32_t nVersion, const CAmount& genesisReward) {
// 当时的头条事件
const char* pszTimestamp = "Sep 02, 2017 Bitcoin breaks $5,000 in latest price frenzy";
// 公钥的十六进制
// 拥有创世块真正私钥的人,才是这个链的主人。
const CScript genesisOutputScript =
CScript() << ParseHex("040d61d8653448c98731ee5fffd303c15e71ec"\
"2057b77f11ab3601979728cdaff2d68afbba14e4fa0bc44f2072b0b23ef63"\
"717f8cdfbe58dcd33f32b6afe98741a") << OP_CHECKSIG;
return CreateGenesisBlock(pszTimestamp, genesisOutputScript, nTime, nNonce, nBits, nVersion, genesisReward);
}
创世块的生成是整个主链的基础,接下来主链的所有块都是创世块的延伸。
genesis = CreateGenesisBlock(1504695029, 8026361, 0x1f00ffff, 1, 50 * COIN);
genesis.GetHash();
这里的四字节用于比特币网络中二进制数据传输过程中,作为数据分隔作用。
以该四字节作为分隔标准,这里可以修改成任意约定字节内容。
pchMessageStart[0] = 0xfd;
pchMessageStart[1] = 0xdd;
pchMessageStart[2] = 0xc6;
pchMessageStart[3] = 0xe1;
服务器起来时,程序会向主机拉去其它节点的信息。
由该中心节点,完成 P2P
网络基础传输地址建设。
此处的中心节点,可以向上添加。
// CDNSSeedData @param 1: 列表名称
// CDNSSeedData @param 2: 服务器地址
vSeeds.push_back(CDNSSeedData("qtum3.dynu.net", "qtum3.dynu.net", false)); // Qtum mainnet
确认数是指该笔交易第一次记录到区块中后,后面的延伸块的长度。
例如当前块高为1000,则创世块的确认数为:1000个。
节点检验是指在同步块的过程中,将已发生的块哈希写死在代码中。
在同步过程中检验对应高度的块,若块哈希不同,直接停止块同步。
此处的节点检验,可以向上添加。
checkpointData = (CCheckpointData) {
boost::assign::map_list_of
( 0, uint256S("000075aef83cf2853580f8ae8ce6f8c3096cfa21d98334d6e3f95e5582ed986c"))
( 5000, uint256S("00006a5338e5647872bd91de1d291365e941e14dff1939b5f16d1804d1ce61cd")) //last PoW block
};
在修改源码参数的过程中,可能会遇到一些问题。
该问题可以查看源码
StakeQtums(true, pwalletMain);
// 摘自 init.cpp (1740)
// @brief : 矿机的主要操作函数
// @param : 当前钱包
void ThreadStakeMiner(CWallet *pwallet)
PoS的运行前提
PoS
挖矿操作//don't disable PoS mining for no connections if in regtest mode
if(!regtestMode && !GetBoolArg("-emergencystaking", false)) {
while (g_connman->GetNodeCount(CConnman::CONNECTIONS_ALL) == 0 || IsInitialBlockDownload()) {
nLastCoinStakeSearchInterval = 0;
fTryToSync = true;
MilliSleep(1000);
}
if (fTryToSync) {
fTryToSync = false;
if (g_connman->GetNodeCount(CConnman::CONNECTIONS_ALL) < 3 ||
pindexBestHeader->GetBlockTime() < GetTime() - 10 * 60) {
MilliSleep(60000);
continue;
}
}
} // 摘自 miner.cpp - ThreadStakeMiner(1093)
ThreadStakeMiner
函数原型:void ThreadStakeMiner(CWallet *pwallet);
函数功能:该函数负责主要的 PoS
挖矿操作,涉及所有挖矿的任务流操作
由 bitcoind.cpp
的 main
函数发起运行在线程池中
检查钱包状态是否可用
检测是否满足 PoS 协议的运行前提
检验是否存在可兑换币龄
附言
若出现同步到第五千个块后,无法继续同步,在测试情况下,一般是由于在线节点数量不够的原因