Hush Full Node software. We were censored from Github, this is where all development happens now. https://hush.is
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

174 lines
7.1 KiB

// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2014 The Bitcoin Core developers
// Copyright (c) 2016-2020 The Hush developers
// Distributed under the GPLv3 software license, see the accompanying
// file COPYING or https://www.gnu.org/licenses/gpl-3.0.en.html
/******************************************************************************
* Copyright © 2014-2019 The SuperNET Developers. *
* *
* See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at *
* the top-level directory of this distribution for the individual copyright *
* holder information and the developer policies on copyright and licensing. *
* *
* Unless otherwise agreed in a custom licensing agreement, no part of the *
* SuperNET software, including this file may be copied, modified, propagated *
* or distributed except according to the terms contained in the LICENSE file *
* *
* Removal or modification of this copyright notice is prohibited. *
* *
******************************************************************************/
#ifndef HUSH_SCRIPT_STANDARD_H
#define HUSH_SCRIPT_STANDARD_H
#include "script/interpreter.h"
#include "uint256.h"
#include <boost/variant.hpp>
#include <stdint.h>
class CKeyID;
class CScript;
/** A reference to a CScript: the Hash160 of its serialization (see script.h) */
class CScriptID : public uint160
{
public:
CScriptID() : uint160() {}
CScriptID(const CScript& in);
CScriptID(const uint160& in) : uint160(in) {}
};
8 years ago
static const unsigned int MAX_OP_RETURN_RELAY = 8192; //! bytes
extern unsigned nMaxDatacarrierBytes;
/**
* Mandatory script verification flags that all new blocks must comply with for
* them to be valid. (but old blocks may not comply with) Currently just P2SH,
* but in the future other flags may be added.
*
* Failing one of these tests may trigger a DoS ban - see CheckInputs() for
* details.
*/
static const unsigned int MANDATORY_SCRIPT_VERIFY_FLAGS = SCRIPT_VERIFY_P2SH;
/**
* Standard script verification flags that standard transactions will comply
* with. However scripts violating these flags may still be present in valid
* blocks and we must accept those blocks.
*/
static const unsigned int STANDARD_SCRIPT_VERIFY_FLAGS = MANDATORY_SCRIPT_VERIFY_FLAGS |
// SCRIPT_VERIFY_DERSIG is always enforced
SCRIPT_VERIFY_STRICTENC |
SCRIPT_VERIFY_MINIMALDATA |
SCRIPT_VERIFY_NULLDUMMY |
SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS |
Test LowS in standardness, removes nuisance malleability vector. This adds SCRIPT_VERIFY_LOW_S to STANDARD_SCRIPT_VERIFY_FLAGS which will make the node require the canonical 'low-s' encoding for ECDSA signatures when relaying or mining. Consensus behavior is unchanged. The rational is explained in a81cd96805ce6b65cca3a40ebbd3b2eb428abb7b: Absent this kind of test ECDSA is not a strong signature as given a valid signature {r, s} both that value and {r, -s mod n} are valid. These two encodings have different hashes allowing third parties a vector to change users txids. These attacks are avoided by picking a particular form as canonical and rejecting the other form(s); in the of the LOW_S rule, the smaller of the two possible S values is used. If widely deployed this change would eliminate the last remaining known vector for nuisance malleability on boring SIGHASH_ALL p2pkh transactions. On the down-side it will block most transactions made by sufficiently out of date software. Unlike the other avenues to change txids on boring transactions this one was randomly violated by all deployed bitcoin software prior to its discovery. So, while other malleability vectors where made non-standard as soon as they were discovered, this one has remained permitted. Even BIP62 did not propose applying this rule to old version transactions, but conforming implementations have become much more common since BIP62 was initially written. Bitcoin Core has produced compatible signatures since a28fb70e in September 2013, but this didn't make it into a release until 0.9 in March 2014; Bitcoinj has done so for a similar span of time. Bitcoinjs and electrum have been more recently updated. This does not replace the need for BIP62 or similar, as miners can still cooperate to break transactions. Nor does it replace the need for wallet software to handle malleability sanely[1]. This only eliminates the cheap and irritating DOS attack. [1] On the Malleability of Bitcoin Transactions Marcin Andrychowicz, Stefan Dziembowski, Daniel Malinowski, Łukasz Mazurek http://fc15.ifca.ai/preproceedings/bitcoin/paper_9.pdf Rebased-From: b196b685c9089b74fd4ff3d9a28ea847ab36179b Github-Pull: #6769
9 years ago
SCRIPT_VERIFY_CLEANSTACK |
SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY |
Test LowS in standardness, removes nuisance malleability vector. This adds SCRIPT_VERIFY_LOW_S to STANDARD_SCRIPT_VERIFY_FLAGS which will make the node require the canonical 'low-s' encoding for ECDSA signatures when relaying or mining. Consensus behavior is unchanged. The rational is explained in a81cd96805ce6b65cca3a40ebbd3b2eb428abb7b: Absent this kind of test ECDSA is not a strong signature as given a valid signature {r, s} both that value and {r, -s mod n} are valid. These two encodings have different hashes allowing third parties a vector to change users txids. These attacks are avoided by picking a particular form as canonical and rejecting the other form(s); in the of the LOW_S rule, the smaller of the two possible S values is used. If widely deployed this change would eliminate the last remaining known vector for nuisance malleability on boring SIGHASH_ALL p2pkh transactions. On the down-side it will block most transactions made by sufficiently out of date software. Unlike the other avenues to change txids on boring transactions this one was randomly violated by all deployed bitcoin software prior to its discovery. So, while other malleability vectors where made non-standard as soon as they were discovered, this one has remained permitted. Even BIP62 did not propose applying this rule to old version transactions, but conforming implementations have become much more common since BIP62 was initially written. Bitcoin Core has produced compatible signatures since a28fb70e in September 2013, but this didn't make it into a release until 0.9 in March 2014; Bitcoinj has done so for a similar span of time. Bitcoinjs and electrum have been more recently updated. This does not replace the need for BIP62 or similar, as miners can still cooperate to break transactions. Nor does it replace the need for wallet software to handle malleability sanely[1]. This only eliminates the cheap and irritating DOS attack. [1] On the Malleability of Bitcoin Transactions Marcin Andrychowicz, Stefan Dziembowski, Daniel Malinowski, Łukasz Mazurek http://fc15.ifca.ai/preproceedings/bitcoin/paper_9.pdf Rebased-From: b196b685c9089b74fd4ff3d9a28ea847ab36179b Github-Pull: #6769
9 years ago
SCRIPT_VERIFY_LOW_S;
/** For convenience, standard but not mandatory verify flags. */
static const unsigned int STANDARD_NOT_MANDATORY_VERIFY_FLAGS = STANDARD_SCRIPT_VERIFY_FLAGS & ~MANDATORY_SCRIPT_VERIFY_FLAGS;
enum txnouttype
{
TX_NONSTANDARD,
// 'standard' transaction types:
TX_PUBKEY,
TX_PUBKEYHASH,
TX_SCRIPTHASH,
TX_MULTISIG,
TX_CRYPTOCONDITION,
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 bitcoin address
*/
typedef boost::variant<CNoDestination, CPubKey, CKeyID, CScriptID> CTxDestination;
class COptCCParams
{
public:
static const uint8_t VERSION = 1;
uint8_t version;
uint8_t evalCode;
uint8_t m, n; // for m of n sigs required, n pub keys for sigs will follow
std::vector<CPubKey> vKeys; // n public keys to aid in signing
std::vector<std::vector<unsigned char>> vData; // extra parameters
COptCCParams() : version(0), evalCode(0), n(0), m(0) {}
COptCCParams(uint8_t ver, uint8_t code, uint8_t _n, uint8_t _m, std::vector<CPubKey> &vkeys, std::vector<std::vector<unsigned char>> &vdata) :
version(ver), evalCode(code), n(_n), m(_m), vKeys(vkeys), vData(vdata) {}
COptCCParams(std::vector<unsigned char> &vch);
bool IsValid() { return version != 0; }
std::vector<unsigned char> AsVector();
};
class CStakeParams
{
public:
static const uint32_t STAKE_MINPARAMS = 4;
static const uint32_t STAKE_MAXPARAMS = 5;
uint32_t srcHeight;
uint32_t blkHeight;
uint256 prevHash;
CPubKey pk;
CStakeParams() : srcHeight(0), blkHeight(0), prevHash(), pk() {}
CStakeParams(const std::vector<std::vector<unsigned char>> &vData);
CStakeParams(uint32_t _srcHeight, uint32_t _blkHeight, const uint256 &_prevHash, const CPubKey &_pk) :
srcHeight(_srcHeight), blkHeight(_blkHeight), prevHash(_prevHash), pk(_pk) {}
std::vector<unsigned char> AsVector()
{
std::vector<unsigned char> ret;
CScript scr = CScript();
scr << OPRETTYPE_STAKEPARAMS;
scr << srcHeight;
scr << blkHeight;
scr << std::vector<unsigned char>(prevHash.begin(), prevHash.end());
if (pk.IsValid())
{
scr << std::vector<unsigned char>(pk.begin(), pk.end());
}
ret = std::vector<unsigned char>(scr.begin(), scr.end());
return ret;
}
bool IsValid() { return srcHeight != 0; }
};
/** Check whether a CTxDestination is a CNoDestination. */
bool IsValidDestination(const CTxDestination& dest);
const char* GetTxnOutputType(txnouttype t);
bool Solver(const CScript& scriptPubKey, txnouttype& typeRet, std::vector<std::vector<unsigned char> >& vSolutionsRet);
int ScriptSigArgsExpected(txnouttype t, const std::vector<std::vector<unsigned char> >& vSolutions);
bool IsStandard(const CScript& scriptPubKey, txnouttype& whichType);
bool ExtractDestination(const CScript& scriptPubKey, CTxDestination& addressRet, bool returnPubKey=false);
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 // HUSH_SCRIPT_STANDARD_H