| 547 | } |
| 548 | |
| 549 | static void MutateTxSign(CMutableTransaction& tx, const std::string& flagStr) |
| 550 | { |
| 551 | int nHashType = SIGHASH_ALL | SIGHASH_FORKID; |
| 552 | |
| 553 | if (flagStr.size() > 0) |
| 554 | if (!findSighashFlags(nHashType, flagStr)) |
| 555 | throw std::runtime_error("unknown sighash flag/sign option"); |
| 556 | |
| 557 | // mergedTx will end up with all the signatures; it |
| 558 | // starts as a clone of the raw tx: |
| 559 | CMutableTransaction mergedTx{tx}; |
| 560 | const CMutableTransaction txv{tx}; |
| 561 | CCoinsView viewDummy; |
| 562 | CCoinsViewCache view(&viewDummy); |
| 563 | |
| 564 | if (!registers.count("privatekeys")) |
| 565 | throw std::runtime_error("privatekeys register variable must be set."); |
| 566 | CBasicKeyStore tempKeystore; |
| 567 | UniValue keysObj = registers["privatekeys"]; |
| 568 | |
| 569 | for (unsigned int kidx = 0; kidx < keysObj.size(); kidx++) { |
| 570 | if (!keysObj[kidx].isStr()) |
| 571 | throw std::runtime_error("privatekey not a std::string"); |
| 572 | CKey key = DecodeSecret(keysObj[kidx].getValStr()); |
| 573 | if (!key.IsValid()) { |
| 574 | throw std::runtime_error("privatekey not valid"); |
| 575 | } |
| 576 | tempKeystore.AddKey(key); |
| 577 | } |
| 578 | |
| 579 | // Add previous txouts given in the RPC call: |
| 580 | if (!registers.count("prevtxs")) |
| 581 | throw std::runtime_error("prevtxs register variable must be set."); |
| 582 | UniValue prevtxsObj = registers["prevtxs"]; |
| 583 | { |
| 584 | for (unsigned int previdx = 0; previdx < prevtxsObj.size(); previdx++) { |
| 585 | UniValue prevOut = prevtxsObj[previdx]; |
| 586 | if (!prevOut.isObject()) |
| 587 | throw std::runtime_error("expected prevtxs internal object"); |
| 588 | |
| 589 | std::map<std::string, UniValue::VType> types = { |
| 590 | {"txid", UniValue::VSTR}, |
| 591 | {"vout", UniValue::VNUM}, |
| 592 | {"scriptPubKey", UniValue::VSTR}, |
| 593 | }; |
| 594 | if (!prevOut.checkObject(types)) |
| 595 | throw std::runtime_error("prevtxs internal object typecheck fail"); |
| 596 | |
| 597 | uint256 txid = ParseHashStr(prevOut["txid"].get_str(), "txid"); |
| 598 | |
| 599 | const int nOut = prevOut["vout"].get_int(); |
| 600 | if (nOut < 0) |
| 601 | throw std::runtime_error("vout must be positive"); |
| 602 | |
| 603 | COutPoint out(txid, nOut); |
| 604 | std::vector<unsigned char> pkData(ParseHexUV(prevOut["scriptPubKey"], "scriptPubKey")); |
| 605 | CScript scriptPubKey(pkData.begin(), pkData.end()); |
| 606 |
no test coverage detected