|
|
@ -79,6 +79,7 @@ const char* GetTxnOutputType(txnouttype t) |
|
|
|
case TX_PUBKEYHASH: return "pubkeyhash"; |
|
|
|
case TX_PUBKEYHASH: return "pubkeyhash"; |
|
|
|
case TX_SCRIPTHASH: return "scripthash"; |
|
|
|
case TX_SCRIPTHASH: return "scripthash"; |
|
|
|
case TX_MULTISIG: return "multisig"; |
|
|
|
case TX_MULTISIG: return "multisig"; |
|
|
|
|
|
|
|
case TX_NULL_DATA: return "nulldata"; |
|
|
|
} |
|
|
|
} |
|
|
|
return NULL; |
|
|
|
return NULL; |
|
|
|
} |
|
|
|
} |
|
|
@ -220,6 +221,7 @@ const char* GetOpName(opcodetype opcode) |
|
|
|
// template matching params
|
|
|
|
// template matching params
|
|
|
|
case OP_PUBKEYHASH : return "OP_PUBKEYHASH"; |
|
|
|
case OP_PUBKEYHASH : return "OP_PUBKEYHASH"; |
|
|
|
case OP_PUBKEY : return "OP_PUBKEY"; |
|
|
|
case OP_PUBKEY : return "OP_PUBKEY"; |
|
|
|
|
|
|
|
case OP_SMALLDATA : return "OP_SMALLDATA"; |
|
|
|
|
|
|
|
|
|
|
|
case OP_INVALIDOPCODE : return "OP_INVALIDOPCODE"; |
|
|
|
case OP_INVALIDOPCODE : return "OP_INVALIDOPCODE"; |
|
|
|
default: |
|
|
|
default: |
|
|
@ -1204,6 +1206,9 @@ bool Solver(const CScript& scriptPubKey, txnouttype& typeRet, vector<vector<unsi |
|
|
|
|
|
|
|
|
|
|
|
// Sender provides N pubkeys, receivers provides M signatures
|
|
|
|
// Sender provides N pubkeys, receivers provides M signatures
|
|
|
|
mTemplates.insert(make_pair(TX_MULTISIG, CScript() << OP_SMALLINTEGER << OP_PUBKEYS << OP_SMALLINTEGER << OP_CHECKMULTISIG)); |
|
|
|
mTemplates.insert(make_pair(TX_MULTISIG, CScript() << OP_SMALLINTEGER << OP_PUBKEYS << OP_SMALLINTEGER << OP_CHECKMULTISIG)); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Empty, provably prunable, data-carrying output
|
|
|
|
|
|
|
|
mTemplates.insert(make_pair(TX_NULL_DATA, CScript() << OP_RETURN << OP_SMALLDATA)); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Shortcut for pay-to-script-hash, which are more constrained than the other types:
|
|
|
|
// Shortcut for pay-to-script-hash, which are more constrained than the other types:
|
|
|
@ -1288,6 +1293,12 @@ bool Solver(const CScript& scriptPubKey, txnouttype& typeRet, vector<vector<unsi |
|
|
|
else |
|
|
|
else |
|
|
|
break; |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
else if (opcode2 == OP_SMALLDATA) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
// small pushdata, <= 80 bytes
|
|
|
|
|
|
|
|
if (vch1.size() > 80) |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
} |
|
|
|
else if (opcode1 != opcode2 || vch1 != vch2) |
|
|
|
else if (opcode1 != opcode2 || vch1 != vch2) |
|
|
|
{ |
|
|
|
{ |
|
|
|
// Others must match exactly
|
|
|
|
// Others must match exactly
|
|
|
@ -1350,6 +1361,7 @@ bool Solver(const CKeyStore& keystore, const CScript& scriptPubKey, uint256 hash |
|
|
|
switch (whichTypeRet) |
|
|
|
switch (whichTypeRet) |
|
|
|
{ |
|
|
|
{ |
|
|
|
case TX_NONSTANDARD: |
|
|
|
case TX_NONSTANDARD: |
|
|
|
|
|
|
|
case TX_NULL_DATA: |
|
|
|
return false; |
|
|
|
return false; |
|
|
|
case TX_PUBKEY: |
|
|
|
case TX_PUBKEY: |
|
|
|
keyID = CPubKey(vSolutions[0]).GetID(); |
|
|
|
keyID = CPubKey(vSolutions[0]).GetID(); |
|
|
@ -1381,6 +1393,8 @@ int ScriptSigArgsExpected(txnouttype t, const std::vector<std::vector<unsigned c |
|
|
|
{ |
|
|
|
{ |
|
|
|
case TX_NONSTANDARD: |
|
|
|
case TX_NONSTANDARD: |
|
|
|
return -1; |
|
|
|
return -1; |
|
|
|
|
|
|
|
case TX_NULL_DATA: |
|
|
|
|
|
|
|
return 1; |
|
|
|
case TX_PUBKEY: |
|
|
|
case TX_PUBKEY: |
|
|
|
return 1; |
|
|
|
return 1; |
|
|
|
case TX_PUBKEYHASH: |
|
|
|
case TX_PUBKEYHASH: |
|
|
@ -1395,10 +1409,9 @@ int ScriptSigArgsExpected(txnouttype t, const std::vector<std::vector<unsigned c |
|
|
|
return -1; |
|
|
|
return -1; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
bool IsStandard(const CScript& scriptPubKey) |
|
|
|
bool IsStandard(const CScript& scriptPubKey, txnouttype& whichType) |
|
|
|
{ |
|
|
|
{ |
|
|
|
vector<valtype> vSolutions; |
|
|
|
vector<valtype> vSolutions; |
|
|
|
txnouttype whichType; |
|
|
|
|
|
|
|
if (!Solver(scriptPubKey, whichType, vSolutions)) |
|
|
|
if (!Solver(scriptPubKey, whichType, vSolutions)) |
|
|
|
return false; |
|
|
|
return false; |
|
|
|
|
|
|
|
|
|
|
@ -1457,6 +1470,7 @@ bool IsMine(const CKeyStore &keystore, const CScript& scriptPubKey) |
|
|
|
switch (whichType) |
|
|
|
switch (whichType) |
|
|
|
{ |
|
|
|
{ |
|
|
|
case TX_NONSTANDARD: |
|
|
|
case TX_NONSTANDARD: |
|
|
|
|
|
|
|
case TX_NULL_DATA: |
|
|
|
return false; |
|
|
|
return false; |
|
|
|
case TX_PUBKEY: |
|
|
|
case TX_PUBKEY: |
|
|
|
keyID = CPubKey(vSolutions[0]).GetID(); |
|
|
|
keyID = CPubKey(vSolutions[0]).GetID(); |
|
|
@ -1518,6 +1532,8 @@ bool ExtractDestinations(const CScript& scriptPubKey, txnouttype& typeRet, vecto |
|
|
|
vector<valtype> vSolutions; |
|
|
|
vector<valtype> vSolutions; |
|
|
|
if (!Solver(scriptPubKey, typeRet, vSolutions)) |
|
|
|
if (!Solver(scriptPubKey, typeRet, vSolutions)) |
|
|
|
return false; |
|
|
|
return false; |
|
|
|
|
|
|
|
if (typeRet == TX_NULL_DATA) |
|
|
|
|
|
|
|
return true; |
|
|
|
|
|
|
|
|
|
|
|
if (typeRet == TX_MULTISIG) |
|
|
|
if (typeRet == TX_MULTISIG) |
|
|
|
{ |
|
|
|
{ |
|
|
@ -1733,6 +1749,7 @@ static CScript CombineSignatures(CScript scriptPubKey, const CTransaction& txTo, |
|
|
|
switch (txType) |
|
|
|
switch (txType) |
|
|
|
{ |
|
|
|
{ |
|
|
|
case TX_NONSTANDARD: |
|
|
|
case TX_NONSTANDARD: |
|
|
|
|
|
|
|
case TX_NULL_DATA: |
|
|
|
// Don't know anything about this, assume bigger one is correct:
|
|
|
|
// Don't know anything about this, assume bigger one is correct:
|
|
|
|
if (sigs1.size() >= sigs2.size()) |
|
|
|
if (sigs1.size() >= sigs2.size()) |
|
|
|
return PushAll(sigs1); |
|
|
|
return PushAll(sigs1); |
|
|
|