| 1597 | |
| 1598 | template <typename Stream> |
| 1599 | inline void Serialize(Stream& s) const { |
| 1600 | |
| 1601 | // magic bytes |
| 1602 | s << PSBT_ELEMENTS_MAGIC_BYTES; |
| 1603 | |
| 1604 | if (GetVersion() == 0) { |
| 1605 | // unsigned tx flag |
| 1606 | SerializeToVector(s, CompactSizeWriter(PSBT_GLOBAL_UNSIGNED_TX)); |
| 1607 | |
| 1608 | // Write serialized tx to a stream |
| 1609 | OverrideStream<Stream> os(&s, s.GetType(), s.GetVersion() | SERIALIZE_TRANSACTION_NO_WITNESS); |
| 1610 | SerializeToVector(os, GetUnsignedTx()); |
| 1611 | } |
| 1612 | |
| 1613 | // Write xpubs |
| 1614 | for (const auto& xpub_pair : m_xpubs) { |
| 1615 | for (const auto& xpub : xpub_pair.second) { |
| 1616 | unsigned char ser_xpub[BIP32_EXTKEY_WITH_VERSION_SIZE]; |
| 1617 | xpub.EncodeWithVersion(ser_xpub); |
| 1618 | // Note that the serialization swaps the key and value |
| 1619 | // The xpub is the key (for uniqueness) while the path is the value |
| 1620 | SerializeToVector(s, PSBT_GLOBAL_XPUB, ser_xpub); |
| 1621 | SerializeHDKeypath(s, xpub_pair.first); |
| 1622 | } |
| 1623 | } |
| 1624 | |
| 1625 | if (GetVersion() >= 2) { |
| 1626 | // Write PSBTv2 tx version, locktime, counts, etc. |
| 1627 | SerializeToVector(s, CompactSizeWriter(PSBT_GLOBAL_TX_VERSION)); |
| 1628 | SerializeToVector(s, *tx_version); |
| 1629 | |
| 1630 | if (fallback_locktime != std::nullopt) { |
| 1631 | SerializeToVector(s, CompactSizeWriter(PSBT_GLOBAL_FALLBACK_LOCKTIME)); |
| 1632 | SerializeToVector(s, *fallback_locktime); |
| 1633 | } |
| 1634 | |
| 1635 | SerializeToVector(s, CompactSizeWriter(PSBT_GLOBAL_INPUT_COUNT)); |
| 1636 | SerializeToVector(s, CompactSizeWriter(inputs.size())); |
| 1637 | SerializeToVector(s, CompactSizeWriter(PSBT_GLOBAL_OUTPUT_COUNT)); |
| 1638 | SerializeToVector(s, CompactSizeWriter(outputs.size())); |
| 1639 | |
| 1640 | if (m_tx_modifiable != std::nullopt) { |
| 1641 | SerializeToVector(s, CompactSizeWriter(PSBT_GLOBAL_TX_MODIFIABLE)); |
| 1642 | SerializeToVector(s, static_cast<uint8_t>(m_tx_modifiable->to_ulong())); |
| 1643 | } |
| 1644 | |
| 1645 | // Elements proprietary fields |
| 1646 | // Scalar offsets |
| 1647 | for (const uint256& scalar : m_scalar_offsets) { |
| 1648 | SerializeToVector(s, CompactSizeWriter(PSBT_GLOBAL_PROPRIETARY), PSBT_ELEMENTS_ID, CompactSizeWriter(PSBT_ELEMENTS_GLOBAL_SCALAR), scalar); |
| 1649 | s << PSBT_SEPARATOR; /* Zero length data value */ |
| 1650 | } |
| 1651 | } |
| 1652 | |
| 1653 | // PSBT version |
| 1654 | if (GetVersion() > 0) { |
| 1655 | SerializeToVector(s, CompactSizeWriter(PSBT_GLOBAL_VERSION)); |
| 1656 | SerializeToVector(s, *m_version); |
nothing calls this directly
no test coverage detected