aboutsummaryrefslogtreecommitdiff
path: root/src/script
diff options
context:
space:
mode:
Diffstat (limited to 'src/script')
-rw-r--r--src/script/bitcoinconsensus.cpp12
-rw-r--r--src/script/bitcoinconsensus.h4
-rw-r--r--src/script/interpreter.cpp29
-rw-r--r--src/script/interpreter.h29
-rw-r--r--src/script/ismine.cpp13
-rw-r--r--src/script/ismine.h4
-rw-r--r--src/script/script.cpp8
-rw-r--r--src/script/script.h8
-rw-r--r--src/script/script_error.cpp4
-rw-r--r--src/script/sigcache.cpp16
-rw-r--r--src/script/sigcache.h4
-rw-r--r--src/script/sign.cpp35
-rw-r--r--src/script/sign.h10
-rw-r--r--src/script/standard.cpp23
-rw-r--r--src/script/standard.h28
15 files changed, 134 insertions, 93 deletions
diff --git a/src/script/bitcoinconsensus.cpp b/src/script/bitcoinconsensus.cpp
index 03128917f..7d3587e2c 100644
--- a/src/script/bitcoinconsensus.cpp
+++ b/src/script/bitcoinconsensus.cpp
@@ -1,14 +1,14 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto
-// Copyright (c) 2009-2016 The Bitcoin Core developers
+// Copyright (c) 2009-2017 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
-#include "bitcoinconsensus.h"
+#include <script/bitcoinconsensus.h>
-#include "primitives/transaction.h"
-#include "pubkey.h"
-#include "script/interpreter.h"
-#include "version.h"
+#include <primitives/transaction.h>
+#include <pubkey.h>
+#include <script/interpreter.h>
+#include <version.h>
namespace {
diff --git a/src/script/bitcoinconsensus.h b/src/script/bitcoinconsensus.h
index 33bf80e5a..bb94c1752 100644
--- a/src/script/bitcoinconsensus.h
+++ b/src/script/bitcoinconsensus.h
@@ -1,5 +1,5 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto
-// Copyright (c) 2009-2016 The Bitcoin Core developers
+// Copyright (c) 2009-2017 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
@@ -9,7 +9,7 @@
#include <stdint.h>
#if defined(BUILD_BITCOIN_INTERNAL) && defined(HAVE_CONFIG_H)
-#include "config/bitcoin-config.h"
+#include <config/bitcoin-config.h>
#if defined(_WIN32)
#if defined(DLL_EXPORT)
#if defined(HAVE_FUNC_ATTRIBUTE_DLLEXPORT)
diff --git a/src/script/interpreter.cpp b/src/script/interpreter.cpp
index 2f7b8e3a0..2cdff7ee5 100644
--- a/src/script/interpreter.cpp
+++ b/src/script/interpreter.cpp
@@ -1,17 +1,16 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto
-// Copyright (c) 2009-2016 The Bitcoin Core developers
+// Copyright (c) 2009-2017 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
-#include "interpreter.h"
+#include <script/interpreter.h>
-#include "primitives/transaction.h"
-#include "crypto/ripemd160.h"
-#include "crypto/sha1.h"
-#include "crypto/sha256.h"
-#include "pubkey.h"
-#include "script/script.h"
-#include "uint256.h"
+#include <crypto/ripemd160.h>
+#include <crypto/sha1.h>
+#include <crypto/sha256.h>
+#include <pubkey.h>
+#include <script/script.h>
+#include <uint256.h>
typedef std::vector<unsigned char> valtype;
@@ -174,7 +173,13 @@ bool static IsLowDERSignature(const valtype &vchSig, ScriptError* serror) {
if (!IsValidSignatureEncoding(vchSig)) {
return set_error(serror, SCRIPT_ERR_SIG_DER);
}
+ // https://bitcoin.stackexchange.com/a/12556:
+ // Also note that inside transaction signatures, an extra hashtype byte
+ // follows the actual signature data.
std::vector<unsigned char> vchSigCopy(vchSig.begin(), vchSig.begin() + vchSig.size() - 1);
+ // If the S value is above the order of the curve divided by two, its
+ // complement modulo the order could have been used instead, which is
+ // one byte shorter when encoded correctly.
if (!CPubKey::CheckLowS(vchSigCopy)) {
return set_error(serror, SCRIPT_ERR_SIG_HIGH_S);
}
@@ -349,9 +354,6 @@ bool EvalScript(std::vector<std::vector<unsigned char> >& stack, const CScript&
{
if (!(flags & SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY)) {
// not enabled; treat as a NOP2
- if (flags & SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS) {
- return set_error(serror, SCRIPT_ERR_DISCOURAGE_UPGRADABLE_NOPS);
- }
break;
}
@@ -391,9 +393,6 @@ bool EvalScript(std::vector<std::vector<unsigned char> >& stack, const CScript&
{
if (!(flags & SCRIPT_VERIFY_CHECKSEQUENCEVERIFY)) {
// not enabled; treat as a NOP3
- if (flags & SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS) {
- return set_error(serror, SCRIPT_ERR_DISCOURAGE_UPGRADABLE_NOPS);
- }
break;
}
diff --git a/src/script/interpreter.h b/src/script/interpreter.h
index 1cb9cc789..e12329be7 100644
--- a/src/script/interpreter.h
+++ b/src/script/interpreter.h
@@ -1,13 +1,13 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto
-// Copyright (c) 2009-2016 The Bitcoin Core developers
+// Copyright (c) 2009-2017 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_SCRIPT_INTERPRETER_H
#define BITCOIN_SCRIPT_INTERPRETER_H
-#include "script_error.h"
-#include "primitives/transaction.h"
+#include <script/script_error.h>
+#include <primitives/transaction.h>
#include <vector>
#include <stdint.h>
@@ -27,37 +27,40 @@ enum
SIGHASH_ANYONECANPAY = 0x80,
};
-/** Script verification flags */
+/** Script verification flags.
+ *
+ * All flags are intended to be soft forks: the set of acceptable scripts under
+ * flags (A | B) is a subset of the acceptable scripts under flag (A).
+ */
enum
{
SCRIPT_VERIFY_NONE = 0,
- // Evaluate P2SH subscripts (softfork safe, BIP16).
+ // Evaluate P2SH subscripts (BIP16).
SCRIPT_VERIFY_P2SH = (1U << 0),
// Passing a non-strict-DER signature or one with undefined hashtype to a checksig operation causes script failure.
// Evaluating a pubkey that is not (0x04 + 64 bytes) or (0x02 or 0x03 + 32 bytes) by checksig causes script failure.
- // (softfork safe, but not used or intended as a consensus rule).
+ // (not used or intended as a consensus rule).
SCRIPT_VERIFY_STRICTENC = (1U << 1),
- // Passing a non-strict-DER signature to a checksig operation causes script failure (softfork safe, BIP62 rule 1)
+ // Passing a non-strict-DER signature to a checksig operation causes script failure (BIP62 rule 1)
SCRIPT_VERIFY_DERSIG = (1U << 2),
// Passing a non-strict-DER signature or one with S > order/2 to a checksig operation causes script failure
- // (softfork safe, BIP62 rule 5).
+ // (BIP62 rule 5).
SCRIPT_VERIFY_LOW_S = (1U << 3),
- // verify dummy stack item consumed by CHECKMULTISIG is of zero-length (softfork safe, BIP62 rule 7).
+ // verify dummy stack item consumed by CHECKMULTISIG is of zero-length (BIP62 rule 7).
SCRIPT_VERIFY_NULLDUMMY = (1U << 4),
- // Using a non-push operator in the scriptSig causes script failure (softfork safe, BIP62 rule 2).
+ // Using a non-push operator in the scriptSig causes script failure (BIP62 rule 2).
SCRIPT_VERIFY_SIGPUSHONLY = (1U << 5),
// Require minimal encodings for all push operations (OP_0... OP_16, OP_1NEGATE where possible, direct
// pushes up to 75 bytes, OP_PUSHDATA up to 255 bytes, OP_PUSHDATA2 for anything larger). Evaluating
// any other push causes the script to fail (BIP62 rule 3).
// In addition, whenever a stack element is interpreted as a number, it must be of minimal length (BIP62 rule 4).
- // (softfork safe)
SCRIPT_VERIFY_MINIMALDATA = (1U << 6),
// Discourage use of NOPs reserved for upgrades (NOP1-10)
@@ -68,12 +71,14 @@ enum
// discouraged NOPs fails the script. This verification flag will never be
// a mandatory flag applied to scripts in a block. NOPs that are not
// executed, e.g. within an unexecuted IF ENDIF block, are *not* rejected.
+ // NOPs that have associated forks to give them new meaning (CLTV, CSV)
+ // are not subject to this rule.
SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS = (1U << 7),
// Require that only a single stack element remains after evaluation. This changes the success criterion from
// "At least one stack element must remain, and when interpreted as a boolean, it must be true" to
// "Exactly one stack element must remain, and when interpreted as a boolean, it must be true".
- // (softfork safe, BIP62 rule 6)
+ // (BIP62 rule 6)
// Note: CLEANSTACK should never be used without P2SH or WITNESS.
SCRIPT_VERIFY_CLEANSTACK = (1U << 8),
diff --git a/src/script/ismine.cpp b/src/script/ismine.cpp
index 6b68f0679..d0dd27255 100644
--- a/src/script/ismine.cpp
+++ b/src/script/ismine.cpp
@@ -1,15 +1,14 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto
-// Copyright (c) 2009-2016 The Bitcoin Core developers
+// Copyright (c) 2009-2017 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
-#include "ismine.h"
+#include <script/ismine.h>
-#include "key.h"
-#include "keystore.h"
-#include "script/script.h"
-#include "script/standard.h"
-#include "script/sign.h"
+#include <key.h>
+#include <keystore.h>
+#include <script/script.h>
+#include <script/sign.h>
typedef std::vector<unsigned char> valtype;
diff --git a/src/script/ismine.h b/src/script/ismine.h
index 1aa5937b3..b54879cc1 100644
--- a/src/script/ismine.h
+++ b/src/script/ismine.h
@@ -1,12 +1,12 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto
-// Copyright (c) 2009-2016 The Bitcoin Core developers
+// Copyright (c) 2009-2017 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_SCRIPT_ISMINE_H
#define BITCOIN_SCRIPT_ISMINE_H
-#include "script/standard.h"
+#include <script/standard.h>
#include <stdint.h>
diff --git a/src/script/script.cpp b/src/script/script.cpp
index a10b619f7..65e5405eb 100644
--- a/src/script/script.cpp
+++ b/src/script/script.cpp
@@ -1,12 +1,12 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto
-// Copyright (c) 2009-2016 The Bitcoin Core developers
+// Copyright (c) 2009-2017 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
-#include "script.h"
+#include <script/script.h>
-#include "tinyformat.h"
-#include "utilstrencodings.h"
+#include <tinyformat.h>
+#include <utilstrencodings.h>
const char* GetOpName(opcodetype opcode)
{
diff --git a/src/script/script.h b/src/script/script.h
index 2a9206054..bedf5f9be 100644
--- a/src/script/script.h
+++ b/src/script/script.h
@@ -1,14 +1,14 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto
-// Copyright (c) 2009-2016 The Bitcoin Core developers
+// Copyright (c) 2009-2017 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_SCRIPT_SCRIPT_H
#define BITCOIN_SCRIPT_SCRIPT_H
-#include "crypto/common.h"
-#include "prevector.h"
-#include "serialize.h"
+#include <crypto/common.h>
+#include <prevector.h>
+#include <serialize.h>
#include <assert.h>
#include <climits>
diff --git a/src/script/script_error.cpp b/src/script/script_error.cpp
index 6c590f53e..dbceb1f74 100644
--- a/src/script/script_error.cpp
+++ b/src/script/script_error.cpp
@@ -1,9 +1,9 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto
-// Copyright (c) 2009-2016 The Bitcoin Core developers
+// Copyright (c) 2009-2017 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
-#include "script_error.h"
+#include <script/script_error.h>
const char* ScriptErrorString(const ScriptError serror)
{
diff --git a/src/script/sigcache.cpp b/src/script/sigcache.cpp
index 4cc7afa2f..9638b12f9 100644
--- a/src/script/sigcache.cpp
+++ b/src/script/sigcache.cpp
@@ -1,17 +1,17 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto
-// Copyright (c) 2009-2016 The Bitcoin Core developers
+// Copyright (c) 2009-2017 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
-#include "sigcache.h"
+#include <script/sigcache.h>
-#include "memusage.h"
-#include "pubkey.h"
-#include "random.h"
-#include "uint256.h"
-#include "util.h"
+#include <memusage.h>
+#include <pubkey.h>
+#include <random.h>
+#include <uint256.h>
+#include <util.h>
-#include "cuckoocache.h"
+#include <cuckoocache.h>
#include <boost/thread.hpp>
namespace {
diff --git a/src/script/sigcache.h b/src/script/sigcache.h
index 5832b264b..1309d57cc 100644
--- a/src/script/sigcache.h
+++ b/src/script/sigcache.h
@@ -1,12 +1,12 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto
-// Copyright (c) 2009-2016 The Bitcoin Core developers
+// Copyright (c) 2009-2017 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_SCRIPT_SIGCACHE_H
#define BITCOIN_SCRIPT_SIGCACHE_H
-#include "script/interpreter.h"
+#include <script/interpreter.h>
#include <vector>
diff --git a/src/script/sign.cpp b/src/script/sign.cpp
index ac58b690a..838e502a0 100644
--- a/src/script/sign.cpp
+++ b/src/script/sign.cpp
@@ -1,16 +1,16 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto
-// Copyright (c) 2009-2016 The Bitcoin Core developers
+// Copyright (c) 2009-2017 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
-#include "script/sign.h"
+#include <script/sign.h>
-#include "key.h"
-#include "keystore.h"
-#include "policy/policy.h"
-#include "primitives/transaction.h"
-#include "script/standard.h"
-#include "uint256.h"
+#include <key.h>
+#include <keystore.h>
+#include <policy/policy.h>
+#include <primitives/transaction.h>
+#include <script/standard.h>
+#include <uint256.h>
typedef std::vector<unsigned char> valtype;
@@ -422,3 +422,22 @@ bool DummySignatureCreator::CreateSig(std::vector<unsigned char>& vchSig, const
vchSig[6 + 33 + 32] = SIGHASH_ALL;
return true;
}
+
+bool IsSolvable(const CKeyStore& store, const CScript& script)
+{
+ // This check is to make sure that the script we created can actually be solved for and signed by us
+ // if we were to have the private keys. This is just to make sure that the script is valid and that,
+ // if found in a transaction, we would still accept and relay that transaction. In particular,
+ // it will reject witness outputs that require signing with an uncompressed public key.
+ DummySignatureCreator creator(&store);
+ SignatureData sigs;
+ // Make sure that STANDARD_SCRIPT_VERIFY_FLAGS includes SCRIPT_VERIFY_WITNESS_PUBKEYTYPE, the most
+ // important property this function is designed to test for.
+ static_assert(STANDARD_SCRIPT_VERIFY_FLAGS & SCRIPT_VERIFY_WITNESS_PUBKEYTYPE, "IsSolvable requires standard script flags to include WITNESS_PUBKEYTYPE");
+ if (ProduceSignature(creator, script, sigs)) {
+ // VerifyScript check is just defensive, and should never fail.
+ assert(VerifyScript(sigs.scriptSig, script, &sigs.scriptWitness, STANDARD_SCRIPT_VERIFY_FLAGS, creator.Checker()));
+ return true;
+ }
+ return false;
+}
diff --git a/src/script/sign.h b/src/script/sign.h
index a0d8ee4ff..97c0014cd 100644
--- a/src/script/sign.h
+++ b/src/script/sign.h
@@ -1,12 +1,12 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto
-// Copyright (c) 2009-2016 The Bitcoin Core developers
+// Copyright (c) 2009-2017 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_SCRIPT_SIGN_H
#define BITCOIN_SCRIPT_SIGN_H
-#include "script/interpreter.h"
+#include <script/interpreter.h>
class CKeyID;
class CKeyStore;
@@ -81,4 +81,10 @@ SignatureData CombineSignatures(const CScript& scriptPubKey, const BaseSignature
SignatureData DataFromTransaction(const CMutableTransaction& tx, unsigned int nIn);
void UpdateTransaction(CMutableTransaction& tx, unsigned int nIn, const SignatureData& data);
+/* Check whether we know how to sign for an output like this, assuming we
+ * have all private keys. While this function does not need private keys, the passed
+ * keystore is used to look up public keys and redeemscripts by hash.
+ * Solvability is unrelated to whether we consider this output to be ours. */
+bool IsSolvable(const CKeyStore& store, const CScript& script);
+
#endif // BITCOIN_SCRIPT_SIGN_H
diff --git a/src/script/standard.cpp b/src/script/standard.cpp
index f57f1f61b..cfb3c5858 100644
--- a/src/script/standard.cpp
+++ b/src/script/standard.cpp
@@ -1,14 +1,14 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto
-// Copyright (c) 2009-2016 The Bitcoin Core developers
+// Copyright (c) 2009-2017 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
-#include "script/standard.h"
+#include <script/standard.h>
-#include "pubkey.h"
-#include "script/script.h"
-#include "util.h"
-#include "utilstrencodings.h"
+#include <pubkey.h>
+#include <script/script.h>
+#include <util.h>
+#include <utilstrencodings.h>
typedef std::vector<unsigned char> valtype;
@@ -348,19 +348,14 @@ CScript GetScriptForWitness(const CScript& redeemscript)
std::vector<std::vector<unsigned char> > vSolutions;
if (Solver(redeemscript, typ, vSolutions)) {
if (typ == TX_PUBKEY) {
- unsigned char h160[20];
- CHash160().Write(&vSolutions[0][0], vSolutions[0].size()).Finalize(h160);
- ret << OP_0 << std::vector<unsigned char>(&h160[0], &h160[20]);
- return ret;
+ return GetScriptForDestination(WitnessV0KeyHash(Hash160(vSolutions[0].begin(), vSolutions[0].end())));
} else if (typ == TX_PUBKEYHASH) {
- ret << OP_0 << vSolutions[0];
- return ret;
+ return GetScriptForDestination(WitnessV0KeyHash(vSolutions[0]));
}
}
uint256 hash;
CSHA256().Write(&redeemscript[0], redeemscript.size()).Finalize(hash.begin());
- ret << OP_0 << ToByteVector(hash);
- return ret;
+ return GetScriptForDestination(WitnessV0ScriptHash(hash));
}
bool IsValidDestination(const CTxDestination& dest) {
diff --git a/src/script/standard.h b/src/script/standard.h
index fa07ea88c..3b2838a5b 100644
--- a/src/script/standard.h
+++ b/src/script/standard.h
@@ -1,13 +1,13 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto
-// Copyright (c) 2009-2016 The Bitcoin Core developers
+// Copyright (c) 2009-2017 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_SCRIPT_STANDARD_H
#define BITCOIN_SCRIPT_STANDARD_H
-#include "script/interpreter.h"
-#include "uint256.h"
+#include <script/interpreter.h>
+#include <uint256.h>
#include <boost/variant.hpp>
@@ -73,8 +73,19 @@ public:
friend bool operator<(const CNoDestination &a, const CNoDestination &b) { return true; }
};
-struct WitnessV0ScriptHash : public uint256 {};
-struct WitnessV0KeyHash : public uint160 {};
+struct WitnessV0ScriptHash : public uint256
+{
+ WitnessV0ScriptHash() : uint256() {}
+ explicit WitnessV0ScriptHash(const uint256& hash) : uint256(hash) {}
+ using uint256::uint256;
+};
+
+struct WitnessV0KeyHash : public uint160
+{
+ WitnessV0KeyHash() : uint160() {}
+ explicit WitnessV0KeyHash(const uint160& hash) : uint160(hash) {}
+ using uint160::uint160;
+};
//! CTxDestination subtype to encode any future Witness version
struct WitnessUnknown
@@ -144,6 +155,10 @@ bool ExtractDestination(const CScript& scriptPubKey, CTxDestination& addressRet)
* addressRet is populated with a single value and nRequiredRet is set to 1.
* Returns true if successful. Currently does not extract address from
* pay-to-witness scripts.
+ *
+ * Note: this function confuses destinations (a subset of CScripts that are
+ * encodable as an address) with key identifiers (of keys involved in a
+ * CScript), and its use should be phased out.
*/
bool ExtractDestinations(const CScript& scriptPubKey, txnouttype& typeRet, std::vector<CTxDestination>& addressRet, int& nRequiredRet);
@@ -164,6 +179,9 @@ CScript GetScriptForMultisig(int nRequired, const std::vector<CPubKey>& keys);
* Generate a pay-to-witness script for the given redeem script. If the redeem
* script is P2PK or P2PKH, this returns a P2WPKH script, otherwise it returns a
* P2WSH script.
+ *
+ * TODO: replace calls to GetScriptForWitness with GetScriptForDestination using
+ * the various witness-specific CTxDestination subtypes.
*/
CScript GetScriptForWitness(const CScript& redeemscript);