在上一篇文章中,我们知道了,在交易以前要先判断entry是否有效。验证是否有效需要判断以下几个参数:
1)检查地址是否有效
2)交易额是否有效
3)交易额是否小于0
4)拒绝小额交易
今天,我们在来看看拒绝小额交易的代码
// Reject dust outputs:
if (retval && GUIUtil::isDust(ui->payTo->text(),ui->payAmount->value())) {
ui->payAmount->setValid(false);
retval = false;
}
其中的函数GUIUtil::isDust()是判断该交易是否为dust,该函数定义在guiutil.cpp文件中。函数如下:
bool isDust(const QString& address,const CAmount& amount)
{
CTxDestination dest = DecodeDestination(address.toStdString()); //编译地址
CScript script = GetScriptForDestination(dest); //获取脚本
CTxOuttxOut(amount, script);
return IsDust(txOut, ::dustRelayFee);
}
1 DecodeDestination()
DecodeDestination()函数是用于编译地址,该函数定义在base58.cpp中,定义如下:
CTxDestination DecodeDestination(conststd::string& str)
{
return CBitcoinAddress(str).Get();
}
CBitcoinAddress类定义如下:
/** base58-encoded Bitcoin addresses.
*Public-key-hash-addresses have version 0 (or 111 testnet).
*The data vector contains RIPEMD160(SHA256(pubkey)), where pubkey is theserialized public key.
*Script-hash-addresses have version 5 (or 196 testnet).
*The data vector contains RIPEMD160(SHA256(cscript)), where cscript is theserialized redemption script.
*/
class CBitcoinAddress : public CBase58Data{
public:
bool Set(const CKeyID &id);
bool Set(const CScriptID &id);
bool Set(const CTxDestination &dest);
bool IsValid() const;
bool IsValid(const CChainParams ¶ms) const;
CBitcoinAddress() {}
CBitcoinAddress(const CTxDestination &dest) { Set(dest); }
CBitcoinAddress(const std::string& strAddress) {SetString(strAddress); }
CBitcoinAddress(const char* pszAddress) {SetString(pszAddress); }
CTxDestination Get() const;
};
从注释可以看出:该类用于base58编码,版本5以前用公钥地址,版本5以后用脚本公钥
Get()函数定义如下;
CTxDestination CBitcoinAddress::Get() const
{
if (!IsValid())
return CNoDestination();
uint160 id;
memcpy(&id,vchData.data(), 20);
if (vchVersion == Params().Base58Prefix(CChainParams::PUBKEY_ADDRESS))//公钥地址编译
return CKeyID(id);
else if (vchVersion ==Params().Base58Prefix(CChainParams::SCRIPT_ADDRESS))//脚本地址编译
return CScriptID(id);
else
return CNoDestination();
}
2 GetScriptForDestination
GetScriptForDestination()函数,获取脚本,函数定义如下:
CScript GetScriptForDestination(constCTxDestination& dest)
{
CScript script;
boost::apply_visitor(CScriptVisitor(&script), dest);
return script;
}
3 IsDust()
IsDust()函数为判断是否为dust的函数,定义在policy.cpp中,定义如下:
bool IsDust(const CTxOut& txout, constCFeeRate& dustRelayFeeIn)
{
return (txout.nValue < GetDustThreshold(txout, dustRelayFeeIn));
}
其中函数GetDustThreshold()是检测设定的dust值,定义在policy.cpp中。
CAmount GetDustThreshold(const CTxOut&txout, const CFeeRate& dustRelayFeeIn)
{
//"Dust" is defined in terms of dustRelayFee,
// which hasunits satoshis-per-kilobyte.
// If you'd pay more in fees than the value of the output
// to spend something, then we consider it dust.
// A typical spendable non-segwit txout is 34 bytes big, and will
// need a CTxIn of at least 148 bytes to spend:
// so dust is a spendable txout less than
// 182*dustRelayFee/1000 (in satoshis).
// 546 satoshis at the default rate of 3000 sat/kB
// A typical spendablesegwit txout is 31 bytesbig, and will
// need a CTxIn of at least 67 bytes to spend:
// so dust is a spendable txout less than
// 98*dustRelayFee/1000 (in satoshis).
// 294 satoshisat the default rate of 3000 sat/kB.
if (txout.scriptPubKey.IsUnspendable()) //判断脚本格式是否支持
return 0;
size_t nSize = GetSerializeSize(txout, SER_DISK, 0);
int witnessversion = 0;
std::vector witnessprogram;
//判断是否支持隔离见证
if (txout.scriptPubKey.IsWitnessProgram(witnessversion, witnessprogram)){
// sum the sizes of the parts of a transaction input
// with 75% segwit discount applied to the script size.
nSize += (32 + 4 + 1 + (107 /WITNESS_SCALE_FACTOR)+ 4);
}else {
nSize += (32 + 4 + 1 + 107 + 4); // the 148 mentioned above
}
return dustRelayFeeIn.GetFee(nSize);
}
由注释可以看出,交易费用是否为dust与下面几个因素有关
1)设定的dustRelayFee,dustRelayFee设置的越大,则dust越大
2)如果没用隔离见证,则dust较大:dust = 182*dustRelayFee/1000,当交易费用为3000 sat/kB.,是dust= 546sat。
3)如果有隔离见证,则dust较小。Dust=98*dustRelayFee/1000,当交易费用为3000 sat/kB.,是dust= 294sat。
本文由【区块链研习社】优质内容计划支持,更多关于区块链的深度好文,请点击[区块链研习社](http://www.jianshu.com/c/b17f09dc2831)
区块链研习社比特币源码研读班 electroman
以下是广告:
我们区块链研习社已创建“区块链研习社币圈交流”小密圈”,在小密圈中,我们将带领大家一起学习区块链的原理与投资,还将提供区块链基本原理解答、交易所注册与交易操作、ICO交易与操作、投资分析、风险分析等内容。

网友评论