@@ -108,6 +108,50 @@ const (
108
108
EncodeSegwit
109
109
)
110
110
111
+ // ScriptKeyType denotes the type of script key used for an asset. This type is
112
+ // serialized to the database, so we don't use iota for the values to ensure
113
+ // they don't change by accident.
114
+ type ScriptKeyType uint8
115
+
116
+ const (
117
+ // ScriptKeyUnknown is the default script key type used for assets that
118
+ // we don't know the type of. This should only be stored for assets
119
+ // where we don't know the internal key of the script key (e.g. for
120
+ // imported proofs).
121
+ ScriptKeyUnknown ScriptKeyType = 0
122
+
123
+ // ScriptKeyBip86 is the script key type used for assets that use the
124
+ // BIP86 style tweak (e.g. an empty tweak).
125
+ ScriptKeyBip86 ScriptKeyType = 1
126
+
127
+ // ScriptKeyScriptPathExternal is the script key type used for assets
128
+ // that use a script path that is defined by an external application.
129
+ // Keys with script paths are normally not shown in asset balances and
130
+ // by default aren't used for coin selection unless specifically
131
+ // requested.
132
+ ScriptKeyScriptPathExternal ScriptKeyType = 2
133
+
134
+ // ScriptKeyBurn is the script key type used for assets that are burned
135
+ // and not spendable.
136
+ ScriptKeyBurn ScriptKeyType = 3
137
+
138
+ // ScriptKeyTombstone is the script key type used for assets that are
139
+ // not spendable and have been marked as tombstones. This is only the
140
+ // case for zero-value assets that result from a non-interactive (TAP
141
+ // address) send where no change was left over. The script key used for
142
+ // this is a NUMS key that is not spendable.
143
+ ScriptKeyTombstone ScriptKeyType = 4
144
+
145
+ // ScriptKeyScriptPathChannel is the script key type used for assets
146
+ // that use a script path that is somehow related to Taproot Asset
147
+ // Channels. That means the script key is either a funding key
148
+ // (OP_TRUE), a commitment output key (to_local, to_remote, htlc), or a
149
+ // HTLC second-level transaction output key.
150
+ // Keys related to channels are not shown in asset balances (unless
151
+ // specifically requested) and are _never_ used for coin selection.
152
+ ScriptKeyScriptPathChannel ScriptKeyType = 5
153
+ )
154
+
111
155
var (
112
156
// ZeroPrevID is the blank prev ID used for genesis assets and also
113
157
// asset split leaves.
@@ -1005,14 +1049,8 @@ type TweakedScriptKey struct {
1005
1049
// public key. If this is nil, then a BIP-0086 tweak is assumed.
1006
1050
Tweak []byte
1007
1051
1008
- // DeclaredKnown indicates that this script key has been explicitly
1009
- // declared as being important to the local wallet, even if it might not
1010
- // be fully known to the local wallet. This could perhaps also be named
1011
- // "imported", though that might imply that the corresponding private
1012
- // key was also somehow imported and available. The only relevance this
1013
- // flag has is that assets with a declared key are shown in the asset
1014
- // list/balance.
1015
- DeclaredKnown bool
1052
+ // Type is the type of script key that is being used.
1053
+ Type ScriptKeyType
1016
1054
}
1017
1055
1018
1056
// IsEqual returns true is this tweaked script key is exactly equivalent to the
@@ -1083,12 +1121,9 @@ func (s *ScriptKey) IsEqual(otherScriptKey *ScriptKey) bool {
1083
1121
// the local wallet or was explicitly declared to be known by using the
1084
1122
// DeclareScriptKey RPC. Knowing the key conceptually means the key belongs to
1085
1123
// the local wallet or is at least known by a software that operates on the
1086
- // local wallet. The DeclaredAsKnown flag is never serialized in proofs, so this
1087
- // is never explicitly set for keys foreign to the local wallet. Therefore, if
1088
- // this method returns true for a script key, it means the asset with the script
1089
- // key will be shown in the wallet balance.
1124
+ // local wallet.
1090
1125
func (s * ScriptKey ) DeclaredAsKnown () bool {
1091
- return s .TweakedScriptKey != nil && s .TweakedScriptKey . DeclaredKnown
1126
+ return s .TweakedScriptKey != nil && s .Type != ScriptKeyUnknown
1092
1127
}
1093
1128
1094
1129
// HasScriptPath returns true if we know the internals of the script key and
@@ -1098,15 +1133,55 @@ func (s *ScriptKey) HasScriptPath() bool {
1098
1133
return s .TweakedScriptKey != nil && len (s .TweakedScriptKey .Tweak ) > 0
1099
1134
}
1100
1135
1136
+ // DetermineType attempts to determine the type of the script key based on the
1137
+ // information available. This method will only return ScriptKeyUnknown if the
1138
+ // following condition is met:
1139
+ // - The script key doesn't have a script path, but the final Taproot output
1140
+ // key doesn't match a BIP-0086 key derived from the internal key. This will
1141
+ // be the case for "foreign" script keys we import from proofs, where we set
1142
+ // the internal key to the same key as the tweaked script key (because we
1143
+ // don't know the internal key, as it's not part of the proof encoding).
1144
+ func (s * ScriptKey ) DetermineType () ScriptKeyType {
1145
+ // If we have an explicit script key type set, we can return that.
1146
+ if s .TweakedScriptKey != nil &&
1147
+ s .TweakedScriptKey .Type != ScriptKeyUnknown {
1148
+
1149
+ return s .TweakedScriptKey .Type
1150
+ }
1151
+
1152
+ // If there is a known tweak, then we know that this is a script path
1153
+ // key. We never return the channel type, since those keys should always
1154
+ // be declared properly, and we never should need to guess their type.
1155
+ if s .HasScriptPath () {
1156
+ return ScriptKeyScriptPathExternal
1157
+ }
1158
+
1159
+ // Is it the known NUMS key? Then this is a tombstone output.
1160
+ if s .PubKey != nil && s .PubKey .IsEqual (NUMSPubKey ) {
1161
+ return ScriptKeyTombstone
1162
+ }
1163
+
1164
+ // Do we know the internal key? Then we can check whether it is a
1165
+ // BIP-0086 key.
1166
+ if s .PubKey != nil && s .TweakedScriptKey != nil &&
1167
+ s .TweakedScriptKey .RawKey .PubKey != nil {
1168
+
1169
+ bip86 := NewScriptKeyBip86 (s .TweakedScriptKey .RawKey )
1170
+ if bip86 .PubKey .IsEqual (s .PubKey ) {
1171
+ return ScriptKeyBip86
1172
+ }
1173
+ }
1174
+
1175
+ return ScriptKeyUnknown
1176
+ }
1177
+
1101
1178
// NewScriptKey constructs a ScriptKey with only the publicly available
1102
1179
// information. This resulting key may or may not have a tweak applied to it.
1103
1180
func NewScriptKey (key * btcec.PublicKey ) ScriptKey {
1104
1181
// Since we'll never query lnd for a tweaked key, it doesn't matter if
1105
1182
// we lose the parity information here. And this will only ever be
1106
1183
// serialized on chain in a 32-bit representation as well.
1107
- key , _ = schnorr .ParsePubKey (
1108
- schnorr .SerializePubKey (key ),
1109
- )
1184
+ key , _ = schnorr .ParsePubKey (schnorr .SerializePubKey (key ))
1110
1185
return ScriptKey {
1111
1186
PubKey : key ,
1112
1187
}
@@ -1118,9 +1193,7 @@ func NewScriptKey(key *btcec.PublicKey) ScriptKey {
1118
1193
func NewScriptKeyBip86 (rawKey keychain.KeyDescriptor ) ScriptKey {
1119
1194
// Tweak the script key BIP-0086 style (such that we only commit to the
1120
1195
// internal key when signing).
1121
- tweakedPubKey := txscript .ComputeTaprootKeyNoScript (
1122
- rawKey .PubKey ,
1123
- )
1196
+ tweakedPubKey := txscript .ComputeTaprootKeyNoScript (rawKey .PubKey )
1124
1197
1125
1198
// Since we'll never query lnd for a tweaked key, it doesn't matter if
1126
1199
// we lose the parity information here. And this will only ever be
@@ -1133,6 +1206,7 @@ func NewScriptKeyBip86(rawKey keychain.KeyDescriptor) ScriptKey {
1133
1206
PubKey : tweakedPubKey ,
1134
1207
TweakedScriptKey : & TweakedScriptKey {
1135
1208
RawKey : rawKey ,
1209
+ Type : ScriptKeyBip86 ,
1136
1210
},
1137
1211
}
1138
1212
}
@@ -1526,7 +1600,7 @@ func (a *Asset) Copy() *Asset {
1526
1600
1527
1601
if a .ScriptKey .TweakedScriptKey != nil {
1528
1602
assetCopy .ScriptKey .TweakedScriptKey = & TweakedScriptKey {
1529
- DeclaredKnown : a .ScriptKey .DeclaredKnown ,
1603
+ Type : a .ScriptKey .Type ,
1530
1604
}
1531
1605
assetCopy .ScriptKey .RawKey = a .ScriptKey .RawKey
1532
1606
0 commit comments