From fa9796de83b7a3ec401a4b502c246a55d79ef0c1 Mon Sep 17 00:00:00 2001 From: CryptoManiac Date: Thu, 10 Jul 2014 23:03:49 +0400 Subject: [PATCH] Relay OP_RETURN data TxOut as standard transaction type --- src/main.cpp | 24 +++++++++++++++++++----- src/script.cpp | 20 ++++++++++++++++++-- src/script.h | 4 +++- 3 files changed, 40 insertions(+), 8 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 44444a7..d8fedf4 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -300,6 +300,8 @@ bool CTransaction::IsStandard() const if (nVersion > CTransaction::CURRENT_VERSION) return false; + unsigned int nDataOut = 0; + txnouttype whichType; BOOST_FOREACH(const CTxIn& txin, vin) { // Biggest 'standard' txin is a 3-signature 3-of-3 CHECKMULTISIG @@ -314,14 +316,26 @@ bool CTransaction::IsStandard() const } } BOOST_FOREACH(const CTxOut& txout, vout) { - if (!::IsStandard(txout.scriptPubKey)) - return false; - if (txout.nValue == 0) - return false; - if (fEnforceCanonical && !txout.scriptPubKey.HasCanonicalPushes()) { + if (!::IsStandard(txout.scriptPubKey, whichType)) { return false; } + if (whichType == TX_NULL_DATA) + nDataOut++; + else { + if (txout.nValue == 0) { + return false; + } + if (fEnforceCanonical && !txout.scriptPubKey.HasCanonicalPushes()) { + return false; + } + } + } + + // only one OP_RETURN txout is permitted + if (nDataOut > 1) { + return false; } + return true; } diff --git a/src/script.cpp b/src/script.cpp index 2bf2cbf..15733a7 100644 --- a/src/script.cpp +++ b/src/script.cpp @@ -102,6 +102,7 @@ const char* GetTxnOutputType(txnouttype t) case TX_PUBKEYHASH: return "pubkeyhash"; case TX_SCRIPTHASH: return "scripthash"; case TX_MULTISIG: return "multisig"; + case TX_NULL_DATA: return "nulldata"; } return NULL; } @@ -1232,6 +1233,9 @@ bool Solver(const CScript& scriptPubKey, txnouttype& typeRet, vector 80) + break; + } else if (opcode1 != opcode2 || vch1 != vch2) { // Others must match exactly @@ -1378,6 +1388,7 @@ bool Solver(const CKeyStore& keystore, const CScript& scriptPubKey, uint256 hash switch (whichTypeRet) { case TX_NONSTANDARD: + case TX_NULL_DATA: return false; case TX_PUBKEY: keyID = CPubKey(vSolutions[0]).GetID(); @@ -1409,6 +1420,8 @@ int ScriptSigArgsExpected(txnouttype t, const std::vector vSolutions; - txnouttype whichType; if (!Solver(scriptPubKey, whichType, vSolutions)) return false; @@ -1485,6 +1497,7 @@ bool IsMine(const CKeyStore &keystore, const CScript& scriptPubKey) switch (whichType) { case TX_NONSTANDARD: + case TX_NULL_DATA: return false; case TX_PUBKEY: keyID = CPubKey(vSolutions[0]).GetID(); @@ -1583,6 +1596,8 @@ bool ExtractDestinations(const CScript& scriptPubKey, txnouttype& typeRet, vecto vector vSolutions; if (!Solver(scriptPubKey, typeRet, vSolutions)) return false; + if (typeRet == TX_NULL_DATA) + return true; if (typeRet == TX_MULTISIG) { @@ -1772,6 +1787,7 @@ static CScript CombineSignatures(CScript scriptPubKey, const CTransaction& txTo, switch (txType) { case TX_NONSTANDARD: + case TX_NULL_DATA: // Don't know anything about this, assume bigger one is correct: if (sigs1.size() >= sigs2.size()) return PushAll(sigs1); diff --git a/src/script.h b/src/script.h index 577e80c..8901981 100644 --- a/src/script.h +++ b/src/script.h @@ -36,6 +36,7 @@ enum txnouttype TX_PUBKEYHASH, TX_SCRIPTHASH, TX_MULTISIG, + TX_NULL_DATA, }; class CNoDestination { @@ -192,6 +193,7 @@ enum opcodetype // template matching params + OP_SMALLDATA = 0xf9, OP_SMALLINTEGER = 0xfa, OP_PUBKEYS = 0xfb, OP_PUBKEYHASH = 0xfd, @@ -590,7 +592,7 @@ public: bool EvalScript(std::vector >& stack, const CScript& script, const CTransaction& txTo, unsigned int nIn, int nHashType); bool Solver(const CScript& scriptPubKey, txnouttype& typeRet, std::vector >& vSolutionsRet); int ScriptSigArgsExpected(txnouttype t, const std::vector >& vSolutions); -bool IsStandard(const CScript& scriptPubKey); +bool IsStandard(const CScript& scriptPubKey, txnouttype& whichType); bool IsMine(const CKeyStore& keystore, const CScript& scriptPubKey); bool IsMine(const CKeyStore& keystore, const CTxDestination &dest); void ExtractAffectedKeys(const CKeyStore &keystore, const CScript& scriptPubKey, std::vector &vKeys); -- 1.7.1