@@ -17,43 +17,52 @@ using namespace std;
17
17
18
18
typedef vector<unsigned char > valtype;
19
19
20
- bool Sign1 (const CKeyID& address, const CKeyStore& keystore, uint256 hash, int nHashType, CScript& scriptSigRet)
20
+ TransactionSignatureCreator::TransactionSignatureCreator (const CKeyStore* keystoreIn, const CTransaction* txToIn, unsigned int nInIn, int nHashTypeIn) : BaseSignatureCreator(keystoreIn), txTo(txToIn), nIn(nInIn), nHashType(nHashTypeIn), checker(txTo, nIn) {}
21
+
22
+ bool TransactionSignatureCreator::CreateSig (std::vector<unsigned char >& vchSig, const CKeyID& address, const CScript& scriptCode) const
21
23
{
22
24
CKey key;
23
- if (!keystore. GetKey (address, key))
25
+ if (!keystore-> GetKey (address, key))
24
26
return false ;
25
27
26
- vector< unsigned char > vchSig ;
28
+ uint256 hash = SignatureHash (scriptCode, *txTo, nIn, nHashType) ;
27
29
if (!key.Sign (hash, vchSig))
28
30
return false ;
29
31
vchSig.push_back ((unsigned char )nHashType);
30
- scriptSigRet << vchSig;
32
+ return true ;
33
+ }
31
34
35
+ static bool Sign1 (const CKeyID& address, const BaseSignatureCreator& creator, const CScript& scriptCode, CScript& scriptSigRet)
36
+ {
37
+ vector<unsigned char > vchSig;
38
+ if (!creator.CreateSig (vchSig, address, scriptCode))
39
+ return false ;
40
+ scriptSigRet << vchSig;
32
41
return true ;
33
42
}
34
43
35
- bool SignN (const vector<valtype>& multisigdata, const CKeyStore& keystore, uint256 hash, int nHashType , CScript& scriptSigRet)
44
+ static bool SignN (const vector<valtype>& multisigdata, const BaseSignatureCreator& creator, const CScript& scriptCode , CScript& scriptSigRet)
36
45
{
37
46
int nSigned = 0 ;
38
47
int nRequired = multisigdata.front ()[0 ];
39
48
for (unsigned int i = 1 ; i < multisigdata.size ()-1 && nSigned < nRequired; i++)
40
49
{
41
50
const valtype& pubkey = multisigdata[i];
42
51
CKeyID keyID = CPubKey (pubkey).GetID ();
43
- if (Sign1 (keyID, keystore, hash, nHashType , scriptSigRet))
52
+ if (Sign1 (keyID, creator, scriptCode , scriptSigRet))
44
53
++nSigned;
45
54
}
46
55
return nSigned==nRequired;
47
56
}
48
57
49
58
/* *
50
- * Sign scriptPubKey with private keys stored in keystore, given transaction hash and hash type .
59
+ * Sign scriptPubKey using signature made with creator .
51
60
* Signatures are returned in scriptSigRet (or returns false if scriptPubKey can't be signed),
52
61
* unless whichTypeRet is TX_SCRIPTHASH, in which case scriptSigRet is the redemption script.
53
62
* Returns false if scriptPubKey could not be completely satisfied.
54
63
*/
55
- bool Solver (const CKeyStore& keystore , const CScript& scriptPubKey, uint256 hash, int nHashType ,
56
- CScript& scriptSigRet, txnouttype& whichTypeRet)
64
+ static bool SignStep (const BaseSignatureCreator& creator , const CScript& scriptPubKey,
65
+ CScript& scriptSigRet, txnouttype& whichTypeRet)
57
66
{
58
67
scriptSigRet.clear ();
59
68
@@ -69,61 +78,62 @@ bool Solver(const CKeyStore& keystore, const CScript& scriptPubKey, uint256 hash
69
78
return false ;
70
79
case TX_PUBKEY:
71
80
keyID = CPubKey (vSolutions[0 ]).GetID ();
72
- return Sign1 (keyID, keystore, hash, nHashType , scriptSigRet);
81
+ return Sign1 (keyID, creator, scriptPubKey , scriptSigRet);
73
82
case TX_PUBKEYHASH:
74
83
keyID = CKeyID (uint160 (vSolutions[0 ]));
75
- if (!Sign1 (keyID, keystore, hash, nHashType , scriptSigRet))
84
+ if (!Sign1 (keyID, creator, scriptPubKey , scriptSigRet))
76
85
return false ;
77
86
else
78
87
{
79
88
CPubKey vch;
80
- keystore .GetPubKey (keyID, vch);
89
+ creator. KeyStore () .GetPubKey (keyID, vch);
81
90
scriptSigRet << ToByteVector (vch);
82
91
}
83
92
return true ;
84
93
case TX_SCRIPTHASH:
85
- return keystore .GetCScript (uint160 (vSolutions[0 ]), scriptSigRet);
94
+ return creator. KeyStore () .GetCScript (uint160 (vSolutions[0 ]), scriptSigRet);
86
95
87
96
case TX_MULTISIG:
88
97
scriptSigRet << OP_0; // workaround CHECKMULTISIG bug
89
- return (SignN (vSolutions, keystore, hash, nHashType , scriptSigRet));
98
+ return (SignN (vSolutions, creator, scriptPubKey , scriptSigRet));
90
99
}
91
100
return false ;
92
101
}
93
102
94
- bool SignSignature (const CKeyStore &keystore , const CScript& fromPubKey, CMutableTransaction& txTo, unsigned int nIn, int nHashType )
103
+ bool ProduceSignature (const BaseSignatureCreator& creator , const CScript& fromPubKey, CScript& scriptSig )
95
104
{
96
- assert (nIn < txTo.vin .size ());
97
- CTxIn& txin = txTo.vin [nIn];
98
-
99
- // Leave out the signature from the hash, since a signature can't sign itself.
100
- // The checksig op will also drop the signatures from its hash.
101
- uint256 hash = SignatureHash (fromPubKey, txTo, nIn, nHashType);
102
-
103
105
txnouttype whichType;
104
- if (!Solver (keystore , fromPubKey, hash, nHashType, txin. scriptSig , whichType))
106
+ if (!SignStep (creator , fromPubKey, scriptSig, whichType))
105
107
return false ;
106
108
107
109
if (whichType == TX_SCRIPTHASH)
108
110
{
109
111
// Solver returns the subscript that need to be evaluated;
110
112
// the final scriptSig is the signatures from that
111
113
// and then the serialized subscript:
112
- CScript subscript = txin.scriptSig ;
113
-
114
- // Recompute txn hash using subscript in place of scriptPubKey:
115
- uint256 hash2 = SignatureHash (subscript, txTo, nIn, nHashType);
114
+ CScript subscript = scriptSig;
116
115
117
116
txnouttype subType;
118
117
bool fSolved =
119
- Solver (keystore , subscript, hash2, nHashType, txin. scriptSig , subType) && subType != TX_SCRIPTHASH;
118
+ SignStep (creator , subscript, scriptSig, subType) && subType != TX_SCRIPTHASH;
120
119
// Append serialized subscript whether or not it is completely signed:
121
- txin. scriptSig << static_cast <valtype>(subscript);
120
+ scriptSig << static_cast <valtype>(subscript);
122
121
if (!fSolved ) return false ;
123
122
}
124
123
125
124
// Test solution
126
- return VerifyScript (txin.scriptSig , fromPubKey, STANDARD_SCRIPT_VERIFY_FLAGS, MutableTransactionSignatureChecker (&txTo, nIn));
125
+ return VerifyScript (scriptSig, fromPubKey, STANDARD_SCRIPT_VERIFY_FLAGS, creator.Checker ());
126
+ }
127
+
128
+ bool SignSignature (const CKeyStore &keystore, const CScript& fromPubKey, CMutableTransaction& txTo, unsigned int nIn, int nHashType)
129
+ {
130
+ assert (nIn < txTo.vin .size ());
131
+ CTxIn& txin = txTo.vin [nIn];
132
+
133
+ CTransaction txToConst (txTo);
134
+ TransactionSignatureCreator creator (&keystore, &txToConst, nIn, nHashType);
135
+
136
+ return ProduceSignature (creator, fromPubKey, txin.scriptSig );
127
137
}
128
138
129
139
bool SignSignature (const CKeyStore &keystore, const CTransaction& txFrom, CMutableTransaction& txTo, unsigned int nIn, int nHashType)
@@ -144,7 +154,7 @@ static CScript PushAll(const vector<valtype>& values)
144
154
return result;
145
155
}
146
156
147
- static CScript CombineMultisig (const CScript& scriptPubKey, const CTransaction& txTo, unsigned int nIn ,
157
+ static CScript CombineMultisig (const CScript& scriptPubKey, const BaseSignatureChecker& checker ,
148
158
const vector<valtype>& vSolutions,
149
159
const vector<valtype>& sigs1, const vector<valtype>& sigs2)
150
160
{
@@ -174,7 +184,7 @@ static CScript CombineMultisig(const CScript& scriptPubKey, const CTransaction&
174
184
if (sigs.count (pubkey))
175
185
continue ; // Already got a sig for this pubkey
176
186
177
- if (TransactionSignatureChecker (&txTo, nIn) .CheckSig (sig, pubkey, scriptPubKey))
187
+ if (checker .CheckSig (sig, pubkey, scriptPubKey))
178
188
{
179
189
sigs[pubkey] = sig;
180
190
break ;
@@ -199,7 +209,7 @@ static CScript CombineMultisig(const CScript& scriptPubKey, const CTransaction&
199
209
return result;
200
210
}
201
211
202
- static CScript CombineSignatures (const CScript& scriptPubKey, const CTransaction& txTo, unsigned int nIn ,
212
+ static CScript CombineSignatures (const CScript& scriptPubKey, const BaseSignatureChecker& checker ,
203
213
const txnouttype txType, const vector<valtype>& vSolutions,
204
214
vector<valtype>& sigs1, vector<valtype>& sigs2)
205
215
{
@@ -233,19 +243,26 @@ static CScript CombineSignatures(const CScript& scriptPubKey, const CTransaction
233
243
Solver (pubKey2, txType2, vSolutions2);
234
244
sigs1.pop_back ();
235
245
sigs2.pop_back ();
236
- CScript result = CombineSignatures (pubKey2, txTo, nIn , txType2, vSolutions2, sigs1, sigs2);
246
+ CScript result = CombineSignatures (pubKey2, checker , txType2, vSolutions2, sigs1, sigs2);
237
247
result << spk;
238
248
return result;
239
249
}
240
250
case TX_MULTISIG:
241
- return CombineMultisig (scriptPubKey, txTo, nIn , vSolutions, sigs1, sigs2);
251
+ return CombineMultisig (scriptPubKey, checker , vSolutions, sigs1, sigs2);
242
252
}
243
253
244
254
return CScript ();
245
255
}
246
256
247
257
CScript CombineSignatures (const CScript& scriptPubKey, const CTransaction& txTo, unsigned int nIn,
248
258
const CScript& scriptSig1, const CScript& scriptSig2)
259
+ {
260
+ TransactionSignatureChecker checker (&txTo, nIn);
261
+ return CombineSignatures (scriptPubKey, checker, scriptSig1, scriptSig2);
262
+ }
263
+
264
+ CScript CombineSignatures (const CScript& scriptPubKey, const BaseSignatureChecker& checker,
265
+ const CScript& scriptSig1, const CScript& scriptSig2)
249
266
{
250
267
txnouttype txType;
251
268
vector<vector<unsigned char > > vSolutions;
@@ -256,5 +273,5 @@ CScript CombineSignatures(const CScript& scriptPubKey, const CTransaction& txTo,
256
273
vector<valtype> stack2;
257
274
EvalScript (stack2, scriptSig2, SCRIPT_VERIFY_STRICTENC, BaseSignatureChecker ());
258
275
259
- return CombineSignatures (scriptPubKey, txTo, nIn , txType, vSolutions, stack1, stack2);
276
+ return CombineSignatures (scriptPubKey, checker , txType, vSolutions, stack1, stack2);
260
277
}
0 commit comments