比特币源码研读之五

本篇文章涉及的文件有:

init.cpp、wallet.cpp、policy.cpp

我们接着上篇内容继续分析方法AppInitParameterInteraction().在此之前,大家可以从https://bitcoin.org/en/developer-guide#non-standard-transactions 学习到比特币中有关标准交易(Standard Transaction)以及非标准交易(Non-standard Transaction)的定义,主要根据交易中包含的信息是否是有效的且已经定义好的,如锁定脚本与解锁脚本中是否包含了没有定义的脚本命令等,判断一个交易是否是标准交易封装在函数policy.cpp中的IsStandardTx ()方法中,我们后续将具体分析该函数的内容。
可以通过参数acceptnonstdtxn来指定节点是否接受非标准交易。在文件chainparams.cpp中可以看到,只有主网络的参数fRequireStandard设置为true, 而Test和Reg网络为false,从下面的代码可以看出,如果在启动主网络的节点设置acceptnonstdtxn为false,是会抛出异常的。

fRequireStandard = !gArgs.GetBoolArg("-acceptnonstdtxn", !chainparams.RequireStandard());
if (chainparams.RequireStandard() && !fRequireStandard)
   return InitError(strprintf("acceptnonstdtxn is not currently supported for %s chain", 
              chainparams.NetworkIDString()));

下面的参数-bytespersigop用于policy.cpp的函数GetVirtualTransactionSize中计算交易的大小,默认值为20(衡量每个操作符大小,用于交易手续费的计算???后续需再研究该参数的具体作用)。

nBytesPerSigOp = gArgs.GetArg("-bytespersigop", nBytesPerSigOp);
int64_t GetVirtualTransactionSize(int64_t nWeight, int64_t nSigOpCost)
{
    return (std::max(nWeight, nSigOpCost * nBytesPerSigOp) + WITNESS_SCALE_FACTOR - 1) / WITNESS_SCALE_FACTOR;
}

如果节点开启了钱包服务,则需要设置与钱包相关的参数。

#ifdef ENABLE_WALLET
    if (!CWallet::ParameterInteraction())
        return false;
#endif

我们接下来将通过分析函数ParameterInteraction看下都有哪些和钱包服务相关的参数需要设置。

gArgs.SoftSetArg("-wallet", DEFAULT_WALLET_DAT);//设置默认的钱包文件名称wallet.dat
const bool is_multiwallet = gArgs.GetArgs("-wallet").size() > 1;//是否设置了多个-wallet值
if (gArgs.GetBoolArg("-disablewallet", DEFAULT_DISABLE_WALLET))//是否设置不启用钱包服务
return true;

用户可以选择加入区块链网络的参与度,如可以通过参数blocksonly设置不进行交易的获取和转发来减少带宽占用。

if (gArgs.GetBoolArg("-blocksonly", DEFAULT_BLOCKSONLY) && gArgs.SoftSetBoolArg("-walletbroadcast", false)) {
   LogPrintf("%s: parameter interaction: -blocksonly=1 -> setting -walletbroadcast=0\n", __func__);
}

节点程序有时候会运行出现故障等导致程序不能正常工作的问题,当钱包节点出现故障时,可以通过参数salvagewallet尝试恢复之前的公私钥对。

if (gArgs.GetBoolArg("-salvagewallet", false)) {
  if (is_multiwallet) {//如果通过参数salvagewallet进行恢复,只能指定单个钱包文件进行
      return InitError(strprintf("%s is only allowed with a single wallet file", "-salvagewallet"));
  }
  // Rewrite just private keys: rescan to find transactions
  if (gArgs.SoftSetBoolArg("-rescan", true)) {//重新扫描区块链,找到恢复后相关的交易
      LogPrintf("%s: parameter interaction: -salvagewallet=1 -> setting -rescan=1\n", __func__);
  }
}

