2014-08-27 17:22:33 +02:00
// Copyright (c) 2009-2010 Satoshi Nakamoto
2018-07-26 18:36:45 -04:00
// Copyright (c) 2009-2018 The Bitcoin Core developers
2014-09-09 10:00:42 +02:00
// Distributed under the MIT software license, see the accompanying
2014-08-27 17:22:33 +02:00
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
2014-11-03 16:16:40 +01:00
# ifndef BITCOIN_SCRIPT_SIGN_H
# define BITCOIN_SCRIPT_SIGN_H
2014-08-27 17:22:33 +02:00
2018-06-27 16:53:48 -07:00
# include <boost/optional.hpp>
# include <hash.h>
# include <pubkey.h>
2017-11-10 13:57:53 +13:00
# include <script/interpreter.h>
2019-06-17 15:47:12 -04:00
# include <script/keyorigin.h>
2018-06-27 16:53:48 -07:00
# include <streams.h>
2014-08-27 17:22:33 +02:00
2018-03-17 19:19:09 -07:00
class CKey ;
2014-11-04 10:06:20 -08:00
class CKeyID ;
2014-08-27 17:22:33 +02:00
class CScript ;
2018-03-17 19:19:09 -07:00
class CScriptID ;
2014-08-27 17:22:33 +02:00
class CTransaction ;
2019-06-06 22:52:24 +02:00
class SigningProvider ;
2014-09-09 10:00:42 +02:00
2014-08-27 17:22:33 +02:00
struct CMutableTransaction ;
2018-03-27 13:15:10 -07:00
/** Interface for signature creators. */
2014-11-04 10:06:20 -08:00
class BaseSignatureCreator {
public :
virtual ~ BaseSignatureCreator ( ) { }
virtual const BaseSignatureChecker & Checker ( ) const = 0 ;
/** Create a singular (non-script) signature. */
2018-03-27 13:15:10 -07:00
virtual bool CreateSig ( const SigningProvider & provider , std : : vector < unsigned char > & vchSig , const CKeyID & keyid , const CScript & scriptCode , SigVersion sigversion ) const = 0 ;
2014-11-04 10:06:20 -08:00
} ;
/** A signature creator for transactions. */
2018-05-20 22:47:14 +02:00
class MutableTransactionSignatureCreator : public BaseSignatureCreator {
const CMutableTransaction * txTo ;
2014-11-04 10:06:20 -08:00
unsigned int nIn ;
int nHashType ;
2015-12-27 19:49:08 +01:00
CAmount amount ;
2018-05-20 22:47:14 +02:00
const MutableTransactionSignatureChecker checker ;
2014-11-04 10:06:20 -08:00
public :
2018-05-20 22:47:14 +02:00
MutableTransactionSignatureCreator ( const CMutableTransaction * txToIn , unsigned int nInIn , const CAmount & amountIn , int nHashTypeIn = SIGHASH_ALL ) ;
2017-06-20 21:58:56 +02:00
const BaseSignatureChecker & Checker ( ) const override { return checker ; }
2018-03-27 13:15:10 -07:00
bool CreateSig ( const SigningProvider & provider , std : : vector < unsigned char > & vchSig , const CKeyID & keyid , const CScript & scriptCode , SigVersion sigversion ) const override ;
2016-03-31 14:54:58 +02:00
} ;
2018-08-07 16:59:53 -07:00
/** A signature creator that just produces 71-byte empty signatures. */
2018-03-27 13:34:39 -07:00
extern const BaseSignatureCreator & DUMMY_SIGNATURE_CREATOR ;
2018-08-07 16:59:53 -07:00
/** A signature creator that just produces 72-byte empty signatures. */
extern const BaseSignatureCreator & DUMMY_MAXIMUM_SIGNATURE_CREATOR ;
2016-03-31 14:54:58 +02:00
2018-07-03 17:18:52 -07:00
typedef std : : pair < CPubKey , std : : vector < unsigned char > > SigPair ;
// This struct contains information from a transaction input and also contains signatures for that input.
// The information contained here can be used to create a signature and is also filled by ProduceSignature
// in order to construct final scriptSigs and scriptWitnesses.
2016-03-31 14:54:58 +02:00
struct SignatureData {
2018-07-03 17:18:52 -07:00
bool complete = false ; ///< Stores whether the scriptSig and scriptWitness are complete
2018-06-27 16:56:30 -07:00
bool witness = false ; ///< Stores whether the input this SigData corresponds to is a witness input
2018-07-03 17:18:52 -07:00
CScript scriptSig ; ///< The scriptSig of an input. Contains complete signatures or the traditional partial signatures format
CScript redeem_script ; ///< The redeemScript (if any) for the input
CScript witness_script ; ///< The witnessScript (if any) for the input. witnessScripts are used in P2WSH outputs.
CScriptWitness scriptWitness ; ///< The scriptWitness of an input. Contains complete signatures or the traditional partial signatures format. scriptWitness is part of a transaction input per BIP 144.
std : : map < CKeyID , SigPair > signatures ; ///< BIP 174 style partial signatures for the input. May contain all signatures necessary for producing a final scriptSig or scriptWitness.
2018-07-19 18:47:24 -07:00
std : : map < CKeyID , std : : pair < CPubKey , KeyOriginInfo > > misc_pubkeys ;
2018-07-31 17:57:15 -07:00
std : : vector < CKeyID > missing_pubkeys ; ///< KeyIDs of pubkeys which could not be found
std : : vector < CKeyID > missing_sigs ; ///< KeyIDs of pubkeys for signatures which could not be found
uint160 missing_redeem_script ; ///< ScriptID of the missing redeemScript (if any)
uint256 missing_witness_script ; ///< SHA256 of the missing witnessScript (if any)
2016-03-31 14:54:58 +02:00
SignatureData ( ) { }
explicit SignatureData ( const CScript & script ) : scriptSig ( script ) { }
2018-06-07 21:12:25 -07:00
void MergeSignatureData ( SignatureData sigdata ) ;
2015-05-01 15:21:06 +02:00
} ;
2018-07-18 17:52:43 -07:00
// Takes a stream and multiple arguments and serializes them as if first serialized into a vector and then into the stream
2018-06-27 16:53:48 -07:00
// The resulting output into the stream has the total serialized length of all of the objects followed by all objects concatenated with each other.
template < typename Stream , typename . . . X >
void SerializeToVector ( Stream & s , const X & . . . args )
{
2018-06-14 19:48:30 -05:00
WriteCompactSize ( s , GetSerializeSizeMany ( s . GetVersion ( ) , args . . . ) ) ;
2018-07-18 17:52:43 -07:00
SerializeMany ( s , args . . . ) ;
2018-06-27 16:53:48 -07:00
}
// Takes a stream and multiple arguments and unserializes them first as a vector then each object individually in the order provided in the arguments
template < typename Stream , typename . . . X >
void UnserializeFromVector ( Stream & s , X & . . . args )
{
2018-07-18 17:52:43 -07:00
size_t expected_size = ReadCompactSize ( s ) ;
size_t remaining_before = s . size ( ) ;
UnserializeMany ( s , args . . . ) ;
size_t remaining_after = s . size ( ) ;
if ( remaining_after + expected_size ! = remaining_before ) {
2018-06-27 16:53:48 -07:00
throw std : : ios_base : : failure ( " Size of value was not the stated size " ) ;
}
}
// Deserialize HD keypaths into a map
template < typename Stream >
2018-07-19 23:15:53 -07:00
void DeserializeHDKeypaths ( Stream & s , const std : : vector < unsigned char > & key , std : : map < CPubKey , KeyOriginInfo > & hd_keypaths )
2018-06-27 16:53:48 -07:00
{
// Make sure that the key is the size of pubkey + 1
if ( key . size ( ) ! = CPubKey : : PUBLIC_KEY_SIZE + 1 & & key . size ( ) ! = CPubKey : : COMPRESSED_PUBLIC_KEY_SIZE + 1 ) {
throw std : : ios_base : : failure ( " Size of key was not the expected size for the type BIP32 keypath " ) ;
}
// Read in the pubkey from key
CPubKey pubkey ( key . begin ( ) + 1 , key . end ( ) ) ;
if ( ! pubkey . IsFullyValid ( ) ) {
throw std : : ios_base : : failure ( " Invalid pubkey " ) ;
}
if ( hd_keypaths . count ( pubkey ) > 0 ) {
throw std : : ios_base : : failure ( " Duplicate Key, pubkey derivation path already provided " ) ;
}
// Read in key path
uint64_t value_len = ReadCompactSize ( s ) ;
2018-07-19 23:15:53 -07:00
if ( value_len % 4 | | value_len = = 0 ) {
throw std : : ios_base : : failure ( " Invalid length for HD key path " ) ;
}
KeyOriginInfo keypath ;
s > > keypath . fingerprint ;
for ( unsigned int i = 4 ; i < value_len ; i + = sizeof ( uint32_t ) ) {
2018-06-27 16:53:48 -07:00
uint32_t index ;
s > > index ;
2018-07-19 23:15:53 -07:00
keypath . path . push_back ( index ) ;
2018-06-27 16:53:48 -07:00
}
// Add to map
2018-07-19 23:15:53 -07:00
hd_keypaths . emplace ( pubkey , std : : move ( keypath ) ) ;
2018-06-27 16:53:48 -07:00
}
// Serialize HD keypaths to a stream from a map
template < typename Stream >
2018-07-19 23:15:53 -07:00
void SerializeHDKeypaths ( Stream & s , const std : : map < CPubKey , KeyOriginInfo > & hd_keypaths , uint8_t type )
2018-06-27 16:53:48 -07:00
{
for ( auto keypath_pair : hd_keypaths ) {
2018-11-08 10:33:05 -05:00
if ( ! keypath_pair . first . IsValid ( ) ) {
throw std : : ios_base : : failure ( " Invalid CPubKey being serialized " ) ;
}
2018-06-27 16:53:48 -07:00
SerializeToVector ( s , type , MakeSpan ( keypath_pair . first ) ) ;
2018-07-19 23:15:53 -07:00
WriteCompactSize ( s , ( keypath_pair . second . path . size ( ) + 1 ) * sizeof ( uint32_t ) ) ;
s < < keypath_pair . second . fingerprint ;
for ( const auto & path : keypath_pair . second . path ) {
2018-06-27 16:53:48 -07:00
s < < path ;
}
}
}
2014-11-04 10:06:20 -08:00
/** Produce a script signature using a generic signature creator. */
2018-03-27 13:15:10 -07:00
bool ProduceSignature ( const SigningProvider & provider , const BaseSignatureCreator & creator , const CScript & scriptPubKey , SignatureData & sigdata ) ;
2014-11-04 10:06:20 -08:00
/** Produce a script signature for a transaction. */
2018-03-17 19:19:09 -07:00
bool SignSignature ( const SigningProvider & provider , const CScript & fromPubKey , CMutableTransaction & txTo , unsigned int nIn , const CAmount & amount , int nHashType ) ;
bool SignSignature ( const SigningProvider & provider , const CTransaction & txFrom , CMutableTransaction & txTo , unsigned int nIn , int nHashType ) ;
2014-08-27 17:22:33 +02:00
2018-07-03 17:18:52 -07:00
/** Extract signature data from a transaction input, and insert it. */
SignatureData DataFromTransaction ( const CMutableTransaction & tx , unsigned int nIn , const CTxOut & txout ) ;
2018-03-05 16:37:24 -05:00
void UpdateInput ( CTxIn & input , const SignatureData & data ) ;
2014-08-27 17:22:33 +02:00
2017-11-30 16:48:31 -08:00
/* 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
2018-03-17 19:19:09 -07:00
* provider is used to look up public keys and redeemscripts by hash .
2017-11-30 16:48:31 -08:00
* Solvability is unrelated to whether we consider this output to be ours . */
2018-03-17 19:19:09 -07:00
bool IsSolvable ( const SigningProvider & provider , const CScript & script ) ;
2017-11-30 16:48:31 -08:00
2019-02-16 14:18:54 -08:00
/** Check whether a scriptPubKey is known to be segwit. */
bool IsSegWitOutput ( const SigningProvider & provider , const CScript & script ) ;
2014-11-03 16:16:40 +01:00
# endif // BITCOIN_SCRIPT_SIGN_H