比特币源码研读之十五
比特币昨日已成功突破3万大关,这个价格是上个月还处于无法想象的,作为普罗大众的我们是根本不敢想的。不过这点还是要佩服笑来老师,他在硬币资本的分享会上就说了:“现在价格处于下跌阶段,正是买入好时机。”。所以,还真是要像李老师那样深刻理解比特币的内涵与原理才能做到长期持有,才能拿得住!而投资的世界与我们平时的世界是反的,在投资的世界里我们越频繁地操作就越容易犯错,我们要做的就是在投资之前花时间认真研究投资标的,研究后认可其价值则长期持有之,坚决不能频繁关注价格!我们要做的就是去学习知识、学习区块链知识、学习比特币源码,进而深刻理解其内涵!在掌握了比特币的实现原理之后,我们再去研究其他的区块链资产肯定可以得心应手了。所以现在让我们继续在比特币源码研读之路中前行。开启我们的第十五篇源码研读之旅。
本文将继续开展应用程序参数交互源码部分(AppInitParameterInteraction)的研读与分析。
本文主要涉及的源码文件包括:
src/bitcond.cpp、src/init.h、src/init.cpp、src/util.h、src/util.cpp、src/netbase.h、src/policy/policy.h、src/policy/policy.cpp
一、节点超时参数
比特币网络中新加入的节点都会去寻找节点,加入比特币P2P网络中,与其他节点完成同步操作。但是在网络中寻找节点,并建立连接是有时间限制的,即会出现连接超时的问题。这个超时时间通过src/netbase.h中的全局变量DEFAULT_CONNECT_TIMEOUT定义,其默认值为5000毫秒,最小值为1毫秒,这个1毫秒的最小值是通过-timeout参数的帮助信息得知的。该帮助信息可在src/init.cpp中的HelpMessage函数中获取,或者在比特币程序的help命令进行查询-timeout参数的详细信息。
默认值(src/netbase.h):
//! -timeout default
static const int DEFAULT_CONNECT_TIMEOUT = 5000;
最小值(src/init.h):
strUsage +=HelpMessageOpt("-timeout=", strprintf(_("Specifyconnection timeout in milliseconds (minimum: 1, default: %d)"), DEFAULT_CONNECT_TIMEOUT));
程序中的帮助信息
我们通过timeout参数解析代码可以明确地知道连接超时时间不能设置为负数,如果为负数则将设置为默认值。
二、最小交易费
此处讨论的最小交易费涉及四方面内容:minrelaytxfee、incrementalRelayFee、blockmintxfee以及dustrelayfee。
(1)minrelaytxfee为最小交易费率。通过代码与注释我们可以了解到该费率为每千字节所需的最小费率。该费率值的设置对于矿工来说很重要,需谨慎设置,切忌设置为为0,因为如果设置为0时,每个被挖出的区块中都将会被塞满1聪交易费的交易,这将会使得矿工入不敷出。所以最低交易费必须高于处理交易所需成本。其默认值为DEFAULT_MIN_RELAY_TX_FEE=1000,定义于src/validation.h中。最小交易费用通过全局变量::minRelayTxFee进行存储,其类型为CFeeRate。如果我们在程序没有设置minrelaytxfee参数,minRelayTxFee必须大于等于incrementalRelayFee(其含义见《比特币源码研读之十三》);
(2)incrementalRelayFee该变量我们已经在《比特币源码研读之十三》中介绍了,具体内容可前往第十三篇阅读;
(3)blockmintxfee为区块中打包交易的最小费用值信息,我们可以通过其帮助信息了解到其最低费用通过src/policy.h中的DEFAULT_BLOCK_MIN_TX_FEE全局变量进行定义。
/** Default for -blockmintxfee, whichsets the minimum feerate for a transaction in blocks created by mining code **/
static const unsigned intDEFAULT_BLOCK_MIN_TX_FEE = 1000;
从上可以看出,通过挖矿发现的区块打包交易的最低费率为1000聪。
(4)dustrelayfee为全局变量,其在src/policy/policy.h中声明,在policy.cpp中实现定义:
CFeeRate dustRelayFee = CFeeRate(DUST_RELAY_TX_FEE);
其默认值为DUST_RELAY_TX_FEE定义于policy.h,其默认值与minrelayfee一致,均为1000聪。
针对dustrelayfee的含义,我们可通过其具体使用情况来分析,在src/qt/paymentserver.cpp中使用dustRelayFee代码如下:
// Extract and check amounts
CTxOut txOut(sendingTo.second, sendingTo.first);
if (txOut.IsDust(dustRelayFee)) {
Q_EMITmessage(tr("Payment request error"), tr("Requested paymentamount of %1 is too small (considered dust).")
.arg(BitcoinUnits::formatWithUnit(optionsModel->getDisplayUnit(),sendingTo.second)),
CClientUIInterface::MSG_ERROR);
returnfalse;
}
通过消息输出内容为“Requested payment amount of %1 is too small(considered dust).”我们可以得知dustrelayfee为那些交易费用很低的交易,可以形象得理解为灰尘、忽略不计的费用。而为了防止出现非标准交易,源码中设置了默认的灰尘交易判断标准,同时针对用户传入的灰尘交易费进行了逻辑判断,保证其大于0。
// Feerate used to define dust.Shouldn't be changed lightly as old
// implementations may inadvertently createnon-standard transactions
if (IsArgSet("-dustrelayfee"))
{
CAmount n =0;
if(!ParseMoney(GetArg("-dustrelayfee", ""), n) || 0 == n)
returnInitError(AmountErrMsg("dustrelayfee",GetArg("-dustrelayfee", "")));
dustRelayFee= CFeeRate(n);
}
三、非标准交易
Acceptnonstdtxn参数的含义是比特币网络中是否需要非标准交易,是否接受标准交易主要看当前运行的是什么网络(主网、测试网、私有网),这3种网络对是否需要标准交易是有默认要求的。该状态是通过fRequireStandard布尔变量记录的,该变量可在chainparams.h中找到,在chainparams.cpp中我们可以看到三种网络对fRequireStandard的赋值。主网中fRequireStandard=true,其他二者为false。即主网只接受标准交易,测试网与私有网可以接受非标准交易。这也好理解,主网是真正上线运行的网络,交易必须是标准的,不然整个网络种的交易就会出错。而另外两者只是开发与测试时使用,测试交易不同状态下的运行情况,保证主网上线后的正常运行。
四、签名操作字节数
我们再来看看签操作字节数参数bytespersigop,其处理代码如下:
nBytesPerSigOp = GetArg("-bytespersigop",nBytesPerSigOp);
nBytesPerSigOp在src/policy/policy.h中声明为全局变量,并在其cpp中实现定义,并对其设置了默认值DEFAULT_BYTES_PER_SIGOP,该默认值也在src/policy/policy.h中进行了定义,默认值为20:
/** Default for -bytespersigop */
static const unsigned int DEFAULT_BYTES_PER_SIGOP =20;
以上即为本次研读内容,在本文我们分析了节点超时参数、最小交易费设置参数、非标准交易参数以及签名操作字节数参数,可以了解到比特币网络中对于交易费是有最低限额要求的,如果太少将影响我们的交易,所以大家在转账时如果想保证交易的成功,交易费这块一定不能太少哦!希望对大家理解这块源码有帮助,也欢迎大家留言讨论。
区块链研习社源码研读班 菜菜子