@ -45,14 +45,14 @@ bool TransactionSignatureCreator::CreateSig(std::vector<unsigned char>& vchSig,
key = * pprivKey ;
else if ( ! keystore | | ! keystore - > GetKey ( address , key ) )
return false ;
uint256 hash ;
try {
hash = SignatureHash ( scriptCode , * txTo , nIn , nHashType , amount , consensusBranchId ) ;
} catch ( logic_error ex ) {
return false ;
}
if ( scriptCode . IsPayToCryptoCondition ( ) )
{
CC * cc = ( CC * ) extraData ;
@ -75,9 +75,9 @@ bool TransactionSignatureCreator::CreateSig(std::vector<unsigned char>& vchSig,
return false ;
}
}
vchSig . push_back ( ( unsigned char ) nHashType ) ;
return true ;
}
@ -128,7 +128,7 @@ std::vector<CCcontract_info> &GetCryptoConditions()
static bool initialized = false ;
static std : : vector < CCcontract_info > vCC = std : : vector < CCcontract_info > ( ) ;
CCcontract_info C ;
if ( ! initialized )
{
// this should initialize any desired auto-signed crypto-conditions
@ -140,7 +140,7 @@ bool GetCCByUnspendableAddress(struct CC_info *cp, char *addrstr)
{
std : : vector < CCcontract_info > & vCC = GetCryptoConditions ( ) ;
bool found = false ;
for ( int i = 0 ; i < vCC . size ( ) ; i + + )
{
if ( strcmp ( addrstr , vCC [ i ] . unspendableCCaddr ) = = 0 )
@ -157,7 +157,7 @@ bool CCinitLite(struct CC_info *cp, uint8_t evalcode)
{
std : : vector < CCcontract_info > & vCC = GetCryptoConditions ( ) ;
bool found = false ;
for ( int i = 0 ; i < vCC . size ( ) ; i + + )
{
if ( vCC [ i ] . evalcode = = evalcode )
@ -172,7 +172,7 @@ bool CCinitLite(struct CC_info *cp, uint8_t evalcode)
bool _Getscriptaddress ( char * destaddr , const CScript & scriptPubKey )
{
CTxDestination address ;
CTxDestination address ;
txnouttype whichType ;
std : : vector < std : : vector < unsigned char > > vvch = std : : vector < std : : vector < unsigned char > > ( ) ;
if ( Solver ( scriptPubKey , whichType , vvch ) & & vvch [ 0 ] . size ( ) = = 20 )
@ -199,10 +199,10 @@ static bool SignStepCC(const BaseSignatureCreator& creator, const CScript& scrip
vector < CPubKey > vPK ;
vector < valtype > vParams = vector < valtype > ( ) ;
COptCCParams p ;
// get information to sign with
CCcontract_info C ;
scriptPubKey . IsPayToCryptoCondition ( & subScript , vParams ) ;
if ( vParams . empty ( ) )
{
@ -219,12 +219,12 @@ static bool SignStepCC(const BaseSignatureCreator& creator, const CScript& scrip
{
p = COptCCParams ( vParams [ 0 ] ) ;
}
if ( p . IsValid ( ) & & p . vKeys . size ( ) > = p . n )
{
bool is1of2 = ( p . m = = 1 & & p . n = = 2 ) ;
CKey privKey ;
// must be a valid cc eval code
if ( CCinitLite ( & C , p . evalCode ) )
{
@ -232,7 +232,7 @@ static bool SignStepCC(const BaseSignatureCreator& creator, const CScript& scrip
if ( ! is1of2 )
{
bool havePriv = creator . KeyStore ( ) . GetKey ( p . vKeys [ 0 ] . GetID ( ) , privKey ) ;
// if we don't have the private key, it must be the unspendable address
if ( ! havePriv & & ( p . vKeys [ 0 ] = = CPubKey ( ParseHex ( C . CChexstr ) ) ) )
{
@ -240,9 +240,9 @@ static bool SignStepCC(const BaseSignatureCreator& creator, const CScript& scrip
std : : vector < unsigned char > vch ( & ( C . CCpriv [ 0 ] ) , C . CCpriv + sizeof ( C . CCpriv ) ) ;
privKey . Set ( vch . begin ( ) , vch . end ( ) , false ) ;
}
CC * cc = CCcond1 ( p . evalCode , p . vKeys [ 0 ] ) ;
if ( cc )
{
vector < unsigned char > vch ;
@ -254,7 +254,7 @@ static bool SignStepCC(const BaseSignatureCreator& creator, const CScript& scrip
{
fprintf ( stderr , " vin has 1of1 CC signing error with address.(%s) \n " , p . vKeys [ 0 ] . GetID ( ) . ToString ( ) . c_str ( ) ) ;
}
cc_free ( cc ) ;
return ret . size ( ) ! = 0 ;
}
@ -266,7 +266,7 @@ static bool SignStepCC(const BaseSignatureCreator& creator, const CScript& scrip
{
if ( creator . IsKeystoreValid ( ) & & creator . KeyStore ( ) . GetKey ( pk . GetID ( ) , privKey ) & & privKey . IsValid ( ) )
break ;
if ( pk = = CPubKey ( ParseHex ( C . CChexstr ) ) )
{
privKey = CKey ( ) ;
@ -275,12 +275,12 @@ static bool SignStepCC(const BaseSignatureCreator& creator, const CScript& scrip
break ;
}
}
if ( ! privKey . IsValid ( ) )
return false ;
CC * cc = CCcond1of2 ( p . evalCode , p . vKeys [ 0 ] , p . vKeys [ 1 ] ) ;
if ( cc )
{
vector < unsigned char > vch ;
@ -292,7 +292,7 @@ static bool SignStepCC(const BaseSignatureCreator& creator, const CScript& scrip
{
fprintf ( stderr , " vin has 1of2 CC signing error with addresses.(%s) \n (%s) \n " , p . vKeys [ 0 ] . GetID ( ) . ToString ( ) . c_str ( ) , p . vKeys [ 1 ] . GetID ( ) . ToString ( ) . c_str ( ) ) ;
}
cc_free ( cc ) ;
return ret . size ( ) ! = 0 ;
}
@ -314,9 +314,9 @@ static bool SignStep(const BaseSignatureCreator& creator, const CScript& scriptP
CScript scriptRet ;
uint160 h160 ;
ret . clear ( ) ;
vector < valtype > vSolutions ;
if ( ! Solver ( scriptPubKey , whichTypeRet , vSolutions ) )
{
// if this is a CLTV script, solve for the destination after CLTV
@ -324,10 +324,10 @@ static bool SignStep(const BaseSignatureCreator& creator, const CScript& scriptP
{
uint8_t pushOp = scriptPubKey [ 0 ] ;
uint32_t scriptStart = pushOp + 3 ;
// check post CLTV script
CScript postfix = CScript ( scriptPubKey . size ( ) > scriptStart ? scriptPubKey . begin ( ) + scriptStart : scriptPubKey . end ( ) , scriptPubKey . end ( ) ) ;
// check again with only postfix subscript
if ( ! Solver ( postfix , whichTypeRet , vSolutions ) )
return false ;
@ -335,44 +335,44 @@ static bool SignStep(const BaseSignatureCreator& creator, const CScript& scriptP
else
return false ;
}
CKeyID keyID ;
switch ( whichTypeRet )
{
case TX_NONSTANDARD :
case TX_NULL_DATA :
return false ;
case TX_PUBKEY :
keyID = CPubKey ( vSolutions [ 0 ] ) . GetID ( ) ;
return Sign1 ( keyID , creator , scriptPubKey , ret , consensusBranchId ) ;
case TX_PUBKEYHASH :
keyID = CKeyID ( uint160 ( vSolutions [ 0 ] ) ) ;
if ( ! Sign1 ( keyID , creator , scriptPubKey , ret , consensusBranchId ) )
case TX_NONSTANDARD :
case TX_NULL_DATA :
return false ;
else
{
CPubKey vch ;
creator . KeyStore ( ) . GetPubKey ( keyID , vch ) ;
ret . push_back ( ToByteVector ( vch ) ) ;
}
return true ;
case TX_SCRIPTHASH :
if ( creator . KeyStore ( ) . GetCScript ( uint160 ( vSolutions [ 0 ] ) , scriptRet ) ) {
ret . push_back ( std : : vector < unsigned char > ( scriptRet . begin ( ) , scriptRet . end ( ) ) ) ;
case TX_PUBKEY :
keyID = CPubKey ( vSolutions [ 0 ] ) . GetID ( ) ;
return Sign1 ( keyID , creator , scriptPubKey , ret , consensusBranchId ) ;
case TX_PUBKEYHASH :
keyID = CKeyID ( uint160 ( vSolutions [ 0 ] ) ) ;
if ( ! Sign1 ( keyID , creator , scriptPubKey , ret , consensusBranchId ) )
return false ;
else
{
CPubKey vch ;
creator . KeyStore ( ) . GetPubKey ( keyID , vch ) ;
ret . push_back ( ToByteVector ( vch ) ) ;
}
return true ;
}
return false ;
case TX_CRYPTOCONDITION :
return SignStepCC ( creator , scriptPubKey , vSolutions , ret , consensusBranchId ) ;
case TX_MULTISIG :
ret . push_back ( valtype ( ) ) ; // workaround CHECKMULTISIG bug
return ( SignN ( vSolutions , creator , scriptPubKey , ret , consensusBranchId ) ) ;
default :
return false ;
case TX_SCRIPTHASH :
if ( creator . KeyStore ( ) . GetCScript ( uint160 ( vSolutions [ 0 ] ) , scriptRet ) ) {
ret . push_back ( std : : vector < unsigned char > ( scriptRet . begin ( ) , scriptRet . end ( ) ) ) ;
return true ;
}
return false ;
case TX_CRYPTOCONDITION :
return SignStepCC ( creator , scriptPubKey , vSolutions , ret , consensusBranchId ) ;
case TX_MULTISIG :
ret . push_back ( valtype ( ) ) ; // workaround CHECKMULTISIG bug
return ( SignN ( vSolutions , creator , scriptPubKey , ret , consensusBranchId ) ) ;
default :
return false ;
}
}
@ -399,7 +399,7 @@ bool ProduceSignature(const BaseSignatureCreator& creator, const CScript& fromPu
txnouttype whichType ;
solved = SignStep ( creator , script , result , whichType , consensusBranchId ) ;
CScript subscript ;
if ( solved & & whichType = = TX_SCRIPTHASH )
{
// Solver returns the subscript that needs to be evaluated;
@ -409,9 +409,9 @@ bool ProduceSignature(const BaseSignatureCreator& creator, const CScript& fromPu
solved = solved & & SignStep ( creator , script , result , whichType , consensusBranchId ) & & whichType ! = TX_SCRIPTHASH ;
result . push_back ( std : : vector < unsigned char > ( subscript . begin ( ) , subscript . end ( ) ) ) ;
}
sigdata . scriptSig = PushAll ( result ) ;
// Test solution
return solved & & VerifyScript ( sigdata . scriptSig , fromPubKey , STANDARD_SCRIPT_VERIFY_FLAGS , creator . Checker ( ) , consensusBranchId ) ;
}
@ -431,19 +431,19 @@ void UpdateTransaction(CMutableTransaction& tx, unsigned int nIn, const Signatur
}
bool SignSignature (
const CKeyStore & keystore ,
const CScript & fromPubKey ,
CMutableTransaction & txTo ,
unsigned int nIn ,
const CAmount & amount ,
int nHashType ,
uint32_t consensusBranchId )
const CKeyStore & keystore ,
const CScript & fromPubKey ,
CMutableTransaction & txTo ,
unsigned int nIn ,
const CAmount & amount ,
int nHashType ,
uint32_t consensusBranchId )
{
assert ( nIn < txTo . vin . size ( ) ) ;
CTransaction txToConst ( txTo ) ;
TransactionSignatureCreator creator ( & keystore , & txToConst , nIn , amount , nHashType ) ;
SignatureData sigdata ;
bool ret = ProduceSignature ( creator , fromPubKey , sigdata , consensusBranchId ) ;
UpdateTransaction ( txTo , nIn , sigdata ) ;
@ -451,24 +451,24 @@ bool SignSignature(
}
bool SignSignature (
const CKeyStore & keystore ,
const CTransaction & txFrom ,
CMutableTransaction & txTo ,
unsigned int nIn ,
int nHashType ,
uint32_t consensusBranchId )
const CKeyStore & keystore ,
const CTransaction & txFrom ,
CMutableTransaction & txTo ,
unsigned int nIn ,
int nHashType ,
uint32_t consensusBranchId )
{
assert ( nIn < txTo . vin . size ( ) ) ;
CTxIn & txin = txTo . vin [ nIn ] ;
assert ( txin . prevout . n < txFrom . vout . size ( ) ) ;
const CTxOut & txout = txFrom . vout [ txin . prevout . n ] ;
return SignSignature ( keystore , txout . scriptPubKey , txTo , nIn , txout . nValue , nHashType , consensusBranchId ) ;
}
static vector < valtype > CombineMultisig ( const CScript & scriptPubKey , const BaseSignatureChecker & checker ,
const vector < valtype > & vSolutions ,
const vector < valtype > & sigs1 , const vector < valtype > & sigs2 , uint32_t consensusBranchId )
const vector < valtype > & vSolutions ,
const vector < valtype > & sigs1 , const vector < valtype > & sigs2 , uint32_t consensusBranchId )
{
// Combine all the signatures we've got:
set < valtype > allsigs ;
@ -482,7 +482,7 @@ static vector<valtype> CombineMultisig(const CScript& scriptPubKey, const BaseSi
if ( ! v . empty ( ) )
allsigs . insert ( v ) ;
}
// Build a map of pubkey -> signature by matching sigs to pubkeys:
assert ( vSolutions . size ( ) > 1 ) ;
unsigned int nSigsRequired = vSolutions . front ( ) [ 0 ] ;
@ -495,7 +495,7 @@ static vector<valtype> CombineMultisig(const CScript& scriptPubKey, const BaseSi
const valtype & pubkey = vSolutions [ i + 1 ] ;
if ( sigs . count ( pubkey ) )
continue ; // Already got a sig for this pubkey
if ( checker . CheckSig ( sig , pubkey , scriptPubKey , consensusBranchId ) )
{
sigs [ pubkey ] = sig ;
@ -517,108 +517,108 @@ static vector<valtype> CombineMultisig(const CScript& scriptPubKey, const BaseSi
// Fill any missing with OP_0:
for ( unsigned int i = nSigsHave ; i < nSigsRequired ; i + + )
result . push_back ( valtype ( ) ) ;
return result ;
}
namespace
{
struct Stacks
{
std : : vector < valtype > script ;
Stacks ( ) { }
explicit Stacks ( const std : : vector < valtype > & scriptSigStack_ ) : script ( scriptSigStack_ ) { }
explicit Stacks ( const SignatureData & data , uint32_t consensusBranchId ) {
EvalScript ( script , data . scriptSig , SCRIPT_VERIFY_STRICTENC , BaseSignatureChecker ( ) , consensusBranchId ) ;
}
SignatureData Output ( ) const {
SignatureData result ;
result . scriptSig = PushAll ( script ) ;
return result ;
}
} ;
struct Stacks
{
std : : vector < valtype > script ;
Stacks ( ) { }
explicit Stacks ( const std : : vector < valtype > & scriptSigStack_ ) : script ( scriptSigStack_ ) { }
explicit Stacks ( const SignatureData & data , uint32_t consensusBranchId ) {
EvalScript ( script , data . scriptSig , SCRIPT_VERIFY_STRICTENC , BaseSignatureChecker ( ) , consensusBranchId ) ;
}
SignatureData Output ( ) const {
SignatureData result ;
result . scriptSig = PushAll ( script ) ;
return result ;
}
} ;
}
static Stacks CombineSignatures ( const CScript & scriptPubKey , const BaseSignatureChecker & checker ,
const txnouttype txType , const vector < valtype > & vSolutions ,
Stacks sigs1 , Stacks sigs2 , uint32_t consensusBranchId )
const txnouttype txType , const vector < valtype > & vSolutions ,
Stacks sigs1 , Stacks sigs2 , uint32_t consensusBranchId )
{
switch ( txType )
{
case TX_NONSTANDARD :
case TX_NULL_DATA :
// Don't know anything about this, assume bigger one is correct:
if ( sigs1 . script . size ( ) > = sigs2 . script . size ( ) )
return sigs1 ;
return sigs2 ;
case TX_PUBKEY :
case TX_PUBKEYHASH :
case TX_CRYPTOCONDITION :
// Signatures are bigger than placeholders or empty scripts:
if ( sigs1 . script . empty ( ) | | sigs1 . script [ 0 ] . empty ( ) )
return sigs2 ;
return sigs1 ;
case TX_SCRIPTHASH :
if ( sigs1 . script . empty ( ) | | sigs1 . script . back ( ) . empty ( ) )
case TX_NONSTANDARD :
case TX_NULL_DATA :
// Don't know anything about this, assume bigger one is correct:
if ( sigs1 . script . size ( ) > = sigs2 . script . size ( ) )
return sigs1 ;
return sigs2 ;
else if ( sigs2 . script . empty ( ) | | sigs2 . script . back ( ) . empty ( ) )
case TX_PUBKEY :
case TX_PUBKEYHASH :
case TX_CRYPTOCONDITION :
// Signatures are bigger than placeholders or empty scripts:
if ( sigs1 . script . empty ( ) | | sigs1 . script [ 0 ] . empty ( ) )
return sigs2 ;
return sigs1 ;
else
{
// Recur to combine:
valtype spk = sigs1 . script . back ( ) ;
CScript pubKey2 ( spk . begin ( ) , spk . end ( ) ) ;
txnouttype txType2 ;
vector < vector < unsigned char > > vSolutions2 ;
Solver ( pubKey2 , txType2 , vSolutions2 ) ;
sigs1 . script . pop_back ( ) ;
sigs2 . script . pop_back ( ) ;
Stacks result = CombineSignatures ( pubKey2 , checker , txType2 , vSolutions2 , sigs1 , sigs2 , consensusBranchId ) ;
result . script . push_back ( spk ) ;
return result ;
}
case TX_MULTISIG :
return Stacks ( CombineMultisig ( scriptPubKey , checker , vSolutions , sigs1 . script , sigs2 . script , consensusBranchId ) ) ;
default :
return Stacks ( ) ;
case TX_SCRIPTHASH :
if ( sigs1 . script . empty ( ) | | sigs1 . script . back ( ) . empty ( ) )
return sigs2 ;
else if ( sigs2 . script . empty ( ) | | sigs2 . script . back ( ) . empty ( ) )
return sigs1 ;
else
{
// Recur to combine:
valtype spk = sigs1 . script . back ( ) ;
CScript pubKey2 ( spk . begin ( ) , spk . end ( ) ) ;
txnouttype txType2 ;
vector < vector < unsigned char > > vSolutions2 ;
Solver ( pubKey2 , txType2 , vSolutions2 ) ;
sigs1 . script . pop_back ( ) ;
sigs2 . script . pop_back ( ) ;
Stacks result = CombineSignatures ( pubKey2 , checker , txType2 , vSolutions2 , sigs1 , sigs2 , consensusBranchId ) ;
result . script . push_back ( spk ) ;
return result ;
}
case TX_MULTISIG :
return Stacks ( CombineMultisig ( scriptPubKey , checker , vSolutions , sigs1 . script , sigs2 . script , consensusBranchId ) ) ;
default :
return Stacks ( ) ;
}
}
SignatureData CombineSignatures ( const CScript & scriptPubKey , const BaseSignatureChecker & checker ,
const SignatureData & scriptSig1 , const SignatureData & scriptSig2 ,
uint32_t consensusBranchId )
const SignatureData & scriptSig1 , const SignatureData & scriptSig2 ,
uint32_t consensusBranchId )
{
txnouttype txType ;
vector < vector < unsigned char > > vSolutions ;
Solver ( scriptPubKey , txType , vSolutions ) ;
return CombineSignatures (
scriptPubKey , checker , txType , vSolutions ,
Stacks ( scriptSig1 , consensusBranchId ) ,
Stacks ( scriptSig2 , consensusBranchId ) ,
consensusBranchId ) . Output ( ) ;
scriptPubKey , checker , txType , vSolutions ,
Stacks ( scriptSig1 , consensusBranchId ) ,
Stacks ( scriptSig2 , consensusBranchId ) ,
consensusBranchId ) . Output ( ) ;
}
namespace {
/** Dummy signature checker which accepts all signatures. */
class DummySignatureChecker : public BaseSignatureChecker
{
public :
DummySignatureChecker ( ) { }
bool CheckSig (
const std : : vector < unsigned char > & scriptSig ,
const std : : vector < unsigned char > & vchPubKey ,
const CScript & scriptCode ,
uint32_t consensusBranchId ) const
/** Dummy signature checker which accepts all signatures. */
class DummySignatureChecker : public BaseSignatureChecker
{
return true ;
}
} ;
const DummySignatureChecker dummyChecker ;
public :
DummySignatureChecker ( ) { }
bool CheckSig (
const std : : vector < unsigned char > & scriptSig ,
const std : : vector < unsigned char > & vchPubKey ,
const CScript & scriptCode ,
uint32_t consensusBranchId ) const
{
return true ;
}
} ;
const DummySignatureChecker dummyChecker ;
}
const BaseSignatureChecker & DummySignatureCreator : : Checker ( ) const
@ -627,12 +627,12 @@ const BaseSignatureChecker& DummySignatureCreator::Checker() const
}
bool DummySignatureCreator : : CreateSig (
std : : vector < unsigned char > & vchSig ,
const CKeyID & keyid ,
const CScript & scriptCode ,
uint32_t consensusBranchId ,
CKey * key ,
void * extraData ) const
std : : vector < unsigned char > & vchSig ,
const CKeyID & keyid ,
const CScript & scriptCode ,
uint32_t consensusBranchId ,
CKey * key ,
void * extraData ) const
{
// Create a dummy signature that is a valid DER-encoding
vchSig . assign ( 72 , ' \000 ' ) ;
@ -647,3 +647,4 @@ bool DummySignatureCreator::CreateSig(
vchSig [ 6 + 33 + 32 ] = SIGHASH_ALL ;
return true ;
}