script: move CScriptID to standard.h and add a ctor for creating them from CScripts
This allows for a reversal of the current behavior. This: CScript foo; CScriptID bar(foo.GetID()); Becomes: CScript foo; CScriptID bar(foo); This way, CScript is no longer dependent on CScriptID or Hash();
This commit is contained in:
parent
e8f6d54f1f
commit
066e2a1403
@ -5,6 +5,7 @@
|
|||||||
#include "crypter.h"
|
#include "crypter.h"
|
||||||
|
|
||||||
#include "script/script.h"
|
#include "script/script.h"
|
||||||
|
#include "script/standard.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
@ -30,14 +30,6 @@ public:
|
|||||||
CKeyID(const uint160& in) : uint160(in) {}
|
CKeyID(const uint160& in) : uint160(in) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
/** A reference to a CScript: the Hash160 of its serialization (see script.h) */
|
|
||||||
class CScriptID : public uint160
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
CScriptID() : uint160(0) {}
|
|
||||||
CScriptID(const uint160& in) : uint160(in) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
/** An encapsulated public key. */
|
/** An encapsulated public key. */
|
||||||
class CPubKey
|
class CPubKey
|
||||||
{
|
{
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
#include "crypter.h"
|
#include "crypter.h"
|
||||||
#include "key.h"
|
#include "key.h"
|
||||||
#include "script/script.h"
|
#include "script/script.h"
|
||||||
|
#include "script/standard.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
#include <boost/foreach.hpp>
|
#include <boost/foreach.hpp>
|
||||||
@ -38,7 +39,7 @@ bool CBasicKeyStore::AddCScript(const CScript& redeemScript)
|
|||||||
return error("CBasicKeyStore::AddCScript() : redeemScripts > %i bytes are invalid", MAX_SCRIPT_ELEMENT_SIZE);
|
return error("CBasicKeyStore::AddCScript() : redeemScripts > %i bytes are invalid", MAX_SCRIPT_ELEMENT_SIZE);
|
||||||
|
|
||||||
LOCK(cs_KeyStore);
|
LOCK(cs_KeyStore);
|
||||||
mapScripts[redeemScript.GetID()] = redeemScript;
|
mapScripts[CScriptID(redeemScript)] = redeemScript;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
#include <boost/variant.hpp>
|
#include <boost/variant.hpp>
|
||||||
|
|
||||||
class CScript;
|
class CScript;
|
||||||
|
class CScriptID;
|
||||||
|
|
||||||
/** A virtual base class for key stores */
|
/** A virtual base class for key stores */
|
||||||
class CKeyStore
|
class CKeyStore
|
||||||
|
@ -292,7 +292,7 @@ Value createmultisig(const Array& params, bool fHelp)
|
|||||||
|
|
||||||
// Construct using pay-to-script-hash:
|
// Construct using pay-to-script-hash:
|
||||||
CScript inner = _createmultisig_redeemScript(params);
|
CScript inner = _createmultisig_redeemScript(params);
|
||||||
CScriptID innerID = inner.GetID();
|
CScriptID innerID(inner);
|
||||||
CBitcoinAddress address(innerID);
|
CBitcoinAddress address(innerID);
|
||||||
|
|
||||||
Object result;
|
Object result;
|
||||||
|
@ -480,7 +480,7 @@ Value decodescript(const Array& params, bool fHelp)
|
|||||||
}
|
}
|
||||||
ScriptPubKeyToJSON(script, r, false);
|
ScriptPubKeyToJSON(script, r, false);
|
||||||
|
|
||||||
r.push_back(Pair("p2sh", CBitcoinAddress(script.GetID()).ToString()));
|
r.push_back(Pair("p2sh", CBitcoinAddress(CScriptID(script)).ToString()));
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -918,7 +918,7 @@ Value addmultisigaddress(const Array& params, bool fHelp)
|
|||||||
|
|
||||||
// Construct using pay-to-script-hash:
|
// Construct using pay-to-script-hash:
|
||||||
CScript inner = _createmultisig_redeemScript(params);
|
CScript inner = _createmultisig_redeemScript(params);
|
||||||
CScriptID innerID = inner.GetID();
|
CScriptID innerID(inner);
|
||||||
pwalletMain->AddCScript(inner);
|
pwalletMain->AddCScript(inner);
|
||||||
|
|
||||||
pwalletMain->SetAddressBook(innerID, strAccount, "send");
|
pwalletMain->SetAddressBook(innerID, strAccount, "send");
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
#include "compressor.h"
|
#include "compressor.h"
|
||||||
|
#include "script/standard.h"
|
||||||
|
|
||||||
bool CScriptCompressor::IsToKeyID(CKeyID &hash) const
|
bool CScriptCompressor::IsToKeyID(CKeyID &hash) const
|
||||||
{
|
{
|
||||||
|
@ -8,6 +8,8 @@
|
|||||||
|
|
||||||
#include "script/script.h"
|
#include "script/script.h"
|
||||||
|
|
||||||
|
class CScriptID;
|
||||||
|
|
||||||
/** Compact serializer for scripts.
|
/** Compact serializer for scripts.
|
||||||
*
|
*
|
||||||
* It detects common cases and encodes them much more efficiently.
|
* It detects common cases and encodes them much more efficiently.
|
||||||
|
@ -610,12 +610,6 @@ public:
|
|||||||
}
|
}
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
CScriptID GetID() const
|
|
||||||
{
|
|
||||||
return CScriptID(Hash160(*this));
|
|
||||||
}
|
|
||||||
|
|
||||||
void clear()
|
void clear()
|
||||||
{
|
{
|
||||||
// The default std::vector::clear() does not release memory.
|
// The default std::vector::clear() does not release memory.
|
||||||
|
@ -14,6 +14,8 @@ using namespace std;
|
|||||||
|
|
||||||
typedef vector<unsigned char> valtype;
|
typedef vector<unsigned char> valtype;
|
||||||
|
|
||||||
|
CScriptID::CScriptID(const CScript& in) : uint160(in.size() ? Hash160(in.begin(), in.end()) : 0) {}
|
||||||
|
|
||||||
const char* GetTxnOutputType(txnouttype t)
|
const char* GetTxnOutputType(txnouttype t)
|
||||||
{
|
{
|
||||||
switch (t)
|
switch (t)
|
||||||
|
@ -13,6 +13,15 @@
|
|||||||
|
|
||||||
class CScript;
|
class CScript;
|
||||||
|
|
||||||
|
/** A reference to a CScript: the Hash160 of its serialization (see script.h) */
|
||||||
|
class CScriptID : public uint160
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CScriptID() : uint160(0) {}
|
||||||
|
CScriptID(const CScript& in);
|
||||||
|
CScriptID(const uint160& in) : uint160(in) {}
|
||||||
|
};
|
||||||
|
|
||||||
static const unsigned int MAX_OP_RETURN_RELAY = 40; // bytes
|
static const unsigned int MAX_OP_RETURN_RELAY = 40; // bytes
|
||||||
|
|
||||||
// Mandatory script verification flags that all new blocks must comply with for
|
// Mandatory script verification flags that all new blocks must comply with for
|
||||||
|
@ -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 = GetScriptForDestination(script.GetID());
|
tx.vout[0].scriptPubKey = GetScriptForDestination(CScriptID(script));
|
||||||
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;
|
||||||
|
@ -75,7 +75,7 @@ BOOST_AUTO_TEST_CASE(sign)
|
|||||||
for (int i = 0; i < 4; i++)
|
for (int i = 0; i < 4; i++)
|
||||||
{
|
{
|
||||||
keystore.AddCScript(standardScripts[i]);
|
keystore.AddCScript(standardScripts[i]);
|
||||||
evalScripts[i] = GetScriptForDestination(standardScripts[i].GetID());
|
evalScripts[i] = GetScriptForDestination(CScriptID(standardScripts[i]));
|
||||||
}
|
}
|
||||||
|
|
||||||
CMutableTransaction txFrom; // Funding transaction:
|
CMutableTransaction txFrom; // Funding transaction:
|
||||||
@ -129,7 +129,7 @@ BOOST_AUTO_TEST_CASE(norecurse)
|
|||||||
CScript invalidAsScript;
|
CScript invalidAsScript;
|
||||||
invalidAsScript << OP_INVALIDOPCODE << OP_INVALIDOPCODE;
|
invalidAsScript << OP_INVALIDOPCODE << OP_INVALIDOPCODE;
|
||||||
|
|
||||||
CScript p2sh = GetScriptForDestination(invalidAsScript.GetID());
|
CScript p2sh = GetScriptForDestination(CScriptID(invalidAsScript));
|
||||||
|
|
||||||
CScript scriptSig;
|
CScript scriptSig;
|
||||||
scriptSig << Serialize(invalidAsScript);
|
scriptSig << Serialize(invalidAsScript);
|
||||||
@ -139,7 +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 = GetScriptForDestination(p2sh.GetID());
|
CScript p2sh2 = GetScriptForDestination(CScriptID(p2sh));
|
||||||
CScript scriptSig2;
|
CScript scriptSig2;
|
||||||
scriptSig2 << Serialize(invalidAsScript) << Serialize(p2sh);
|
scriptSig2 << Serialize(invalidAsScript) << Serialize(p2sh);
|
||||||
|
|
||||||
@ -169,7 +169,7 @@ BOOST_AUTO_TEST_CASE(set)
|
|||||||
CScript outer[4];
|
CScript outer[4];
|
||||||
for (int i = 0; i < 4; i++)
|
for (int i = 0; i < 4; i++)
|
||||||
{
|
{
|
||||||
outer[i] = GetScriptForDestination(inner[i].GetID());
|
outer[i] = GetScriptForDestination(CScriptID(inner[i]));
|
||||||
keystore.AddCScript(inner[i]);
|
keystore.AddCScript(inner[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -242,7 +242,7 @@ BOOST_AUTO_TEST_CASE(switchover)
|
|||||||
CScript scriptSig;
|
CScript scriptSig;
|
||||||
scriptSig << Serialize(notValid);
|
scriptSig << Serialize(notValid);
|
||||||
|
|
||||||
CScript fund = GetScriptForDestination(notValid.GetID());
|
CScript fund = GetScriptForDestination(CScriptID(notValid));
|
||||||
|
|
||||||
|
|
||||||
// Validation should succeed under old rules (hash is correct):
|
// Validation should succeed under old rules (hash is correct):
|
||||||
@ -275,7 +275,7 @@ BOOST_AUTO_TEST_CASE(AreInputsStandard)
|
|||||||
keystore.AddCScript(pay1);
|
keystore.AddCScript(pay1);
|
||||||
CScript pay1of3 = GetScriptForMultisig(1, keys);
|
CScript pay1of3 = GetScriptForMultisig(1, keys);
|
||||||
|
|
||||||
txFrom.vout[0].scriptPubKey = GetScriptForDestination(pay1.GetID()); // P2SH (OP_CHECKSIG)
|
txFrom.vout[0].scriptPubKey = GetScriptForDestination(CScriptID(pay1)); // 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;
|
||||||
@ -290,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 = GetScriptForDestination(oneAndTwo.GetID());
|
txFrom.vout[3].scriptPubKey = GetScriptForDestination(CScriptID(oneAndTwo));
|
||||||
txFrom.vout[3].nValue = 4000;
|
txFrom.vout[3].nValue = 4000;
|
||||||
|
|
||||||
// vout[4] is max sigops:
|
// vout[4] is max sigops:
|
||||||
@ -299,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 = GetScriptForDestination(fifteenSigops.GetID());
|
txFrom.vout[4].scriptPubKey = GetScriptForDestination(CScriptID(fifteenSigops));
|
||||||
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 = GetScriptForDestination(fifteenSigops.GetID());
|
txFrom.vout[5].scriptPubKey = GetScriptForDestination(CScriptID(fifteenSigops));
|
||||||
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 = GetScriptForDestination(twentySigops.GetID());
|
txFrom.vout[6].scriptPubKey = GetScriptForDestination(CScriptID(twentySigops));
|
||||||
txFrom.vout[6].nValue = 6000;
|
txFrom.vout[6].nValue = 6000;
|
||||||
|
|
||||||
coins.ModifyCoins(txFrom.GetHash())->FromTx(txFrom, 0);
|
coins.ModifyCoins(txFrom.GetHash())->FromTx(txFrom, 0);
|
||||||
|
@ -162,7 +162,7 @@ public:
|
|||||||
TestBuilder(const CScript& redeemScript, const std::string& comment_, int flags_, bool P2SH = false) : scriptPubKey(redeemScript), havePush(false), comment(comment_), flags(flags_)
|
TestBuilder(const CScript& redeemScript, const std::string& comment_, int flags_, bool P2SH = false) : scriptPubKey(redeemScript), havePush(false), comment(comment_), flags(flags_)
|
||||||
{
|
{
|
||||||
if (P2SH) {
|
if (P2SH) {
|
||||||
creditTx = BuildCreditingTransaction(CScript() << OP_HASH160 << redeemScript.GetID() << OP_EQUAL);
|
creditTx = BuildCreditingTransaction(CScript() << OP_HASH160 << CScriptID(redeemScript) << OP_EQUAL);
|
||||||
} else {
|
} else {
|
||||||
creditTx = BuildCreditingTransaction(redeemScript);
|
creditTx = BuildCreditingTransaction(redeemScript);
|
||||||
}
|
}
|
||||||
@ -697,7 +697,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 = GetScriptForDestination(pkSingle.GetID());
|
scriptPubKey = GetScriptForDestination(CScriptID(pkSingle));
|
||||||
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);
|
||||||
|
@ -38,7 +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 = GetScriptForDestination(s1.GetID());
|
CScript p2sh = GetScriptForDestination(CScriptID(s1));
|
||||||
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);
|
||||||
@ -54,7 +54,7 @@ BOOST_AUTO_TEST_CASE(GetSigOpCount)
|
|||||||
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 = GetScriptForDestination(s2.GetID());
|
p2sh = GetScriptForDestination(CScriptID(s2));
|
||||||
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;
|
||||||
|
@ -158,7 +158,7 @@ bool CWallet::LoadCScript(const CScript& redeemScript)
|
|||||||
* these. Do not add them to the wallet and warn. */
|
* these. Do not add them to the wallet and warn. */
|
||||||
if (redeemScript.size() > MAX_SCRIPT_ELEMENT_SIZE)
|
if (redeemScript.size() > MAX_SCRIPT_ELEMENT_SIZE)
|
||||||
{
|
{
|
||||||
std::string strAddr = CBitcoinAddress(redeemScript.GetID()).ToString();
|
std::string strAddr = CBitcoinAddress(CScriptID(redeemScript)).ToString();
|
||||||
LogPrintf("%s: Warning: This wallet contains a redeemScript of size %i which exceeds maximum size %i thus can never be redeemed. Do not use address %s.\n",
|
LogPrintf("%s: Warning: This wallet contains a redeemScript of size %i which exceeds maximum size %i thus can never be redeemed. Do not use address %s.\n",
|
||||||
__func__, redeemScript.size(), MAX_SCRIPT_ELEMENT_SIZE, strAddr);
|
__func__, redeemScript.size(), MAX_SCRIPT_ELEMENT_SIZE, strAddr);
|
||||||
return true;
|
return true;
|
||||||
|
Loading…
Reference in New Issue
Block a user