|
|
@ -1058,35 +1058,64 @@ UniValue signrawtransaction(const UniValue& params, bool fHelp) |
|
|
|
|
|
|
|
// Use CTransaction for the constant parts of the
|
|
|
|
// transaction to avoid rehashing.
|
|
|
|
CMutableTransaction mergedTxsave = mergedTx; |
|
|
|
int32_t txpow,numiters = 0; |
|
|
|
const CTransaction txConst(mergedTx); |
|
|
|
// Sign what we can:
|
|
|
|
for (unsigned int i = 0; i < mergedTx.vin.size(); i++) { |
|
|
|
CTxIn& txin = mergedTx.vin[i]; |
|
|
|
const CCoins* coins = view.AccessCoins(txin.prevout.hash); |
|
|
|
if (coins == NULL || !coins->IsAvailable(txin.prevout.n)) { |
|
|
|
TxInErrorToJSON(txin, vErrors, "Input not found or already spent"); |
|
|
|
continue; |
|
|
|
if ( (txpow= ASSETCHAINS_TXPOW) != 0 ) |
|
|
|
{ |
|
|
|
if ( txConst.IsCoinBase() != 0 ) |
|
|
|
{ |
|
|
|
if ( (txpow & 2) == 0 ) |
|
|
|
txpow == 0; |
|
|
|
} |
|
|
|
const CScript& prevPubKey = coins->vout[txin.prevout.n].scriptPubKey; |
|
|
|
const CAmount& amount = coins->vout[txin.prevout.n].nValue; |
|
|
|
|
|
|
|
SignatureData sigdata; |
|
|
|
// Only sign SIGHASH_SINGLE if there's a corresponding output:
|
|
|
|
if (!fHashSingle || (i < mergedTx.vout.size())) |
|
|
|
ProduceSignature(MutableTransactionSignatureCreator(&keystore, &mergedTx, i, amount, nHashType), prevPubKey, sigdata, consensusBranchId); |
|
|
|
|
|
|
|
// ... and merge in other signatures:
|
|
|
|
BOOST_FOREACH(const CMutableTransaction& txv, txVariants) { |
|
|
|
sigdata = CombineSignatures(prevPubKey, TransactionSignatureChecker(&txConst, i, amount), sigdata, DataFromTransaction(txv, i), consensusBranchId); |
|
|
|
else |
|
|
|
{ |
|
|
|
if ( (txpow & 1) == 0 ) |
|
|
|
txpow == 0; |
|
|
|
} |
|
|
|
|
|
|
|
UpdateTransaction(mergedTx, i, sigdata); |
|
|
|
|
|
|
|
ScriptError serror = SCRIPT_ERR_OK; |
|
|
|
if (!VerifyScript(txin.scriptSig, prevPubKey, STANDARD_SCRIPT_VERIFY_FLAGS, TransactionSignatureChecker(&txConst, i, amount), consensusBranchId, &serror)) { |
|
|
|
TxInErrorToJSON(txin, vErrors, ScriptErrorString(serror)); |
|
|
|
} |
|
|
|
while ( 1 ) |
|
|
|
{ |
|
|
|
if ( txpow != 0 ) |
|
|
|
mergedTx = mergedTxsave; |
|
|
|
// Sign what we can:
|
|
|
|
for (unsigned int i = 0; i < mergedTx.vin.size(); i++) { |
|
|
|
CTxIn& txin = mergedTx.vin[i]; |
|
|
|
const CCoins* coins = view.AccessCoins(txin.prevout.hash); |
|
|
|
if (coins == NULL || !coins->IsAvailable(txin.prevout.n)) { |
|
|
|
TxInErrorToJSON(txin, vErrors, "Input not found or already spent"); |
|
|
|
continue; |
|
|
|
} |
|
|
|
const CScript& prevPubKey = coins->vout[txin.prevout.n].scriptPubKey; |
|
|
|
const CAmount& amount = coins->vout[txin.prevout.n].nValue; |
|
|
|
|
|
|
|
SignatureData sigdata; |
|
|
|
// Only sign SIGHASH_SINGLE if there's a corresponding output:
|
|
|
|
if (!fHashSingle || (i < mergedTx.vout.size())) |
|
|
|
ProduceSignature(MutableTransactionSignatureCreator(&keystore, &mergedTx, i, amount, nHashType), prevPubKey, sigdata, consensusBranchId); |
|
|
|
|
|
|
|
// ... and merge in other signatures:
|
|
|
|
BOOST_FOREACH(const CMutableTransaction& txv, txVariants) { |
|
|
|
sigdata = CombineSignatures(prevPubKey, TransactionSignatureChecker(&txConst, i, amount), sigdata, DataFromTransaction(txv, i), consensusBranchId); |
|
|
|
} |
|
|
|
|
|
|
|
UpdateTransaction(mergedTx, i, sigdata); |
|
|
|
|
|
|
|
ScriptError serror = SCRIPT_ERR_OK; |
|
|
|
if (!VerifyScript(txin.scriptSig, prevPubKey, STANDARD_SCRIPT_VERIFY_FLAGS, TransactionSignatureChecker(&txConst, i, amount), consensusBranchId, &serror)) { |
|
|
|
TxInErrorToJSON(txin, vErrors, ScriptErrorString(serror)); |
|
|
|
} |
|
|
|
} |
|
|
|
if ( txpow != 0 ) |
|
|
|
{ |
|
|
|
uint256 txid = mergedTx.GetHash(); |
|
|
|
if ( ((uint8_t *)&txid)[0] == 0 && ((uint8_t *)&txid)[31] == 0 ) |
|
|
|
break; |
|
|
|
} |
|
|
|
numiters++; |
|
|
|
} |
|
|
|
if ( numiters > 0 ) |
|
|
|
fprintf(stderr,"ASSETCHAINS_TXPOW.%d txpow.%d numiters.%d for signature\n",ASSETCHAINS_TXPOW,txpow,numiters); |
|
|
|
bool fComplete = vErrors.empty(); |
|
|
|
|
|
|
|
UniValue result(UniValue::VOBJ); |
|
|
|