| 472 | WitnessV1Taproot TaprootBuilder::GetOutput() { return WitnessV1Taproot{m_output_key}; } |
| 473 | |
| 474 | TaprootSpendData TaprootBuilder::GetSpendData() const |
| 475 | { |
| 476 | assert(IsComplete()); |
| 477 | assert(m_output_key.IsFullyValid()); |
| 478 | TaprootSpendData spd; |
| 479 | spd.merkle_root = m_branch.size() == 0 ? uint256() : m_branch[0]->hash; |
| 480 | spd.internal_key = m_internal_key; |
| 481 | if (m_branch.size()) { |
| 482 | // If any script paths exist, they have been combined into the root m_branch[0] |
| 483 | // by now. Compute the control block for each of its tracked leaves, and put them in |
| 484 | // spd.scripts. |
| 485 | for (const auto& leaf : m_branch[0]->leaves) { |
| 486 | std::vector<unsigned char> control_block; |
| 487 | control_block.resize(TAPROOT_CONTROL_BASE_SIZE + TAPROOT_CONTROL_NODE_SIZE * leaf.merkle_branch.size()); |
| 488 | control_block[0] = leaf.leaf_version | (m_parity ? 1 : 0); |
| 489 | std::copy(m_internal_key.begin(), m_internal_key.end(), control_block.begin() + 1); |
| 490 | if (leaf.merkle_branch.size()) { |
| 491 | std::copy(leaf.merkle_branch[0].begin(), |
| 492 | leaf.merkle_branch[0].begin() + TAPROOT_CONTROL_NODE_SIZE * leaf.merkle_branch.size(), |
| 493 | control_block.begin() + TAPROOT_CONTROL_BASE_SIZE); |
| 494 | } |
| 495 | spd.scripts[{leaf.script, leaf.leaf_version}].insert(std::move(control_block)); |
| 496 | } |
| 497 | } |
| 498 | return spd; |
| 499 | } |
| 500 | |
| 501 | std::optional<std::vector<std::tuple<int, std::vector<unsigned char>, int>>> InferTaprootTree(const TaprootSpendData& spenddata, const XOnlyPubKey& output) |
| 502 | { |