| 288 | } |
| 289 | |
| 290 | static void MutateTxAddOutPubKey(CMutableTransaction& tx, const std::string& strInput) |
| 291 | { |
| 292 | // Separate into VALUE:PUBKEY[:FLAGS] |
| 293 | std::vector<std::string> vStrInputParts; |
| 294 | boost::split(vStrInputParts, strInput, boost::is_any_of(":")); |
| 295 | |
| 296 | if (vStrInputParts.size() < 2 || vStrInputParts.size() > 3) |
| 297 | throw std::runtime_error("TX output missing or too many separators"); |
| 298 | |
| 299 | // Extract and validate VALUE |
| 300 | CAmount value = ExtractAndValidateValue(vStrInputParts[0]); |
| 301 | |
| 302 | // Extract and validate PUBKEY |
| 303 | CPubKey pubkey(ParseHex(vStrInputParts[1])); |
| 304 | if (!pubkey.IsFullyValid()) |
| 305 | throw std::runtime_error("invalid TX output pubkey"); |
| 306 | CScript scriptPubKey = GetScriptForRawPubKey(pubkey); |
| 307 | |
| 308 | // Extract and validate FLAGS |
| 309 | bool bSegWit = false; |
| 310 | bool bScriptHash = false; |
| 311 | if (vStrInputParts.size() == 3) { |
| 312 | std::string flags = vStrInputParts[2]; |
| 313 | bSegWit = (flags.find('W') != std::string::npos); |
| 314 | bScriptHash = (flags.find('S') != std::string::npos); |
| 315 | } |
| 316 | |
| 317 | if (bSegWit) { |
| 318 | if (!pubkey.IsCompressed()) { |
| 319 | throw std::runtime_error("Uncompressed pubkeys are not useable for SegWit outputs"); |
| 320 | } |
| 321 | // Call GetScriptForWitness() to build a P2WSH scriptPubKey |
| 322 | scriptPubKey = GetScriptForWitness(scriptPubKey); |
| 323 | } |
| 324 | if (bScriptHash) { |
| 325 | // Get the ID for the script, and then construct a P2SH destination for it. |
| 326 | scriptPubKey = GetScriptForDestination(CScriptID(scriptPubKey)); |
| 327 | } |
| 328 | |
| 329 | // construct TxOut, append to transaction output list |
| 330 | CTxOut txout(value, scriptPubKey); |
| 331 | tx.vout.push_back(txout); |
| 332 | } |
| 333 | |
| 334 | static void MutateTxAddOutMultiSig(CMutableTransaction& tx, const std::string& strInput) |
| 335 | { |
no test coverage detected