@@ -40,12 +40,21 @@ static constexpr uint8_t PSBT_IN_RIPEMD160 = 0x0A;
40
40
static constexpr uint8_t PSBT_IN_SHA256 = 0x0B ;
41
41
static constexpr uint8_t PSBT_IN_HASH160 = 0x0C ;
42
42
static constexpr uint8_t PSBT_IN_HASH256 = 0x0D ;
43
+ static constexpr uint8_t PSBT_IN_TAP_KEY_SIG = 0x13 ;
44
+ static constexpr uint8_t PSBT_IN_TAP_SCRIPT_SIG = 0x14 ;
45
+ static constexpr uint8_t PSBT_IN_TAP_LEAF_SCRIPT = 0x15 ;
46
+ static constexpr uint8_t PSBT_IN_TAP_BIP32_DERIVATION = 0x16 ;
47
+ static constexpr uint8_t PSBT_IN_TAP_INTERNAL_KEY = 0x17 ;
48
+ static constexpr uint8_t PSBT_IN_TAP_MERKLE_ROOT = 0x18 ;
43
49
static constexpr uint8_t PSBT_IN_PROPRIETARY = 0xFC ;
44
50
45
51
// Output types
46
52
static constexpr uint8_t PSBT_OUT_REDEEMSCRIPT = 0x00 ;
47
53
static constexpr uint8_t PSBT_OUT_WITNESSSCRIPT = 0x01 ;
48
54
static constexpr uint8_t PSBT_OUT_BIP32_DERIVATION = 0x02 ;
55
+ static constexpr uint8_t PSBT_OUT_TAP_INTERNAL_KEY = 0x05 ;
56
+ static constexpr uint8_t PSBT_OUT_TAP_TREE = 0x06 ;
57
+ static constexpr uint8_t PSBT_OUT_TAP_BIP32_DERIVATION = 0x07 ;
49
58
static constexpr uint8_t PSBT_OUT_PROPRIETARY = 0xFC ;
50
59
51
60
// The separator is 0x00. Reading this in means that the unserializer can interpret it
@@ -193,6 +202,15 @@ struct PSBTInput
193
202
std::map<uint256, std::vector<unsigned char >> sha256_preimages;
194
203
std::map<uint160, std::vector<unsigned char >> hash160_preimages;
195
204
std::map<uint256, std::vector<unsigned char >> hash256_preimages;
205
+
206
+ // Taproot fields
207
+ std::vector<unsigned char > m_tap_key_sig;
208
+ std::map<std::pair<XOnlyPubKey, uint256>, std::vector<unsigned char >> m_tap_script_sigs;
209
+ std::map<std::pair<CScript, int >, std::set<std::vector<unsigned char >, ShortestVectorFirstComparator>> m_tap_scripts;
210
+ std::map<XOnlyPubKey, std::pair<std::set<uint256>, KeyOriginInfo>> m_tap_bip32_paths;
211
+ XOnlyPubKey m_tap_internal_key;
212
+ uint256 m_tap_merkle_root;
213
+
196
214
std::map<std::vector<unsigned char >, std::vector<unsigned char >> unknown;
197
215
std::set<PSBTProprietary> m_proprietary;
198
216
std::optional<int > sighash_type;
@@ -267,6 +285,53 @@ struct PSBTInput
267
285
SerializeToVector (s, CompactSizeWriter (PSBT_IN_HASH256), Span{hash});
268
286
s << preimage;
269
287
}
288
+
289
+ // Write taproot key sig
290
+ if (!m_tap_key_sig.empty ()) {
291
+ SerializeToVector (s, PSBT_IN_TAP_KEY_SIG);
292
+ s << m_tap_key_sig;
293
+ }
294
+
295
+ // Write taproot script sigs
296
+ for (const auto & [pubkey_leaf, sig] : m_tap_script_sigs) {
297
+ const auto & [xonly, leaf_hash] = pubkey_leaf;
298
+ SerializeToVector (s, PSBT_IN_TAP_SCRIPT_SIG, xonly, leaf_hash);
299
+ s << sig;
300
+ }
301
+
302
+ // Write taproot leaf scripts
303
+ for (const auto & [leaf, control_blocks] : m_tap_scripts) {
304
+ const auto & [script, leaf_ver] = leaf;
305
+ for (const auto & control_block : control_blocks) {
306
+ SerializeToVector (s, PSBT_IN_TAP_LEAF_SCRIPT, Span{control_block});
307
+ std::vector<unsigned char > value_v (script.begin (), script.end ());
308
+ value_v.push_back ((uint8_t )leaf_ver);
309
+ s << value_v;
310
+ }
311
+ }
312
+
313
+ // Write taproot bip32 keypaths
314
+ for (const auto & [xonly, leaf_origin] : m_tap_bip32_paths) {
315
+ const auto & [leaf_hashes, origin] = leaf_origin;
316
+ SerializeToVector (s, PSBT_IN_TAP_BIP32_DERIVATION, xonly);
317
+ std::vector<unsigned char > value;
318
+ CVectorWriter s_value (s.GetType (), s.GetVersion (), value, 0 );
319
+ s_value << leaf_hashes;
320
+ SerializeKeyOrigin (s_value, origin);
321
+ s << value;
322
+ }
323
+
324
+ // Write taproot internal key
325
+ if (!m_tap_internal_key.IsNull ()) {
326
+ SerializeToVector (s, PSBT_IN_TAP_INTERNAL_KEY);
327
+ s << ToByteVector (m_tap_internal_key);
328
+ }
329
+
330
+ // Write taproot merkle root
331
+ if (!m_tap_merkle_root.IsNull ()) {
332
+ SerializeToVector (s, PSBT_IN_TAP_MERKLE_ROOT);
333
+ SerializeToVector (s, m_tap_merkle_root);
334
+ }
270
335
}
271
336
272
337
// Write script sig
@@ -503,6 +568,103 @@ struct PSBTInput
503
568
hash256_preimages.emplace (hash, std::move (preimage));
504
569
break ;
505
570
}
571
+ case PSBT_IN_TAP_KEY_SIG:
572
+ {
573
+ if (!key_lookup.emplace (key).second ) {
574
+ throw std::ios_base::failure (" Duplicate Key, input Taproot key signature already provided" );
575
+ } else if (key.size () != 1 ) {
576
+ throw std::ios_base::failure (" Input Taproot key signature key is more than one byte type" );
577
+ }
578
+ s >> m_tap_key_sig;
579
+ if (m_tap_key_sig.size () < 64 ) {
580
+ throw std::ios_base::failure (" Input Taproot key path signature is shorter than 64 bytes" );
581
+ } else if (m_tap_key_sig.size () > 65 ) {
582
+ throw std::ios_base::failure (" Input Taproot key path signature is longer than 65 bytes" );
583
+ }
584
+ break ;
585
+ }
586
+ case PSBT_IN_TAP_SCRIPT_SIG:
587
+ {
588
+ if (!key_lookup.emplace (key).second ) {
589
+ throw std::ios_base::failure (" Duplicate Key, input Taproot script signature already provided" );
590
+ } else if (key.size () != 65 ) {
591
+ throw std::ios_base::failure (" Input Taproot script signature key is not 65 bytes" );
592
+ }
593
+ SpanReader s_key (s.GetType (), s.GetVersion (), Span{key}.subspan (1 ));
594
+ XOnlyPubKey xonly;
595
+ uint256 hash;
596
+ s_key >> xonly;
597
+ s_key >> hash;
598
+ std::vector<unsigned char > sig;
599
+ s >> sig;
600
+ if (sig.size () < 64 ) {
601
+ throw std::ios_base::failure (" Input Taproot script path signature is shorter than 64 bytes" );
602
+ } else if (sig.size () > 65 ) {
603
+ throw std::ios_base::failure (" Input Taproot script path signature is longer than 65 bytes" );
604
+ }
605
+ m_tap_script_sigs.emplace (std::make_pair (xonly, hash), sig);
606
+ break ;
607
+ }
608
+ case PSBT_IN_TAP_LEAF_SCRIPT:
609
+ {
610
+ if (!key_lookup.emplace (key).second ) {
611
+ throw std::ios_base::failure (" Duplicate Key, input Taproot leaf script already provided" );
612
+ } else if (key.size () < 34 ) {
613
+ throw std::ios_base::failure (" Taproot leaf script key is not at least 34 bytes" );
614
+ } else if ((key.size () - 2 ) % 32 != 0 ) {
615
+ throw std::ios_base::failure (" Input Taproot leaf script key's control block size is not valid" );
616
+ }
617
+ std::vector<unsigned char > script_v;
618
+ s >> script_v;
619
+ if (script_v.empty ()) {
620
+ throw std::ios_base::failure (" Input Taproot leaf script must be at least 1 byte" );
621
+ }
622
+ uint8_t leaf_ver = script_v.back ();
623
+ script_v.pop_back ();
624
+ const auto leaf_script = std::make_pair (CScript (script_v.begin (), script_v.end ()), (int )leaf_ver);
625
+ m_tap_scripts[leaf_script].insert (std::vector<unsigned char >(key.begin () + 1 , key.end ()));
626
+ break ;
627
+ }
628
+ case PSBT_IN_TAP_BIP32_DERIVATION:
629
+ {
630
+ if (!key_lookup.emplace (key).second ) {
631
+ throw std::ios_base::failure (" Duplicate Key, input Taproot BIP32 keypath already provided" );
632
+ } else if (key.size () != 33 ) {
633
+ throw std::ios_base::failure (" Input Taproot BIP32 keypath key is not at 33 bytes" );
634
+ }
635
+ SpanReader s_key (s.GetType (), s.GetVersion (), Span{key}.subspan (1 ));
636
+ XOnlyPubKey xonly;
637
+ s_key >> xonly;
638
+ std::set<uint256> leaf_hashes;
639
+ uint64_t value_len = ReadCompactSize (s);
640
+ size_t before_hashes = s.size ();
641
+ s >> leaf_hashes;
642
+ size_t after_hashes = s.size ();
643
+ size_t hashes_len = before_hashes - after_hashes;
644
+ size_t origin_len = value_len - hashes_len;
645
+ m_tap_bip32_paths.emplace (xonly, std::make_pair (leaf_hashes, DeserializeKeyOrigin (s, origin_len)));
646
+ break ;
647
+ }
648
+ case PSBT_IN_TAP_INTERNAL_KEY:
649
+ {
650
+ if (!key_lookup.emplace (key).second ) {
651
+ throw std::ios_base::failure (" Duplicate Key, input Taproot internal key already provided" );
652
+ } else if (key.size () != 1 ) {
653
+ throw std::ios_base::failure (" Input Taproot internal key key is more than one byte type" );
654
+ }
655
+ UnserializeFromVector (s, m_tap_internal_key);
656
+ break ;
657
+ }
658
+ case PSBT_IN_TAP_MERKLE_ROOT:
659
+ {
660
+ if (!key_lookup.emplace (key).second ) {
661
+ throw std::ios_base::failure (" Duplicate Key, input Taproot merkle root already provided" );
662
+ } else if (key.size () != 1 ) {
663
+ throw std::ios_base::failure (" Input Taproot merkle root key is more than one byte type" );
664
+ }
665
+ UnserializeFromVector (s, m_tap_merkle_root);
666
+ break ;
667
+ }
506
668
case PSBT_IN_PROPRIETARY:
507
669
{
508
670
PSBTProprietary this_prop;
@@ -547,6 +709,9 @@ struct PSBTOutput
547
709
CScript redeem_script;
548
710
CScript witness_script;
549
711
std::map<CPubKey, KeyOriginInfo> hd_keypaths;
712
+ XOnlyPubKey m_tap_internal_key;
713
+ std::optional<TaprootBuilder> m_tap_tree;
714
+ std::map<XOnlyPubKey, std::pair<std::set<uint256>, KeyOriginInfo>> m_tap_bip32_paths;
550
715
std::map<std::vector<unsigned char >, std::vector<unsigned char >> unknown;
551
716
std::set<PSBTProprietary> m_proprietary;
552
717
@@ -579,6 +744,40 @@ struct PSBTOutput
579
744
s << entry.value ;
580
745
}
581
746
747
+ // Write taproot internal key
748
+ if (!m_tap_internal_key.IsNull ()) {
749
+ SerializeToVector (s, PSBT_OUT_TAP_INTERNAL_KEY);
750
+ s << ToByteVector (m_tap_internal_key);
751
+ }
752
+
753
+ // Write taproot tree
754
+ if (m_tap_tree.has_value ()) {
755
+ SerializeToVector (s, PSBT_OUT_TAP_TREE);
756
+ std::vector<unsigned char > value;
757
+ CVectorWriter s_value (s.GetType (), s.GetVersion (), value, 0 );
758
+ const auto & tuples = m_tap_tree->GetTreeTuples ();
759
+ for (const auto & tuple : tuples) {
760
+ uint8_t depth = std::get<0 >(tuple);
761
+ uint8_t leaf_ver = std::get<1 >(tuple);
762
+ CScript script = std::get<2 >(tuple);
763
+ s_value << depth;
764
+ s_value << leaf_ver;
765
+ s_value << script;
766
+ }
767
+ s << value;
768
+ }
769
+
770
+ // Write taproot bip32 keypaths
771
+ for (const auto & [xonly, leaf] : m_tap_bip32_paths) {
772
+ const auto & [leaf_hashes, origin] = leaf;
773
+ SerializeToVector (s, PSBT_OUT_TAP_BIP32_DERIVATION, xonly);
774
+ std::vector<unsigned char > value;
775
+ CVectorWriter s_value (s.GetType (), s.GetVersion (), value, 0 );
776
+ s_value << leaf_hashes;
777
+ SerializeKeyOrigin (s_value, origin);
778
+ s << value;
779
+ }
780
+
582
781
// Write unknown things
583
782
for (auto & entry : unknown) {
584
783
s << entry.first ;
@@ -639,6 +838,59 @@ struct PSBTOutput
639
838
DeserializeHDKeypaths (s, key, hd_keypaths);
640
839
break ;
641
840
}
841
+ case PSBT_OUT_TAP_INTERNAL_KEY:
842
+ {
843
+ if (!key_lookup.emplace (key).second ) {
844
+ throw std::ios_base::failure (" Duplicate Key, output Taproot internal key already provided" );
845
+ } else if (key.size () != 1 ) {
846
+ throw std::ios_base::failure (" Output Taproot internal key key is more than one byte type" );
847
+ }
848
+ UnserializeFromVector (s, m_tap_internal_key);
849
+ break ;
850
+ }
851
+ case PSBT_OUT_TAP_TREE:
852
+ {
853
+ if (!key_lookup.emplace (key).second ) {
854
+ throw std::ios_base::failure (" Duplicate Key, output Taproot tree already provided" );
855
+ } else if (key.size () != 1 ) {
856
+ throw std::ios_base::failure (" Output Taproot tree key is more than one byte type" );
857
+ }
858
+ m_tap_tree.emplace ();
859
+ std::vector<unsigned char > tree_v;
860
+ s >> tree_v;
861
+ SpanReader s_tree (s.GetType (), s.GetVersion (), tree_v);
862
+ while (!s_tree.empty ()) {
863
+ uint8_t depth;
864
+ uint8_t leaf_ver;
865
+ CScript script;
866
+ s_tree >> depth;
867
+ s_tree >> leaf_ver;
868
+ s_tree >> script;
869
+ m_tap_tree->Add ((int )depth, script, (int )leaf_ver, true /* track */ );
870
+ }
871
+ if (!m_tap_tree->IsComplete ()) {
872
+ throw std::ios_base::failure (" Output Taproot tree is malformed" );
873
+ }
874
+ break ;
875
+ }
876
+ case PSBT_OUT_TAP_BIP32_DERIVATION:
877
+ {
878
+ if (!key_lookup.emplace (key).second ) {
879
+ throw std::ios_base::failure (" Duplicate Key, output Taproot BIP32 keypath already provided" );
880
+ } else if (key.size () != 33 ) {
881
+ throw std::ios_base::failure (" Output Taproot BIP32 keypath key is not at 33 bytes" );
882
+ }
883
+ XOnlyPubKey xonly (uint256 ({key.begin () + 1 , key.begin () + 33 }));
884
+ std::set<uint256> leaf_hashes;
885
+ uint64_t value_len = ReadCompactSize (s);
886
+ size_t before_hashes = s.size ();
887
+ s >> leaf_hashes;
888
+ size_t after_hashes = s.size ();
889
+ size_t hashes_len = before_hashes - after_hashes;
890
+ size_t origin_len = value_len - hashes_len;
891
+ m_tap_bip32_paths.emplace (xonly, std::make_pair (leaf_hashes, DeserializeKeyOrigin (s, origin_len)));
892
+ break ;
893
+ }
642
894
case PSBT_OUT_PROPRIETARY:
643
895
{
644
896
PSBTProprietary this_prop;
@@ -667,6 +919,11 @@ struct PSBTOutput
667
919
}
668
920
}
669
921
922
+ // Finalize m_tap_tree so that all of the computed things are computed
923
+ if (m_tap_tree.has_value () && m_tap_tree->IsComplete () && m_tap_internal_key.IsFullyValid ()) {
924
+ m_tap_tree->Finalize (m_tap_internal_key);
925
+ }
926
+
670
927
if (!found_sep) {
671
928
throw std::ios_base::failure (" Separator is missing at the end of an output map" );
672
929
}
0 commit comments