美文网首页
比特币源码研读之五

比特币源码研读之五

作者: 自如致知 | 来源:发表于2017-11-05 09:42 被阅读0次

    本篇文章涉及的文件有:

    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);
    }
    

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

    相关文章

      网友评论

          本文标题:比特币源码研读之五

          本文链接:https://www.haomeiwen.com/subject/gcdcmxtx.html