| 438 | } |
| 439 | |
| 440 | static RPCMethod decodescript() |
| 441 | { |
| 442 | return RPCMethod{ |
| 443 | "decodescript", |
| 444 | "Decode a hex-encoded script.\n", |
| 445 | { |
| 446 | {"hexstring", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "the hex-encoded script"}, |
| 447 | }, |
| 448 | RPCResult{ |
| 449 | RPCResult::Type::OBJ, "", "", |
| 450 | { |
| 451 | {RPCResult::Type::STR, "asm", "Disassembly of the script"}, |
| 452 | {RPCResult::Type::STR, "desc", "Inferred descriptor for the script"}, |
| 453 | {RPCResult::Type::STR, "type", "The output type (e.g. " + GetAllOutputTypes() + ")"}, |
| 454 | {RPCResult::Type::STR, "address", /*optional=*/true, "The Bitcoin address (only if a well-defined address exists)"}, |
| 455 | {RPCResult::Type::STR, "p2sh", /*optional=*/true, |
| 456 | "address of P2SH script wrapping this redeem script (not returned for types that should not be wrapped)"}, |
| 457 | {RPCResult::Type::OBJ, "segwit", /*optional=*/true, |
| 458 | "Result of a witness output script wrapping this redeem script (not returned for types that should not be wrapped)", |
| 459 | { |
| 460 | {RPCResult::Type::STR, "asm", "Disassembly of the output script"}, |
| 461 | {RPCResult::Type::STR_HEX, "hex", "The raw output script bytes, hex-encoded"}, |
| 462 | {RPCResult::Type::STR, "type", "The type of the output script (e.g. witness_v0_keyhash or witness_v0_scripthash)"}, |
| 463 | {RPCResult::Type::STR, "address", /*optional=*/true, "The Bitcoin address (only if a well-defined address exists)"}, |
| 464 | {RPCResult::Type::STR, "desc", "Inferred descriptor for the script"}, |
| 465 | {RPCResult::Type::STR, "p2sh-segwit", "address of the P2SH script wrapping this witness redeem script"}, |
| 466 | }}, |
| 467 | }, |
| 468 | }, |
| 469 | RPCExamples{ |
| 470 | HelpExampleCli("decodescript", "\"hexstring\"") |
| 471 | + HelpExampleRpc("decodescript", "\"hexstring\"") |
| 472 | }, |
| 473 | [](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue |
| 474 | { |
| 475 | UniValue r(UniValue::VOBJ); |
| 476 | CScript script; |
| 477 | if (request.params[0].get_str().size() > 0){ |
| 478 | std::vector<unsigned char> scriptData(ParseHexV(request.params[0], "argument")); |
| 479 | script = CScript(scriptData.begin(), scriptData.end()); |
| 480 | } else { |
| 481 | // Empty scripts are valid |
| 482 | } |
| 483 | ScriptToUniv(script, /*out=*/r, /*include_hex=*/false, /*include_address=*/true); |
| 484 | |
| 485 | std::vector<std::vector<unsigned char>> solutions_data; |
| 486 | const TxoutType which_type{Solver(script, solutions_data)}; |
| 487 | |
| 488 | const bool can_wrap{[&] { |
| 489 | switch (which_type) { |
| 490 | case TxoutType::MULTISIG: |
| 491 | case TxoutType::NONSTANDARD: |
| 492 | case TxoutType::PUBKEY: |
| 493 | case TxoutType::PUBKEYHASH: |
| 494 | case TxoutType::WITNESS_V0_KEYHASH: |
| 495 | case TxoutType::WITNESS_V0_SCRIPTHASH: |
| 496 | // Can be wrapped if the checks below pass |
| 497 | break; |
nothing calls this directly
no test coverage detected