有时候我们会遇到交易经过很长时间都没有被打包(如:交易手续费设置的太低),我们可以通过参数zapwallettxes尝试进行取消原有的交易。设置zapwallettxes=1会将本地节点中所有未打包的交易清空,同时默认会进行一个rescan。rescan完成后,重新发起一笔交易,使该交易包含了之前未被打包的交易所使用的UTXO。待该交易广播到网络进行打包,因为双花的检查,原有的交易将会被抛弃(参考:http://cryptomining-blog.com/tag/zapwallettxes/)。

int zapwallettxes = gArgs.GetArg("-zapwallettxes", 0);
    // -zapwallettxes implies dropping the mempool on startup//启动时情况内存池
    if (zapwallettxes != 0 && gArgs.SoftSetBoolArg("-persistmempool", false)) {
        LogPrintf("%s: parameter interaction: -zapwallettxes=%s -> setting -persistmempool=0\n", __func__, zapwallettxes);
}
// -zapwallettxes implies a rescan//进行rescan
    if (zapwallettxes != 0) {
        if (is_multiwallet) {
            return InitError(strprintf("%s is only allowed with a single wallet file", "-zapwallettxes"));
        }
        if (gArgs.SoftSetBoolArg("-rescan", true)) {
            LogPrintf("%s: parameter interaction: -zapwallettxes=%s -> setting -rescan=1\n", __func__, zapwallettxes);
        }
}

随着比特币程序的升级,钱包文件的格式也会有更新,可以通过-upgradewallet参数设置进行钱包文件的升级操作,不过升级过程只支持一个钱包文件的情况(为什么不能支持多个,后续分析过程中应该会有答案)。

if (is_multiwallet) {
    if (gArgs.GetBoolArg("-upgradewallet", false)) {//升级钱包文件wallet.dat的格式
        return InitError(strprintf("%s is only allowed with a single wallet file", "-upgradewallet"));
    }
 }

可以通过参数sysperms控制是否已系统默认权限创建文件,但是在开启钱包功能的节点是不能启用的(详细请参考:http://www.jianshu.com/p/d42558e7e8e8).

if (gArgs.GetBoolArg("-sysperms", false))
    return InitError("-sysperms is not allowed in combination with enabled wallet functionality");

之前的文章我们分析过prune和rescan的作用,一个是裁剪一个是重建交易,两者是互斥的。

if (gArgs.GetArg("-prune", 0) && gArgs.GetBoolArg("-rescan", false))
    return InitError(_("Rescans are not possible in pruned mode. You will need to use -reindex which will download the whole blockchain again."));

用户是可以设置交易费率的,程序为保证用户的权益,当交易费率设置的很高时会给出相应的提示。设置的交易费率minRelayTxFee和mintxfee如果高于默认的最高交易费率HIGH_TX_FEE_PER_KB(0.01btc),给给出警告信息。

if (::minRelayTxFee.GetFeePerK() > HIGH_TX_FEE_PER_KB)
        InitWarning(AmountHighWarn("-minrelaytxfee") + " " +
                    _("The wallet will avoid paying less than the minimum relay fee."));

    if (gArgs.IsArgSet("-mintxfee"))
    {
        CAmount n = 0;
        if (!ParseMoney(gArgs.GetArg("-mintxfee", ""), n) || 0 == n)
            return InitError(AmountErrMsg("mintxfee", gArgs.GetArg("-mintxfee", "")));
        if (n > HIGH_TX_FEE_PER_KB)
            InitWarning(AmountHighWarn("-mintxfee") + " " +
                        _("This is the minimum transaction fee you pay on every transaction."));
        CWallet::minTxFee = CFeeRate(n);
}

当交易估算交易费率的数据不足时,将采用fallbackfee的值作为交易费率的默认值,同样如果该值超过了HIGH_TX_FEE_PER_KB也会收到警告。

if (gArgs.IsArgSet("-fallbackfee"))
{
    CAmount nFeePerK = 0;
    if (!ParseMoney(gArgs.GetArg("-fallbackfee", ""), nFeePerK))
        return InitError(strprintf(_("Invalid amount for -fallbackfee=<amount>: '%s'"), gArgs.GetArg("-fallbackfee", "")));
    if (nFeePerK > HIGH_TX_FEE_PER_KB)
        InitWarning(AmountHighWarn("-fallbackfee") + " " +
                        _("This is the transaction fee you may pay when fee estimates are not available."));
        CWallet::fallbackFee = CFeeRate(nFeePerK);
}

好了,本篇文章就先分析到这。因本人水平有限,如有问题,欢迎大家批评指出,非常感谢。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,185评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,445评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,684评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,564评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,681评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,874评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,025评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,761评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,217评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,545评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,694评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,351评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,988评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,778评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,007评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,427评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,580评论 2 349

推荐阅读更多精彩内容

  • 比特币昨日已成功突破3万大关,这个价格是上个月还处于无法想象的,作为普罗大众的我们是根本不敢想的。不过这点还是要佩...
    菜菜子_forest阅读 3,492评论 2 6
  • 一、快速术语检索 比特币地址:(例如:1DSrfJdB2AnWaFNgSbv3MZC2m74996JafV)由一串...
    不如假如阅读 15,899评论 4 88
  • 01 很多家长常常问我,该如何教育孩子? 我告诉家长,爱,就是教育孩子最佳方法。 但究竟该怎么爱孩子呢? 我们看到...
    颖之老师阅读 468评论 0 2
  • 感情爆满手才会去全神贯注地描绘 那些被我们遗忘在记忆里的纯真 沙沙作响于回首的爱与恨 昨夜雨说不哭泣却簌簌的落眼泪...
    暮雨清风阅读 278评论 11 14