Merge pull request #4899
0be990b
Move CTxDestination from script/script to script/standard (Pieter Wuille)
This commit is contained in:
commit
69dd8c919a
@ -17,6 +17,7 @@
|
|||||||
#include "chainparams.h"
|
#include "chainparams.h"
|
||||||
#include "key.h"
|
#include "key.h"
|
||||||
#include "script/script.h"
|
#include "script/script.h"
|
||||||
|
#include "script/standard.h"
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
@ -224,9 +224,8 @@ static void MutateTxAddOutAddr(CMutableTransaction& tx, const string& strInput)
|
|||||||
if (!addr.IsValid())
|
if (!addr.IsValid())
|
||||||
throw runtime_error("invalid TX output address");
|
throw runtime_error("invalid TX output address");
|
||||||
|
|
||||||
// build standard output script via SetDestination()
|
// build standard output script via GetScriptForDestination()
|
||||||
CScript scriptPubKey;
|
CScript scriptPubKey = GetScriptForDestination(addr.Get());
|
||||||
scriptPubKey.SetDestination(addr.Get());
|
|
||||||
|
|
||||||
// construct TxOut, append to transaction output list
|
// construct TxOut, append to transaction output list
|
||||||
CTxOut txout(value, scriptPubKey);
|
CTxOut txout(value, scriptPubKey);
|
||||||
|
@ -13,6 +13,8 @@
|
|||||||
#include "init.h"
|
#include "init.h"
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "protocol.h"
|
#include "protocol.h"
|
||||||
|
#include "script/script.h"
|
||||||
|
#include "script/standard.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
@ -222,7 +224,7 @@ QString formatBitcoinURI(const SendCoinsRecipient &info)
|
|||||||
bool isDust(const QString& address, qint64 amount)
|
bool isDust(const QString& address, qint64 amount)
|
||||||
{
|
{
|
||||||
CTxDestination dest = CBitcoinAddress(address.toStdString()).Get();
|
CTxDestination dest = CBitcoinAddress(address.toStdString()).Get();
|
||||||
CScript script; script.SetDestination(dest);
|
CScript script = GetScriptForDestination(dest);
|
||||||
CTxOut txOut(amount, script);
|
CTxOut txOut(amount, script);
|
||||||
return txOut.IsDust(::minRelayTxFee);
|
return txOut.IsDust(::minRelayTxFee);
|
||||||
}
|
}
|
||||||
|
@ -609,7 +609,7 @@ void PaymentServer::fetchPaymentACK(CWallet* wallet, SendCoinsRecipient recipien
|
|||||||
std::string strAccount = account.toStdString();
|
std::string strAccount = account.toStdString();
|
||||||
set<CTxDestination> refundAddresses = wallet->GetAccountAddresses(strAccount);
|
set<CTxDestination> refundAddresses = wallet->GetAccountAddresses(strAccount);
|
||||||
if (!refundAddresses.empty()) {
|
if (!refundAddresses.empty()) {
|
||||||
CScript s; s.SetDestination(*refundAddresses.begin());
|
CScript s = GetScriptForDestination(*refundAddresses.begin());
|
||||||
payments::Output* refund_to = payment.add_refund_to();
|
payments::Output* refund_to = payment.add_refund_to();
|
||||||
refund_to->set_script(&s[0], s.size());
|
refund_to->set_script(&s[0], s.size());
|
||||||
}
|
}
|
||||||
@ -620,7 +620,7 @@ void PaymentServer::fetchPaymentACK(CWallet* wallet, SendCoinsRecipient recipien
|
|||||||
CKeyID keyID = newKey.GetID();
|
CKeyID keyID = newKey.GetID();
|
||||||
wallet->SetAddressBook(keyID, strAccount, "refund");
|
wallet->SetAddressBook(keyID, strAccount, "refund");
|
||||||
|
|
||||||
CScript s; s.SetDestination(keyID);
|
CScript s = GetScriptForDestination(keyID);
|
||||||
payments::Output* refund_to = payment.add_refund_to();
|
payments::Output* refund_to = payment.add_refund_to();
|
||||||
refund_to->set_script(&s[0], s.size());
|
refund_to->set_script(&s[0], s.size());
|
||||||
}
|
}
|
||||||
|
@ -241,8 +241,7 @@ WalletModel::SendCoinsReturn WalletModel::prepareTransaction(WalletModelTransact
|
|||||||
setAddress.insert(rcp.address);
|
setAddress.insert(rcp.address);
|
||||||
++nAddresses;
|
++nAddresses;
|
||||||
|
|
||||||
CScript scriptPubKey;
|
CScript scriptPubKey = GetScriptForDestination(CBitcoinAddress(rcp.address.toStdString()).Get());
|
||||||
scriptPubKey.SetDestination(CBitcoinAddress(rcp.address.toStdString()).Get());
|
|
||||||
vecSend.push_back(std::pair<CScript, int64_t>(scriptPubKey, rcp.amount));
|
vecSend.push_back(std::pair<CScript, int64_t>(scriptPubKey, rcp.amount));
|
||||||
|
|
||||||
total += rcp.amount;
|
total += rcp.amount;
|
||||||
|
@ -6,6 +6,8 @@
|
|||||||
#include "rpcserver.h"
|
#include "rpcserver.h"
|
||||||
#include "init.h"
|
#include "init.h"
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
|
#include "script/script.h"
|
||||||
|
#include "script/standard.h"
|
||||||
#include "sync.h"
|
#include "sync.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "utiltime.h"
|
#include "utiltime.h"
|
||||||
@ -161,7 +163,7 @@ Value importaddress(const Array& params, bool fHelp)
|
|||||||
|
|
||||||
CBitcoinAddress address(params[0].get_str());
|
CBitcoinAddress address(params[0].get_str());
|
||||||
if (address.IsValid()) {
|
if (address.IsValid()) {
|
||||||
script.SetDestination(address.Get());
|
script = GetScriptForDestination(address.Get());
|
||||||
} else if (IsHex(params[0].get_str())) {
|
} else if (IsHex(params[0].get_str())) {
|
||||||
std::vector<unsigned char> data(ParseHex(params[0].get_str()));
|
std::vector<unsigned char> data(ParseHex(params[0].get_str()));
|
||||||
script = CScript(data.begin(), data.end());
|
script = CScript(data.begin(), data.end());
|
||||||
|
@ -250,8 +250,7 @@ CScript _createmultisig_redeemScript(const Array& params)
|
|||||||
throw runtime_error(" Invalid public key: "+ks);
|
throw runtime_error(" Invalid public key: "+ks);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
CScript result;
|
CScript result = GetScriptForMultisig(nRequired, pubkeys);
|
||||||
result.SetMultisig(nRequired, pubkeys);
|
|
||||||
|
|
||||||
if (result.size() > MAX_SCRIPT_ELEMENT_SIZE)
|
if (result.size() > MAX_SCRIPT_ELEMENT_SIZE)
|
||||||
throw runtime_error(
|
throw runtime_error(
|
||||||
|
@ -366,8 +366,7 @@ Value createrawtransaction(const Array& params, bool fHelp)
|
|||||||
throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, duplicated address: ")+s.name_);
|
throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, duplicated address: ")+s.name_);
|
||||||
setAddress.insert(address);
|
setAddress.insert(address);
|
||||||
|
|
||||||
CScript scriptPubKey;
|
CScript scriptPubKey = GetScriptForDestination(address.Get());
|
||||||
scriptPubKey.SetDestination(address.Get());
|
|
||||||
int64_t nAmount = AmountFromValue(s.value_);
|
int64_t nAmount = AmountFromValue(s.value_);
|
||||||
|
|
||||||
CTxOut out(nAmount, scriptPubKey);
|
CTxOut out(nAmount, scriptPubKey);
|
||||||
|
@ -124,8 +124,7 @@ CBitcoinAddress GetAccountAddress(string strAccount, bool bForceNew=false)
|
|||||||
// Check if the current key has been used
|
// Check if the current key has been used
|
||||||
if (account.vchPubKey.IsValid())
|
if (account.vchPubKey.IsValid())
|
||||||
{
|
{
|
||||||
CScript scriptPubKey;
|
CScript scriptPubKey = GetScriptForDestination(account.vchPubKey.GetID());
|
||||||
scriptPubKey.SetDestination(account.vchPubKey.GetID());
|
|
||||||
for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin();
|
for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin();
|
||||||
it != pwalletMain->mapWallet.end() && account.vchPubKey.IsValid();
|
it != pwalletMain->mapWallet.end() && account.vchPubKey.IsValid();
|
||||||
++it)
|
++it)
|
||||||
@ -472,10 +471,9 @@ Value getreceivedbyaddress(const Array& params, bool fHelp)
|
|||||||
|
|
||||||
// Bitcoin address
|
// Bitcoin address
|
||||||
CBitcoinAddress address = CBitcoinAddress(params[0].get_str());
|
CBitcoinAddress address = CBitcoinAddress(params[0].get_str());
|
||||||
CScript scriptPubKey;
|
|
||||||
if (!address.IsValid())
|
if (!address.IsValid())
|
||||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Bitcoin address");
|
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Bitcoin address");
|
||||||
scriptPubKey.SetDestination(address.Get());
|
CScript scriptPubKey = GetScriptForDestination(address.Get());
|
||||||
if (!IsMine(*pwalletMain,scriptPubKey))
|
if (!IsMine(*pwalletMain,scriptPubKey))
|
||||||
return (double)0.0;
|
return (double)0.0;
|
||||||
|
|
||||||
@ -849,8 +847,7 @@ Value sendmany(const Array& params, bool fHelp)
|
|||||||
throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, duplicated address: ")+s.name_);
|
throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, duplicated address: ")+s.name_);
|
||||||
setAddress.insert(address);
|
setAddress.insert(address);
|
||||||
|
|
||||||
CScript scriptPubKey;
|
CScript scriptPubKey = GetScriptForDestination(address.Get());
|
||||||
scriptPubKey.SetDestination(address.Get());
|
|
||||||
int64_t nAmount = AmountFromValue(s.value_);
|
int64_t nAmount = AmountFromValue(s.value_);
|
||||||
totalAmount += nAmount;
|
totalAmount += nAmount;
|
||||||
|
|
||||||
|
@ -253,43 +253,3 @@ bool CScript::HasCanonicalPushes() const
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
class CScriptVisitor : public boost::static_visitor<bool>
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
CScript *script;
|
|
||||||
public:
|
|
||||||
CScriptVisitor(CScript *scriptin) { script = scriptin; }
|
|
||||||
|
|
||||||
bool operator()(const CNoDestination &dest) const {
|
|
||||||
script->clear();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator()(const CKeyID &keyID) const {
|
|
||||||
script->clear();
|
|
||||||
*script << OP_DUP << OP_HASH160 << keyID << OP_EQUALVERIFY << OP_CHECKSIG;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator()(const CScriptID &scriptID) const {
|
|
||||||
script->clear();
|
|
||||||
*script << OP_HASH160 << scriptID << OP_EQUAL;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
void CScript::SetDestination(const CTxDestination& dest)
|
|
||||||
{
|
|
||||||
boost::apply_visitor(CScriptVisitor(this), dest);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CScript::SetMultisig(int nRequired, const std::vector<CPubKey>& keys)
|
|
||||||
{
|
|
||||||
this->clear();
|
|
||||||
|
|
||||||
*this << EncodeOP_N(nRequired);
|
|
||||||
BOOST_FOREACH(const CPubKey& key, keys)
|
|
||||||
*this << key;
|
|
||||||
*this << EncodeOP_N(keys.size()) << OP_CHECKMULTISIG;
|
|
||||||
}
|
|
||||||
|
@ -320,20 +320,6 @@ inline std::string ValueString(const std::vector<unsigned char>& vch)
|
|||||||
return HexStr(vch);
|
return HexStr(vch);
|
||||||
}
|
}
|
||||||
|
|
||||||
class CNoDestination {
|
|
||||||
public:
|
|
||||||
friend bool operator==(const CNoDestination &a, const CNoDestination &b) { return true; }
|
|
||||||
friend bool operator<(const CNoDestination &a, const CNoDestination &b) { return true; }
|
|
||||||
};
|
|
||||||
|
|
||||||
/** A txout script template with a specific destination. It is either:
|
|
||||||
* * CNoDestination: no destination set
|
|
||||||
* * CKeyID: TX_PUBKEYHASH destination
|
|
||||||
* * CScriptID: TX_SCRIPTHASH destination
|
|
||||||
* A CTxDestination is the internal data type encoded in a CBitcoinAddress
|
|
||||||
*/
|
|
||||||
typedef boost::variant<CNoDestination, CKeyID, CScriptID> CTxDestination;
|
|
||||||
|
|
||||||
/** Serialized script, used inside transaction inputs and outputs */
|
/** Serialized script, used inside transaction inputs and outputs */
|
||||||
class CScript : public std::vector<unsigned char>
|
class CScript : public std::vector<unsigned char>
|
||||||
{
|
{
|
||||||
@ -604,9 +590,6 @@ public:
|
|||||||
return (size() > 0 && *begin() == OP_RETURN);
|
return (size() > 0 && *begin() == OP_RETURN);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetDestination(const CTxDestination& address);
|
|
||||||
void SetMultisig(int nRequired, const std::vector<CPubKey>& keys);
|
|
||||||
|
|
||||||
std::string ToString() const
|
std::string ToString() const
|
||||||
{
|
{
|
||||||
std::string str;
|
std::string str;
|
||||||
|
@ -252,3 +252,50 @@ bool ExtractDestinations(const CScript& scriptPubKey, txnouttype& typeRet, vecto
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
class CScriptVisitor : public boost::static_visitor<bool>
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
CScript *script;
|
||||||
|
public:
|
||||||
|
CScriptVisitor(CScript *scriptin) { script = scriptin; }
|
||||||
|
|
||||||
|
bool operator()(const CNoDestination &dest) const {
|
||||||
|
script->clear();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator()(const CKeyID &keyID) const {
|
||||||
|
script->clear();
|
||||||
|
*script << OP_DUP << OP_HASH160 << keyID << OP_EQUALVERIFY << OP_CHECKSIG;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator()(const CScriptID &scriptID) const {
|
||||||
|
script->clear();
|
||||||
|
*script << OP_HASH160 << scriptID << OP_EQUAL;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
CScript GetScriptForDestination(const CTxDestination& dest)
|
||||||
|
{
|
||||||
|
CScript script;
|
||||||
|
|
||||||
|
boost::apply_visitor(CScriptVisitor(&script), dest);
|
||||||
|
return script;
|
||||||
|
}
|
||||||
|
|
||||||
|
CScript GetScriptForMultisig(int nRequired, const std::vector<CPubKey>& keys)
|
||||||
|
{
|
||||||
|
CScript script;
|
||||||
|
|
||||||
|
script << CScript::EncodeOP_N(nRequired);
|
||||||
|
BOOST_FOREACH(const CPubKey& key, keys)
|
||||||
|
script << key;
|
||||||
|
script << CScript::EncodeOP_N(keys.size()) << OP_CHECKMULTISIG;
|
||||||
|
return script;
|
||||||
|
}
|
||||||
|
@ -45,6 +45,20 @@ enum txnouttype
|
|||||||
TX_NULL_DATA,
|
TX_NULL_DATA,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class CNoDestination {
|
||||||
|
public:
|
||||||
|
friend bool operator==(const CNoDestination &a, const CNoDestination &b) { return true; }
|
||||||
|
friend bool operator<(const CNoDestination &a, const CNoDestination &b) { return true; }
|
||||||
|
};
|
||||||
|
|
||||||
|
/** A txout script template with a specific destination. It is either:
|
||||||
|
* * CNoDestination: no destination set
|
||||||
|
* * CKeyID: TX_PUBKEYHASH destination
|
||||||
|
* * CScriptID: TX_SCRIPTHASH destination
|
||||||
|
* A CTxDestination is the internal data type encoded in a CBitcoinAddress
|
||||||
|
*/
|
||||||
|
typedef boost::variant<CNoDestination, CKeyID, CScriptID> CTxDestination;
|
||||||
|
|
||||||
const char* GetTxnOutputType(txnouttype t);
|
const char* GetTxnOutputType(txnouttype t);
|
||||||
|
|
||||||
bool Solver(const CScript& scriptPubKey, txnouttype& typeRet, std::vector<std::vector<unsigned char> >& vSolutionsRet);
|
bool Solver(const CScript& scriptPubKey, txnouttype& typeRet, std::vector<std::vector<unsigned char> >& vSolutionsRet);
|
||||||
@ -53,4 +67,7 @@ bool IsStandard(const CScript& scriptPubKey, txnouttype& whichType);
|
|||||||
bool ExtractDestination(const CScript& scriptPubKey, CTxDestination& addressRet);
|
bool ExtractDestination(const CScript& scriptPubKey, CTxDestination& addressRet);
|
||||||
bool ExtractDestinations(const CScript& scriptPubKey, txnouttype& typeRet, std::vector<CTxDestination>& addressRet, int& nRequiredRet);
|
bool ExtractDestinations(const CScript& scriptPubKey, txnouttype& typeRet, std::vector<CTxDestination>& addressRet, int& nRequiredRet);
|
||||||
|
|
||||||
|
CScript GetScriptForDestination(const CTxDestination& dest);
|
||||||
|
CScript GetScriptForMultisig(int nRequired, const std::vector<CPubKey>& keys);
|
||||||
|
|
||||||
#endif // H_BITCOIN_SCRIPT_STANDARD
|
#endif // H_BITCOIN_SCRIPT_STANDARD
|
||||||
|
@ -173,7 +173,7 @@ BOOST_AUTO_TEST_CASE(DoS_mapOrphans)
|
|||||||
tx.vin[0].scriptSig << OP_1;
|
tx.vin[0].scriptSig << OP_1;
|
||||||
tx.vout.resize(1);
|
tx.vout.resize(1);
|
||||||
tx.vout[0].nValue = 1*CENT;
|
tx.vout[0].nValue = 1*CENT;
|
||||||
tx.vout[0].scriptPubKey.SetDestination(key.GetPubKey().GetID());
|
tx.vout[0].scriptPubKey = GetScriptForDestination(key.GetPubKey().GetID());
|
||||||
|
|
||||||
AddOrphanTx(tx, i);
|
AddOrphanTx(tx, i);
|
||||||
}
|
}
|
||||||
@ -189,7 +189,7 @@ BOOST_AUTO_TEST_CASE(DoS_mapOrphans)
|
|||||||
tx.vin[0].prevout.hash = txPrev.GetHash();
|
tx.vin[0].prevout.hash = txPrev.GetHash();
|
||||||
tx.vout.resize(1);
|
tx.vout.resize(1);
|
||||||
tx.vout[0].nValue = 1*CENT;
|
tx.vout[0].nValue = 1*CENT;
|
||||||
tx.vout[0].scriptPubKey.SetDestination(key.GetPubKey().GetID());
|
tx.vout[0].scriptPubKey = GetScriptForDestination(key.GetPubKey().GetID());
|
||||||
SignSignature(keystore, txPrev, tx, 0);
|
SignSignature(keystore, txPrev, tx, 0);
|
||||||
|
|
||||||
AddOrphanTx(tx, i);
|
AddOrphanTx(tx, i);
|
||||||
@ -203,7 +203,7 @@ BOOST_AUTO_TEST_CASE(DoS_mapOrphans)
|
|||||||
CMutableTransaction tx;
|
CMutableTransaction tx;
|
||||||
tx.vout.resize(1);
|
tx.vout.resize(1);
|
||||||
tx.vout[0].nValue = 1*CENT;
|
tx.vout[0].nValue = 1*CENT;
|
||||||
tx.vout[0].scriptPubKey.SetDestination(key.GetPubKey().GetID());
|
tx.vout[0].scriptPubKey = GetScriptForDestination(key.GetPubKey().GetID());
|
||||||
tx.vin.resize(500);
|
tx.vin.resize(500);
|
||||||
for (unsigned int j = 0; j < tx.vin.size(); j++)
|
for (unsigned int j = 0; j < tx.vin.size(); j++)
|
||||||
{
|
{
|
||||||
|
@ -170,7 +170,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
|
|||||||
tx.vin[0].scriptSig = CScript() << OP_1;
|
tx.vin[0].scriptSig = CScript() << OP_1;
|
||||||
tx.vout[0].nValue = 4900000000LL;
|
tx.vout[0].nValue = 4900000000LL;
|
||||||
script = CScript() << OP_0;
|
script = CScript() << OP_0;
|
||||||
tx.vout[0].scriptPubKey.SetDestination(script.GetID());
|
tx.vout[0].scriptPubKey = GetScriptForDestination(script.GetID());
|
||||||
hash = tx.GetHash();
|
hash = tx.GetHash();
|
||||||
mempool.addUnchecked(hash, CTxMemPoolEntry(tx, 11, GetTime(), 111.0, 11));
|
mempool.addUnchecked(hash, CTxMemPoolEntry(tx, 11, GetTime(), 111.0, 11));
|
||||||
tx.vin[0].prevout.hash = hash;
|
tx.vin[0].prevout.hash = hash;
|
||||||
|
@ -68,14 +68,14 @@ BOOST_AUTO_TEST_CASE(sign)
|
|||||||
// different keys, straight/P2SH, pubkey/pubkeyhash
|
// different keys, straight/P2SH, pubkey/pubkeyhash
|
||||||
CScript standardScripts[4];
|
CScript standardScripts[4];
|
||||||
standardScripts[0] << key[0].GetPubKey() << OP_CHECKSIG;
|
standardScripts[0] << key[0].GetPubKey() << OP_CHECKSIG;
|
||||||
standardScripts[1].SetDestination(key[1].GetPubKey().GetID());
|
standardScripts[1] = GetScriptForDestination(key[1].GetPubKey().GetID());
|
||||||
standardScripts[2] << key[1].GetPubKey() << OP_CHECKSIG;
|
standardScripts[2] << key[1].GetPubKey() << OP_CHECKSIG;
|
||||||
standardScripts[3].SetDestination(key[2].GetPubKey().GetID());
|
standardScripts[3] = GetScriptForDestination(key[2].GetPubKey().GetID());
|
||||||
CScript evalScripts[4];
|
CScript evalScripts[4];
|
||||||
for (int i = 0; i < 4; i++)
|
for (int i = 0; i < 4; i++)
|
||||||
{
|
{
|
||||||
keystore.AddCScript(standardScripts[i]);
|
keystore.AddCScript(standardScripts[i]);
|
||||||
evalScripts[i].SetDestination(standardScripts[i].GetID());
|
evalScripts[i] = GetScriptForDestination(standardScripts[i].GetID());
|
||||||
}
|
}
|
||||||
|
|
||||||
CMutableTransaction txFrom; // Funding transaction:
|
CMutableTransaction txFrom; // Funding transaction:
|
||||||
@ -129,8 +129,7 @@ BOOST_AUTO_TEST_CASE(norecurse)
|
|||||||
CScript invalidAsScript;
|
CScript invalidAsScript;
|
||||||
invalidAsScript << OP_INVALIDOPCODE << OP_INVALIDOPCODE;
|
invalidAsScript << OP_INVALIDOPCODE << OP_INVALIDOPCODE;
|
||||||
|
|
||||||
CScript p2sh;
|
CScript p2sh = GetScriptForDestination(invalidAsScript.GetID());
|
||||||
p2sh.SetDestination(invalidAsScript.GetID());
|
|
||||||
|
|
||||||
CScript scriptSig;
|
CScript scriptSig;
|
||||||
scriptSig << Serialize(invalidAsScript);
|
scriptSig << Serialize(invalidAsScript);
|
||||||
@ -140,8 +139,7 @@ BOOST_AUTO_TEST_CASE(norecurse)
|
|||||||
|
|
||||||
// Try to recur, and verification should succeed because
|
// Try to recur, and verification should succeed because
|
||||||
// the inner HASH160 <> EQUAL should only check the hash:
|
// the inner HASH160 <> EQUAL should only check the hash:
|
||||||
CScript p2sh2;
|
CScript p2sh2 = GetScriptForDestination(p2sh.GetID());
|
||||||
p2sh2.SetDestination(p2sh.GetID());
|
|
||||||
CScript scriptSig2;
|
CScript scriptSig2;
|
||||||
scriptSig2 << Serialize(invalidAsScript) << Serialize(p2sh);
|
scriptSig2 << Serialize(invalidAsScript) << Serialize(p2sh);
|
||||||
|
|
||||||
@ -163,15 +161,15 @@ BOOST_AUTO_TEST_CASE(set)
|
|||||||
}
|
}
|
||||||
|
|
||||||
CScript inner[4];
|
CScript inner[4];
|
||||||
inner[0].SetDestination(key[0].GetPubKey().GetID());
|
inner[0] = GetScriptForDestination(key[0].GetPubKey().GetID());
|
||||||
inner[1].SetMultisig(2, std::vector<CPubKey>(keys.begin(), keys.begin()+2));
|
inner[1] = GetScriptForMultisig(2, std::vector<CPubKey>(keys.begin(), keys.begin()+2));
|
||||||
inner[2].SetMultisig(1, std::vector<CPubKey>(keys.begin(), keys.begin()+2));
|
inner[2] = GetScriptForMultisig(1, std::vector<CPubKey>(keys.begin(), keys.begin()+2));
|
||||||
inner[3].SetMultisig(2, std::vector<CPubKey>(keys.begin(), keys.begin()+3));
|
inner[3] = GetScriptForMultisig(2, std::vector<CPubKey>(keys.begin(), keys.begin()+3));
|
||||||
|
|
||||||
CScript outer[4];
|
CScript outer[4];
|
||||||
for (int i = 0; i < 4; i++)
|
for (int i = 0; i < 4; i++)
|
||||||
{
|
{
|
||||||
outer[i].SetDestination(inner[i].GetID());
|
outer[i] = GetScriptForDestination(inner[i].GetID());
|
||||||
keystore.AddCScript(inner[i]);
|
keystore.AddCScript(inner[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -244,8 +242,7 @@ BOOST_AUTO_TEST_CASE(switchover)
|
|||||||
CScript scriptSig;
|
CScript scriptSig;
|
||||||
scriptSig << Serialize(notValid);
|
scriptSig << Serialize(notValid);
|
||||||
|
|
||||||
CScript fund;
|
CScript fund = GetScriptForDestination(notValid.GetID());
|
||||||
fund.SetDestination(notValid.GetID());
|
|
||||||
|
|
||||||
|
|
||||||
// Validation should succeed under old rules (hash is correct):
|
// Validation should succeed under old rules (hash is correct):
|
||||||
@ -274,11 +271,11 @@ BOOST_AUTO_TEST_CASE(AreInputsStandard)
|
|||||||
txFrom.vout.resize(7);
|
txFrom.vout.resize(7);
|
||||||
|
|
||||||
// First three are standard:
|
// First three are standard:
|
||||||
CScript pay1; pay1.SetDestination(key[0].GetPubKey().GetID());
|
CScript pay1 = GetScriptForDestination(key[0].GetPubKey().GetID());
|
||||||
keystore.AddCScript(pay1);
|
keystore.AddCScript(pay1);
|
||||||
CScript pay1of3; pay1of3.SetMultisig(1, keys);
|
CScript pay1of3 = GetScriptForMultisig(1, keys);
|
||||||
|
|
||||||
txFrom.vout[0].scriptPubKey.SetDestination(pay1.GetID()); // P2SH (OP_CHECKSIG)
|
txFrom.vout[0].scriptPubKey = GetScriptForDestination(pay1.GetID()); // P2SH (OP_CHECKSIG)
|
||||||
txFrom.vout[0].nValue = 1000;
|
txFrom.vout[0].nValue = 1000;
|
||||||
txFrom.vout[1].scriptPubKey = pay1; // ordinary OP_CHECKSIG
|
txFrom.vout[1].scriptPubKey = pay1; // ordinary OP_CHECKSIG
|
||||||
txFrom.vout[1].nValue = 2000;
|
txFrom.vout[1].nValue = 2000;
|
||||||
@ -293,7 +290,7 @@ BOOST_AUTO_TEST_CASE(AreInputsStandard)
|
|||||||
oneAndTwo << OP_2 << key[3].GetPubKey() << key[4].GetPubKey() << key[5].GetPubKey();
|
oneAndTwo << OP_2 << key[3].GetPubKey() << key[4].GetPubKey() << key[5].GetPubKey();
|
||||||
oneAndTwo << OP_3 << OP_CHECKMULTISIG;
|
oneAndTwo << OP_3 << OP_CHECKMULTISIG;
|
||||||
keystore.AddCScript(oneAndTwo);
|
keystore.AddCScript(oneAndTwo);
|
||||||
txFrom.vout[3].scriptPubKey.SetDestination(oneAndTwo.GetID());
|
txFrom.vout[3].scriptPubKey = GetScriptForDestination(oneAndTwo.GetID());
|
||||||
txFrom.vout[3].nValue = 4000;
|
txFrom.vout[3].nValue = 4000;
|
||||||
|
|
||||||
// vout[4] is max sigops:
|
// vout[4] is max sigops:
|
||||||
@ -302,17 +299,17 @@ BOOST_AUTO_TEST_CASE(AreInputsStandard)
|
|||||||
fifteenSigops << key[i%3].GetPubKey();
|
fifteenSigops << key[i%3].GetPubKey();
|
||||||
fifteenSigops << OP_15 << OP_CHECKMULTISIG;
|
fifteenSigops << OP_15 << OP_CHECKMULTISIG;
|
||||||
keystore.AddCScript(fifteenSigops);
|
keystore.AddCScript(fifteenSigops);
|
||||||
txFrom.vout[4].scriptPubKey.SetDestination(fifteenSigops.GetID());
|
txFrom.vout[4].scriptPubKey = GetScriptForDestination(fifteenSigops.GetID());
|
||||||
txFrom.vout[4].nValue = 5000;
|
txFrom.vout[4].nValue = 5000;
|
||||||
|
|
||||||
// vout[5/6] are non-standard because they exceed MAX_P2SH_SIGOPS
|
// vout[5/6] are non-standard because they exceed MAX_P2SH_SIGOPS
|
||||||
CScript sixteenSigops; sixteenSigops << OP_16 << OP_CHECKMULTISIG;
|
CScript sixteenSigops; sixteenSigops << OP_16 << OP_CHECKMULTISIG;
|
||||||
keystore.AddCScript(sixteenSigops);
|
keystore.AddCScript(sixteenSigops);
|
||||||
txFrom.vout[5].scriptPubKey.SetDestination(fifteenSigops.GetID());
|
txFrom.vout[5].scriptPubKey = GetScriptForDestination(fifteenSigops.GetID());
|
||||||
txFrom.vout[5].nValue = 5000;
|
txFrom.vout[5].nValue = 5000;
|
||||||
CScript twentySigops; twentySigops << OP_CHECKMULTISIG;
|
CScript twentySigops; twentySigops << OP_CHECKMULTISIG;
|
||||||
keystore.AddCScript(twentySigops);
|
keystore.AddCScript(twentySigops);
|
||||||
txFrom.vout[6].scriptPubKey.SetDestination(twentySigops.GetID());
|
txFrom.vout[6].scriptPubKey = GetScriptForDestination(twentySigops.GetID());
|
||||||
txFrom.vout[6].nValue = 6000;
|
txFrom.vout[6].nValue = 6000;
|
||||||
|
|
||||||
|
|
||||||
@ -320,7 +317,7 @@ BOOST_AUTO_TEST_CASE(AreInputsStandard)
|
|||||||
|
|
||||||
CMutableTransaction txTo;
|
CMutableTransaction txTo;
|
||||||
txTo.vout.resize(1);
|
txTo.vout.resize(1);
|
||||||
txTo.vout[0].scriptPubKey.SetDestination(key[1].GetPubKey().GetID());
|
txTo.vout[0].scriptPubKey = GetScriptForDestination(key[1].GetPubKey().GetID());
|
||||||
|
|
||||||
txTo.vin.resize(5);
|
txTo.vin.resize(5);
|
||||||
for (int i = 0; i < 5; i++)
|
for (int i = 0; i < 5; i++)
|
||||||
@ -352,7 +349,7 @@ BOOST_AUTO_TEST_CASE(AreInputsStandard)
|
|||||||
|
|
||||||
CMutableTransaction txToNonStd1;
|
CMutableTransaction txToNonStd1;
|
||||||
txToNonStd1.vout.resize(1);
|
txToNonStd1.vout.resize(1);
|
||||||
txToNonStd1.vout[0].scriptPubKey.SetDestination(key[1].GetPubKey().GetID());
|
txToNonStd1.vout[0].scriptPubKey = GetScriptForDestination(key[1].GetPubKey().GetID());
|
||||||
txToNonStd1.vout[0].nValue = 1000;
|
txToNonStd1.vout[0].nValue = 1000;
|
||||||
txToNonStd1.vin.resize(1);
|
txToNonStd1.vin.resize(1);
|
||||||
txToNonStd1.vin[0].prevout.n = 5;
|
txToNonStd1.vin[0].prevout.n = 5;
|
||||||
@ -364,7 +361,7 @@ BOOST_AUTO_TEST_CASE(AreInputsStandard)
|
|||||||
|
|
||||||
CMutableTransaction txToNonStd2;
|
CMutableTransaction txToNonStd2;
|
||||||
txToNonStd2.vout.resize(1);
|
txToNonStd2.vout.resize(1);
|
||||||
txToNonStd2.vout[0].scriptPubKey.SetDestination(key[1].GetPubKey().GetID());
|
txToNonStd2.vout[0].scriptPubKey = GetScriptForDestination(key[1].GetPubKey().GetID());
|
||||||
txToNonStd2.vout[0].nValue = 1000;
|
txToNonStd2.vout[0].nValue = 1000;
|
||||||
txToNonStd2.vin.resize(1);
|
txToNonStd2.vin.resize(1);
|
||||||
txToNonStd2.vin[0].prevout.n = 6;
|
txToNonStd2.vin[0].prevout.n = 6;
|
||||||
|
@ -280,7 +280,7 @@ BOOST_AUTO_TEST_CASE(script_combineSigs)
|
|||||||
|
|
||||||
CMutableTransaction txFrom;
|
CMutableTransaction txFrom;
|
||||||
txFrom.vout.resize(1);
|
txFrom.vout.resize(1);
|
||||||
txFrom.vout[0].scriptPubKey.SetDestination(keys[0].GetPubKey().GetID());
|
txFrom.vout[0].scriptPubKey = GetScriptForDestination(keys[0].GetPubKey().GetID());
|
||||||
CScript& scriptPubKey = txFrom.vout[0].scriptPubKey;
|
CScript& scriptPubKey = txFrom.vout[0].scriptPubKey;
|
||||||
CMutableTransaction txTo;
|
CMutableTransaction txTo;
|
||||||
txTo.vin.resize(1);
|
txTo.vin.resize(1);
|
||||||
@ -309,7 +309,7 @@ BOOST_AUTO_TEST_CASE(script_combineSigs)
|
|||||||
// P2SH, single-signature case:
|
// P2SH, single-signature case:
|
||||||
CScript pkSingle; pkSingle << keys[0].GetPubKey() << OP_CHECKSIG;
|
CScript pkSingle; pkSingle << keys[0].GetPubKey() << OP_CHECKSIG;
|
||||||
keystore.AddCScript(pkSingle);
|
keystore.AddCScript(pkSingle);
|
||||||
scriptPubKey.SetDestination(pkSingle.GetID());
|
scriptPubKey = GetScriptForDestination(pkSingle.GetID());
|
||||||
SignSignature(keystore, txFrom, txTo, 0);
|
SignSignature(keystore, txFrom, txTo, 0);
|
||||||
combined = CombineSignatures(scriptPubKey, txTo, 0, scriptSig, empty);
|
combined = CombineSignatures(scriptPubKey, txTo, 0, scriptSig, empty);
|
||||||
BOOST_CHECK(combined == scriptSig);
|
BOOST_CHECK(combined == scriptSig);
|
||||||
@ -327,7 +327,7 @@ BOOST_AUTO_TEST_CASE(script_combineSigs)
|
|||||||
BOOST_CHECK(combined == scriptSig);
|
BOOST_CHECK(combined == scriptSig);
|
||||||
|
|
||||||
// Hardest case: Multisig 2-of-3
|
// Hardest case: Multisig 2-of-3
|
||||||
scriptPubKey.SetMultisig(2, pubkeys);
|
scriptPubKey = GetScriptForMultisig(2, pubkeys);
|
||||||
keystore.AddCScript(scriptPubKey);
|
keystore.AddCScript(scriptPubKey);
|
||||||
SignSignature(keystore, txFrom, txTo, 0);
|
SignSignature(keystore, txFrom, txTo, 0);
|
||||||
combined = CombineSignatures(scriptPubKey, txTo, 0, scriptSig, empty);
|
combined = CombineSignatures(scriptPubKey, txTo, 0, scriptSig, empty);
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
#include "key.h"
|
#include "key.h"
|
||||||
#include "script/script.h"
|
#include "script/script.h"
|
||||||
|
#include "script/standard.h"
|
||||||
#include "uint256.h"
|
#include "uint256.h"
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
@ -37,8 +38,7 @@ BOOST_AUTO_TEST_CASE(GetSigOpCount)
|
|||||||
BOOST_CHECK_EQUAL(s1.GetSigOpCount(true), 3U);
|
BOOST_CHECK_EQUAL(s1.GetSigOpCount(true), 3U);
|
||||||
BOOST_CHECK_EQUAL(s1.GetSigOpCount(false), 21U);
|
BOOST_CHECK_EQUAL(s1.GetSigOpCount(false), 21U);
|
||||||
|
|
||||||
CScript p2sh;
|
CScript p2sh = GetScriptForDestination(s1.GetID());
|
||||||
p2sh.SetDestination(s1.GetID());
|
|
||||||
CScript scriptSig;
|
CScript scriptSig;
|
||||||
scriptSig << OP_0 << Serialize(s1);
|
scriptSig << OP_0 << Serialize(s1);
|
||||||
BOOST_CHECK_EQUAL(p2sh.GetSigOpCount(scriptSig), 3U);
|
BOOST_CHECK_EQUAL(p2sh.GetSigOpCount(scriptSig), 3U);
|
||||||
@ -50,12 +50,11 @@ BOOST_AUTO_TEST_CASE(GetSigOpCount)
|
|||||||
k.MakeNewKey(true);
|
k.MakeNewKey(true);
|
||||||
keys.push_back(k.GetPubKey());
|
keys.push_back(k.GetPubKey());
|
||||||
}
|
}
|
||||||
CScript s2;
|
CScript s2 = GetScriptForMultisig(1, keys);
|
||||||
s2.SetMultisig(1, keys);
|
|
||||||
BOOST_CHECK_EQUAL(s2.GetSigOpCount(true), 3U);
|
BOOST_CHECK_EQUAL(s2.GetSigOpCount(true), 3U);
|
||||||
BOOST_CHECK_EQUAL(s2.GetSigOpCount(false), 20U);
|
BOOST_CHECK_EQUAL(s2.GetSigOpCount(false), 20U);
|
||||||
|
|
||||||
p2sh.SetDestination(s2.GetID());
|
p2sh = GetScriptForDestination(s2.GetID());
|
||||||
BOOST_CHECK_EQUAL(p2sh.GetSigOpCount(true), 0U);
|
BOOST_CHECK_EQUAL(p2sh.GetSigOpCount(true), 0U);
|
||||||
BOOST_CHECK_EQUAL(p2sh.GetSigOpCount(false), 0U);
|
BOOST_CHECK_EQUAL(p2sh.GetSigOpCount(false), 0U);
|
||||||
CScript scriptSig2;
|
CScript scriptSig2;
|
||||||
|
@ -248,9 +248,9 @@ SetupDummyInputs(CBasicKeyStore& keystoreRet, CCoinsView & coinsRet)
|
|||||||
|
|
||||||
dummyTransactions[1].vout.resize(2);
|
dummyTransactions[1].vout.resize(2);
|
||||||
dummyTransactions[1].vout[0].nValue = 21*CENT;
|
dummyTransactions[1].vout[0].nValue = 21*CENT;
|
||||||
dummyTransactions[1].vout[0].scriptPubKey.SetDestination(key[2].GetPubKey().GetID());
|
dummyTransactions[1].vout[0].scriptPubKey = GetScriptForDestination(key[2].GetPubKey().GetID());
|
||||||
dummyTransactions[1].vout[1].nValue = 22*CENT;
|
dummyTransactions[1].vout[1].nValue = 22*CENT;
|
||||||
dummyTransactions[1].vout[1].scriptPubKey.SetDestination(key[3].GetPubKey().GetID());
|
dummyTransactions[1].vout[1].scriptPubKey = GetScriptForDestination(key[3].GetPubKey().GetID());
|
||||||
coinsRet.SetCoins(dummyTransactions[1].GetHash(), CCoins(dummyTransactions[1], 0));
|
coinsRet.SetCoins(dummyTransactions[1].GetHash(), CCoins(dummyTransactions[1], 0));
|
||||||
|
|
||||||
return dummyTransactions;
|
return dummyTransactions;
|
||||||
@ -307,7 +307,7 @@ BOOST_AUTO_TEST_CASE(test_IsStandard)
|
|||||||
t.vout[0].nValue = 90*CENT;
|
t.vout[0].nValue = 90*CENT;
|
||||||
CKey key;
|
CKey key;
|
||||||
key.MakeNewKey(true);
|
key.MakeNewKey(true);
|
||||||
t.vout[0].scriptPubKey.SetDestination(key.GetPubKey().GetID());
|
t.vout[0].scriptPubKey = GetScriptForDestination(key.GetPubKey().GetID());
|
||||||
|
|
||||||
string reason;
|
string reason;
|
||||||
BOOST_CHECK(IsStandardTx(t, reason));
|
BOOST_CHECK(IsStandardTx(t, reason));
|
||||||
|
@ -1385,7 +1385,7 @@ bool CWallet::CreateTransaction(const vector<pair<CScript, int64_t> >& vecSend,
|
|||||||
|
|
||||||
// coin control: send change to custom address
|
// coin control: send change to custom address
|
||||||
if (coinControl && !boost::get<CNoDestination>(&coinControl->destChange))
|
if (coinControl && !boost::get<CNoDestination>(&coinControl->destChange))
|
||||||
scriptChange.SetDestination(coinControl->destChange);
|
scriptChange = GetScriptForDestination(coinControl->destChange);
|
||||||
|
|
||||||
// no coin control: send change to newly generated address
|
// no coin control: send change to newly generated address
|
||||||
else
|
else
|
||||||
@ -1403,7 +1403,7 @@ bool CWallet::CreateTransaction(const vector<pair<CScript, int64_t> >& vecSend,
|
|||||||
ret = reservekey.GetReservedKey(vchPubKey);
|
ret = reservekey.GetReservedKey(vchPubKey);
|
||||||
assert(ret); // should never fail, as we just unlocked
|
assert(ret); // should never fail, as we just unlocked
|
||||||
|
|
||||||
scriptChange.SetDestination(vchPubKey.GetID());
|
scriptChange = GetScriptForDestination(vchPubKey.GetID());
|
||||||
}
|
}
|
||||||
|
|
||||||
CTxOut newTxOut(nChange, scriptChange);
|
CTxOut newTxOut(nChange, scriptChange);
|
||||||
@ -1556,8 +1556,7 @@ string CWallet::SendMoney(const CTxDestination &address, int64_t nValue, CWallet
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Parse Bitcoin address
|
// Parse Bitcoin address
|
||||||
CScript scriptPubKey;
|
CScript scriptPubKey = GetScriptForDestination(address);
|
||||||
scriptPubKey.SetDestination(address);
|
|
||||||
|
|
||||||
// Create and send the transaction
|
// Create and send the transaction
|
||||||
CReserveKey reservekey(this);
|
CReserveKey reservekey(this);
|
||||||
|
@ -29,8 +29,7 @@ unsigned int HaveKeys(const vector<valtype>& pubkeys, const CKeyStore& keystore)
|
|||||||
|
|
||||||
isminetype IsMine(const CKeyStore &keystore, const CTxDestination& dest)
|
isminetype IsMine(const CKeyStore &keystore, const CTxDestination& dest)
|
||||||
{
|
{
|
||||||
CScript script;
|
CScript script = GetScriptForDestination(dest);
|
||||||
script.SetDestination(dest);
|
|
||||||
return IsMine(keystore, script);
|
return IsMine(keystore, script);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,9 +7,10 @@
|
|||||||
#define H_BITCOIN_WALLET_ISMINE
|
#define H_BITCOIN_WALLET_ISMINE
|
||||||
|
|
||||||
#include "key.h"
|
#include "key.h"
|
||||||
#include "script/script.h"
|
#include "script/standard.h"
|
||||||
|
|
||||||
class CKeyStore;
|
class CKeyStore;
|
||||||
|
class CScript;
|
||||||
|
|
||||||
/** IsMine() return codes */
|
/** IsMine() return codes */
|
||||||
enum isminetype
|
enum isminetype
|
||||||
|
Loading…
Reference in New Issue
Block a user