diff --git a/address/address.go b/address/address.go index 4104e303e..d290f111a 100644 --- a/address/address.go +++ b/address/address.go @@ -16,7 +16,6 @@ import ( "github.com/btcsuite/btcd/wire" "github.com/lightninglabs/taproot-assets/asset" "github.com/lightninglabs/taproot-assets/commitment" - "github.com/lightninglabs/taproot-assets/fn" "github.com/lightningnetwork/lnd/tlv" ) @@ -98,12 +97,6 @@ type Tap struct { // asset to be made possible. GroupKey *btcec.PublicKey - // groupWitness is a stack of witness elements that authorizes the - // membership of an asset in a partiular asset group. The witness can - // be a single signature or a script from the tapscript tree committed - // to with the TapscriptRoot, and follows the witness rules in BIP-341. - groupWitness wire.TxWitness - // ScriptKey represents a tweaked Taproot output key encumbering the // different ways an asset can be spent. ScriptKey btcec.PublicKey @@ -184,7 +177,6 @@ func New(version Version, genesis asset.Genesis, groupKey *btcec.PublicKey, AssetVersion: asset.V0, AssetID: genesis.ID(), GroupKey: groupKey, - groupWitness: groupWitness, ScriptKey: scriptKey, InternalKey: internalKey, TapscriptSibling: tapscriptSibling, @@ -203,9 +195,6 @@ func (a *Tap) Copy() *Tap { groupPubKey := *a.GroupKey addressCopy.GroupKey = &groupPubKey } - if len(a.groupWitness) != 0 { - addressCopy.groupWitness = fn.CopySlice(a.groupWitness) - } return &addressCopy } @@ -226,11 +215,6 @@ func (a *Tap) AttachGenesis(gen asset.Genesis) { a.assetGen = gen } -// AttachGroupWitness attaches the asset's group witness to the address. -func (a *Tap) AttachGroupWitness(wit wire.TxWitness) { - a.groupWitness = wit -} - // TapCommitmentKey is the key that maps to the root commitment for the asset // group specified by a Taproot Asset address. func (a *Tap) TapCommitmentKey() [32]byte { @@ -259,13 +243,8 @@ func (a *Tap) TapCommitment() (*commitment.TapCommitment, error) { // it in the TLV leaf. var groupKey *asset.GroupKey if a.GroupKey != nil { - if len(a.groupWitness) == 0 { - return nil, fmt.Errorf("missing group signature") - } - groupKey = &asset.GroupKey{ GroupPubKey: *a.GroupKey, - Witness: a.groupWitness, } } newAsset, err := asset.New( diff --git a/address/address_test.go b/address/address_test.go index 5f19984b8..9742521e7 100644 --- a/address/address_test.go +++ b/address/address_test.go @@ -53,8 +53,8 @@ func randAddress(t *testing.T, net *ChainParams, v Version, groupPubKey, ) } - pubKeyCopy1 := *pubKey - pubKeyCopy2 := *pubKey + scriptKey := *pubKey + internalKey := *pubKey genesis := asset.RandGenesis(t, assetType) @@ -64,7 +64,11 @@ func randAddress(t *testing.T, net *ChainParams, v Version, groupPubKey, ) if groupPubKey { - groupInfo := asset.RandGroupKey(t, genesis) + protoAsset := asset.NewAssetNoErr( + t, genesis, amount, 0, 0, + asset.NewScriptKey(&scriptKey), nil, + ) + groupInfo := asset.RandGroupKey(t, genesis, protoAsset) groupKey = &groupInfo.GroupPubKey groupWitness = groupInfo.Witness } @@ -72,7 +76,7 @@ func randAddress(t *testing.T, net *ChainParams, v Version, groupPubKey, proofCourierAddr := RandProofCourierAddr(t) return New( - v, genesis, groupKey, groupWitness, pubKeyCopy1, pubKeyCopy2, + v, genesis, groupKey, groupWitness, scriptKey, internalKey, amount, tapscriptSibling, net, proofCourierAddr, ) } diff --git a/address/mock.go b/address/mock.go index 32a834992..ddae803fe 100644 --- a/address/mock.go +++ b/address/mock.go @@ -33,6 +33,13 @@ func RandAddr(t testing.TB, params *ChainParams, *asset.Genesis, *asset.GroupKey) { scriptKeyPriv := test.RandPrivKey(t) + scriptKey := asset.NewScriptKeyBip86(keychain.KeyDescriptor{ + PubKey: scriptKeyPriv.PubKey(), + KeyLocator: keychain.KeyLocator{ + Family: keychain.KeyFamily(test.RandIntn(255) + 1), + Index: uint32(test.RandIntn(255)), + }, + }) internalKey := test.RandPrivKey(t) @@ -49,7 +56,10 @@ func RandAddr(t testing.TB, params *ChainParams, tapscriptSibling *commitment.TapscriptPreimage ) if test.RandInt[uint32]()%2 == 0 { - groupInfo = asset.RandGroupKey(t, genesis) + protoAsset := asset.NewAssetNoErr( + t, genesis, amount, 0, 0, scriptKey, nil, + ) + groupInfo = asset.RandGroupKey(t, genesis, protoAsset) groupPubKey = &groupInfo.GroupPubKey groupWitness = groupInfo.Witness @@ -58,14 +68,6 @@ func RandAddr(t testing.TB, params *ChainParams, ) } - scriptKey := asset.NewScriptKeyBip86(keychain.KeyDescriptor{ - PubKey: scriptKeyPriv.PubKey(), - KeyLocator: keychain.KeyLocator{ - Family: keychain.KeyFamily(test.RandIntn(255) + 1), - Index: uint32(test.RandIntn(255)), - }, - }) - tapAddr, err := New( V0, genesis, groupPubKey, groupWitness, *scriptKey.PubKey, *internalKey.PubKey(), amount, tapscriptSibling, params, diff --git a/address/testdata/address_tlv_encoding_generated.json b/address/testdata/address_tlv_encoding_generated.json index 41880b42f..bc4964def 100644 --- a/address/testdata/address_tlv_encoding_generated.json +++ b/address/testdata/address_tlv_encoding_generated.json @@ -70,14 +70,14 @@ "chain_params_hrp": "taptb", "asset_version": 0, "asset_id": "7f3a94b3048ecbce4f2b1686e2df89bde52d5ead1aed011f75fa6578dcab0839", - "group_key": "03f32d239904d1addae728d1917a94bc1d20455b12b251a9222d035e5014a9f759", + "group_key": "02cd028e8899c3324c75a41f6f34b0038fa640b96b93e421c9860c52a7efa9d395", "script_key": "02a0afeb165f0ec36880b68e0baabd9ad9c62fd1a69aa998bc30e9a346202e078f", "internal_key": "02a0afeb165f0ec36880b68e0baabd9ad9c62fd1a69aa998bc30e9a346202e078f", "tapscript_sibling": "", "amount": 1, "proof_courier_addr": "hashmail://rand.hashmail.proof.courier:443" }, - "expected": "taptb1qqqsqqspqqzzqle6jjesfrktee8jk95xut0cn00994026xhdqy0ht7n90rw2kzpeq5ss8uedywvsf5ddmtnj35v3022tc8fqg4d39vj34y3z6q672q22na6eqcss9g90avt97rkrdzqtdrst427e4kwx9lg6dx4fnz7rp6drgcszupu0pqss9g90avt97rkrdzqtdrst427e4kwx9lg6dx4fnz7rp6drgcszupu0pgqszrp2dpshx6rdv95kcw309aexzmny9e5xzumgd4skjmpwwpex7mmx9e3k7atjd9jhyw35xseskkqklz", + "expected": "taptb1qqqsqqspqqzzqle6jjesfrktee8jk95xut0cn00994026xhdqy0ht7n90rw2kzpeq5ss9ngz36yfnsejf366g8m0xjcq8raxgzukhylyy8ycvrzj5lh6n5u4qcss9g90avt97rkrdzqtdrst427e4kwx9lg6dx4fnz7rp6drgcszupu0pqss9g90avt97rkrdzqtdrst427e4kwx9lg6dx4fnz7rp6drgcszupu0pgqszrp2dpshx6rdv95kcw309aexzmny9e5xzumgd4skjmpwwpex7mmx9e3k7atjd9jhyw35xses833965", "comment": "signet group collectible" }, { diff --git a/asset/asset.go b/asset/asset.go index 81a37fe75..a0570ab27 100644 --- a/asset/asset.go +++ b/asset/asset.go @@ -17,6 +17,7 @@ import ( "github.com/btcsuite/btcd/btcec/v2/schnorr" "github.com/btcsuite/btcd/txscript" "github.com/btcsuite/btcd/wire" + "github.com/lightninglabs/lndclient" "github.com/lightninglabs/taproot-assets/mssmt" "github.com/lightningnetwork/lnd/input" "github.com/lightningnetwork/lnd/keychain" @@ -184,16 +185,6 @@ func (g Genesis) GroupKeyTweak() []byte { return keyGroupBytes.Bytes() } -// VerifySignature verifies the given signature that it is valid over the -// asset's unique identifier with the given public key. -func (g Genesis) VerifySignature(sig *schnorr.Signature, - pubKey *btcec.PublicKey) bool { - - msg := g.ID() - digest := sha256.Sum256(msg[:]) - return sig.Verify(digest[:], pubKey) -} - // Encode encodes an asset genesis. func (g Genesis) Encode(w io.Writer) error { var buf [8]byte @@ -437,14 +428,17 @@ type GroupKey struct { // GroupPubKey is the tweaked public key that is used to associate assets // together across distinct asset IDs, allowing further issuance of the // asset to be made possible. The tweaked public key is the result of: - // groupInternalKey + sha256(groupInternalKey || genesisOutPoint) * G + // + // internalKey = rawKey + singleTweak * G + // tweakedGroupKey = TapTweak(internalKey, tapTweak) GroupPubKey btcec.PublicKey // TapscriptRoot is the root of the Tapscript tree that commits to all // script spend conditions for the group key. Instead of spending an // asset, these scripts are used to define witnesses more complex than - // a Schnorr signature for reissuing assets. - TapscriptRoot [sha256.Size]byte + // a Schnorr signature for reissuing assets. A group key with an empty + // Tapscript root can only authorize reissuance with a signature. + TapscriptRoot []byte // Witness is a stack of witness elements that authorizes the membership // of an asset in a particular asset group. The witness can be a single @@ -459,8 +453,8 @@ type GroupKey struct { type GroupKeyReveal struct { // RawKey is the public key that is tweaked twice to derive the final // tweaked group key. The final tweaked key is the result of: - // groupInternalKey = RawKey * sha256(assetID || RawKey) * G. - // GroupPubKey = TapTweak(groupInternalKey, TapscriptRoot) + // internalKey = rawKey + singleTweak * G + // tweakedGroupKey = TapTweak(internalKey, tapTweak) RawKey SerializedKey // TapscriptRoot is the root of the Tapscript tree that commits to all @@ -478,11 +472,38 @@ func (g *GroupKeyReveal) GroupPubKey(assetID ID) (*btcec.PublicKey, error) { return nil, err } - internalKey := input.TweakPubKeyWithTweak(rawKey, assetID[:]) - tweakedGroupKey := txscript.ComputeTaprootOutputKey( - internalKey, g.TapscriptRoot[:], - ) - return tweakedGroupKey, nil + return GroupPubKey(rawKey, assetID[:], g.TapscriptRoot) +} + +// GroupPubKey derives a tweaked group key from a public key and two tweaks; +// the single tweak is the asset ID of the group anchor asset, and the tapTweak +// is the root of a tapscript tree that commits to script-based conditions for +// reissuing assets as part of this asset group. The tweaked key is defined by: +// +// internalKey = rawKey + singleTweak * G +// tweakedGroupKey = TapTweak(internalKey, tapTweak) +func GroupPubKey(rawKey *btcec.PublicKey, singleTweak, tapTweak []byte) ( + *btcec.PublicKey, error) { + + if len(singleTweak) != sha256.Size { + return nil, fmt.Errorf("genesis tweak must be %d bytes", + sha256.Size) + } + + internalKey := input.TweakPubKeyWithTweak(rawKey, singleTweak) + + switch len(tapTweak) { + case 0: + return txscript.ComputeTaprootKeyNoScript(internalKey), nil + + case sha256.Size: + return txscript.ComputeTaprootOutputKey(internalKey, tapTweak), + nil + + default: + return nil, fmt.Errorf("tapscript tweaks must be %d bytes", + sha256.Size) + } } // IsEqual returns true if this group key and signature are exactly equivalent @@ -501,7 +522,7 @@ func (g *GroupKey) IsEqual(otherGroupKey *GroupKey) bool { return false } - if g.TapscriptRoot != otherGroupKey.TapscriptRoot { + if !bytes.Equal(g.TapscriptRoot, otherGroupKey.TapscriptRoot) { return false } @@ -733,96 +754,65 @@ func NewScriptKeyBip86(rawKey keychain.KeyDescriptor) ScriptKey { } } -// GenesisSigner is used to sign the assetID using the group key public key -// for a given asset. -type GenesisSigner interface { - // SignGenesis tweaks the public key identified by the passed key - // descriptor with the the first passed Genesis description, and signs - // the second passed Genesis description with the tweaked public key. - // For minting the first asset in a group, only one Genesis object is - // needed, since we tweak with and sign over the same Genesis object. - // The final tweaked public key and the signature are returned. - SignGenesis(keychain.KeyDescriptor, Genesis, - *Genesis) (*btcec.PublicKey, *schnorr.Signature, error) -} - -// RawKeyGenesisSigner implements the GenesisSigner interface using a raw -// private key. -type RawKeyGenesisSigner struct { - privKey *btcec.PrivateKey -} +// DeriveGroupKey derives an asset's group key based on an internal public +// key descriptor, the original group asset genesis, and the asset's genesis. +func DeriveGroupKey(genSigner GenesisSigner, genBuilder GenesisTxBuilder, + rawKey keychain.KeyDescriptor, initialGen Genesis, + newAsset *Asset) (*GroupKey, error) { -// NewRawKeyGenesisSigner creates a new RawKeyGenesisSigner instance given the -// passed public key. -func NewRawKeyGenesisSigner(priv *btcec.PrivateKey) *RawKeyGenesisSigner { - return &RawKeyGenesisSigner{ - privKey: priv, + // First, perform the final checks on the asset being authorized for + // group membership. + if newAsset == nil { + return nil, fmt.Errorf("grouped asset cannot be nil") } -} -// SignGenesis tweaks the public key identified by the passed key -// descriptor with the the first passed Genesis description, and signs -// the second passed Genesis description with the tweaked public key. -// For minting the first asset in a group, only one Genesis object is -// needed, since we tweak with and sign over the same Genesis object. -// The final tweaked public key and the signature are returned. -func (r *RawKeyGenesisSigner) SignGenesis(keyDesc keychain.KeyDescriptor, - initialGen Genesis, currentGen *Genesis) (*btcec.PublicKey, - *schnorr.Signature, error) { - - if !keyDesc.PubKey.IsEqual(r.privKey.PubKey()) { - return nil, nil, fmt.Errorf("cannot sign with key") + if !newAsset.HasGenesisWitness() { + return nil, fmt.Errorf("asset is not a genesis asset") } - // TODO(jhb): Update to two-phase tweak - tweakedPrivKey := txscript.TweakTaprootPrivKey( - *r.privKey, initialGen.GroupKeyTweak(), - ) - - // If the current genesis is not set, we are minting the first asset in - // the group. This means that we use the same Genesis object for both - // the key tweak and to create the asset ID we sign. If the current - // genesis is set, the asset type of the new asset must match the type - // of the first asset in the group. - id := initialGen.ID() - if currentGen != nil { - if initialGen.Type != currentGen.Type { - return nil, nil, fmt.Errorf("asset group type mismatch") - } - - id = currentGen.ID() + if initialGen.Type != newAsset.Type { + return nil, fmt.Errorf("asset group type mismatch") } - // TODO(roasbeef): this actually needs to sign the digest of the asset - // itself - idHash := sha256.Sum256(id[:]) - sig, err := schnorr.Sign(tweakedPrivKey, idHash[:]) + // Compute the tweaked group key and set it in the asset before + // creating the virtual minting transaction. + genesisTweak := initialGen.ID() + tweakedGroupKey, err := GroupPubKey(rawKey.PubKey, genesisTweak[:], nil) if err != nil { - return nil, nil, err + return nil, fmt.Errorf("cannot tweak group key: %w", err) } - return tweakedPrivKey.PubKey(), sig, nil -} - -// A compile-time assertion to ensure RawKeyGenesisSigner meets the -// GenesisSigner interface. -var _ GenesisSigner = (*RawKeyGenesisSigner)(nil) + assetWithGroup := newAsset.Copy() + assetWithGroup.GroupKey = &GroupKey{ + GroupPubKey: *tweakedGroupKey, + } -// DeriveGroupKey derives an asset's group key based on an internal public -// key descriptor, the original group asset genesis, and the asset's genesis. -func DeriveGroupKey(genSigner GenesisSigner, rawKey keychain.KeyDescriptor, - initialGen Genesis, currentGen *Genesis) (*GroupKey, error) { + // Build the virtual transaction that represents the minting of the new + // asset, which will be signed to generate the group witness. + genesisTx, prevOut, err := genBuilder.BuildGenesisTx(assetWithGroup) + if err != nil { + return nil, fmt.Errorf("cannot build virtual tx: %w", err) + } - groupPubKey, sig, err := genSigner.SignGenesis( - rawKey, initialGen, currentGen, - ) + // Build the static signing descriptor needed to sign the virtual + // minting transaction. This is restricted to group keys with an empty + // tapscript root and key path spends. + signDesc := &lndclient.SignDescriptor{ + KeyDesc: rawKey, + SingleTweak: genesisTweak[:], + SignMethod: input.TaprootKeySpendBIP0086SignMethod, + Output: prevOut, + HashType: txscript.SigHashDefault, + InputIndex: 0, + } + sig, err := genSigner.SignVirtualTx(signDesc, genesisTx, prevOut) if err != nil { return nil, err } return &GroupKey{ RawKey: rawKey, - GroupPubKey: *groupPubKey, + GroupPubKey: *tweakedGroupKey, Witness: wire.TxWitness{sig.Serialize()}, }, nil } @@ -893,18 +883,28 @@ func New(genesis Genesis, amount, locktime, relativeLocktime uint64, genesis.Type) } + // Valid genesis asset witness. + genesisWitness := Witness{ + PrevID: &PrevID{}, + TxWitness: nil, + SplitCommitment: nil, + } + + // Genesis assets with an asset group must have the group witness stored + // in the genesis asset witness, if present. + if groupKey != nil && groupKey.Witness != nil && + len(groupKey.Witness) != 0 { + + genesisWitness.TxWitness = groupKey.Witness + } + return &Asset{ - Version: V0, - Genesis: genesis, - Amount: amount, - LockTime: locktime, - RelativeLockTime: relativeLocktime, - PrevWitnesses: []Witness{{ - // Valid genesis asset witness. - PrevID: &PrevID{}, - TxWitness: nil, - SplitCommitment: nil, - }}, + Version: V0, + Genesis: genesis, + Amount: amount, + LockTime: locktime, + RelativeLockTime: relativeLocktime, + PrevWitnesses: []Witness{genesisWitness}, SplitCommitmentRoot: nil, ScriptVersion: ScriptV0, ScriptKey: scriptKey, @@ -977,6 +977,33 @@ func (a *Asset) HasGenesisWitness() bool { return *witness.PrevID == ZeroPrevID } +// NeedsGenesisWitnessForGroup determines whether an asset is a genesis grouped +// asset, which does not yet have a group witness. +func (a *Asset) NeedsGenesisWitnessForGroup() bool { + return a.HasGenesisWitness() && a.GroupKey != nil +} + +// HasGenesisWitnessForGroup determines whether an asset has a witness for a +// genesis asset in an asset group. This asset must have a non-empty group key +// and a single prevWitness with a zero PrevID, empty split commitment proof, +// and non-empty witness. +func (a *Asset) HasGenesisWitnessForGroup() bool { + if a.GroupKey == nil || len(a.PrevWitnesses) != 1 { + return false + } + + // The single PrevWitness must have a ZeroPrevID, non-empty witness, and + // nil split commitment. + witness := a.PrevWitnesses[0] + if witness.PrevID == nil || len(witness.TxWitness) == 0 || + witness.SplitCommitment != nil { + + return false + } + + return *witness.PrevID == ZeroPrevID +} + // HasSplitCommitmentWitness returns true if an asset has a split commitment // witness. func (a *Asset) HasSplitCommitmentWitness() bool { diff --git a/asset/asset_test.go b/asset/asset_test.go index 00ee9abc7..8f456ac18 100644 --- a/asset/asset_test.go +++ b/asset/asset_test.go @@ -15,6 +15,7 @@ import ( "github.com/lightninglabs/taproot-assets/fn" "github.com/lightninglabs/taproot-assets/internal/test" "github.com/lightninglabs/taproot-assets/mssmt" + "github.com/lightningnetwork/lnd/input" "github.com/lightningnetwork/lnd/keychain" "github.com/stretchr/testify/require" ) @@ -290,7 +291,7 @@ func TestValidateAssetName(t *testing.T) { }, { // Invalid if tab in name. - name: "tab tab", + name: "tab tab", valid: false, }, { @@ -513,10 +514,10 @@ func TestAssetGroupKey(t *testing.T) { privKey, err := btcec.NewPrivateKey() require.NoError(t, err) privKeyCopy := btcec.PrivKeyFromScalar(&privKey.Key) - genSigner := NewRawKeyGenesisSigner(privKeyCopy) - fakeKeyDesc := keychain.KeyDescriptor{ - PubKey: privKeyCopy.PubKey(), - } + genSigner := NewMockGenesisSigner(privKeyCopy) + genBuilder := MockGroupTxBuilder{} + fakeKeyDesc := test.PubToKeyDesc(privKeyCopy.PubKey()) + fakeScriptKey := NewScriptKeyBip86(fakeKeyDesc) g := Genesis{ FirstPrevOut: wire.OutPoint{ @@ -528,16 +529,17 @@ func TestAssetGroupKey(t *testing.T) { OutputIndex: 21, Type: Collectible, } + groupTweak := g.ID() - var groupBytes bytes.Buffer - _ = wire.WriteOutPoint(&groupBytes, 0, 0, &g.FirstPrevOut) - _, _ = groupBytes.Write([]byte{0, 0, 0, 21, 1}) - - tweakedKey := txscript.TweakTaprootPrivKey(*privKey, groupBytes.Bytes()) + internalKey := input.TweakPrivKey(privKeyCopy, groupTweak[:]) + tweakedKey := txscript.TweakTaprootPrivKey(*internalKey, nil) // TweakTaprootPrivKey modifies the private key that is passed in! We // need to provide a copy to arrive at the same result. - keyGroup, err := DeriveGroupKey(genSigner, fakeKeyDesc, g, nil) + protoAsset := NewAssetNoErr(t, g, 1, 0, 0, fakeScriptKey, nil) + keyGroup, err := DeriveGroupKey( + genSigner, &genBuilder, fakeKeyDesc, g, protoAsset, + ) require.NoError(t, err) require.Equal( diff --git a/asset/interface.go b/asset/interface.go new file mode 100644 index 000000000..6d1e5368c --- /dev/null +++ b/asset/interface.go @@ -0,0 +1,26 @@ +package asset + +import ( + "github.com/btcsuite/btcd/btcec/v2/schnorr" + "github.com/btcsuite/btcd/wire" + "github.com/lightninglabs/lndclient" +) + +// GenesisSigner is used to sign the assetID using the group key public key +// for a given asset. +type GenesisSigner interface { + // SignVirtualTx generates a signature according to the passed signing + // descriptor and TX. + SignVirtualTx(signDesc *lndclient.SignDescriptor, tx *wire.MsgTx, + prevOut *wire.TxOut) (*schnorr.Signature, error) +} + +// GenesisTxBuilder is used to construct the virtual transaction that represents +// asset minting for grouped assets. This transaction is used to generate a +// group witness that authorizes the minting of an asset into the asset group. +type GenesisTxBuilder interface { + // BuildGenesisTx constructs a virtual transaction and prevOut that + // represent the genesis state transition for a grouped asset. This + // ouput is used to create a group witness for the grouped asset. + BuildGenesisTx(newAsset *Asset) (*wire.MsgTx, *wire.TxOut, error) +} diff --git a/asset/mock.go b/asset/mock.go index f27066fbf..5170a26f6 100644 --- a/asset/mock.go +++ b/asset/mock.go @@ -2,11 +2,20 @@ package asset import ( "bytes" + "context" + "crypto/sha256" "encoding/hex" + "fmt" "testing" + "github.com/btcsuite/btcd/btcec/v2" + "github.com/btcsuite/btcd/btcec/v2/schnorr" + "github.com/btcsuite/btcd/txscript" + "github.com/btcsuite/btcd/wire" + "github.com/lightninglabs/lndclient" "github.com/lightninglabs/taproot-assets/internal/test" "github.com/lightninglabs/taproot-assets/mssmt" + "github.com/lightningnetwork/lnd/input" "github.com/stretchr/testify/require" ) @@ -27,34 +36,275 @@ func RandGenesis(t testing.TB, assetType Type) Genesis { } // RandGroupKey creates a random group key for testing. -func RandGroupKey(t testing.TB, genesis Genesis) *GroupKey { - privateKey := test.RandPrivKey(t) - - genSigner := NewRawKeyGenesisSigner(privateKey) - - groupKey, err := DeriveGroupKey( - genSigner, test.PubToKeyDesc(privateKey.PubKey()), - genesis, nil, - ) - require.NoError(t, err) +func RandGroupKey(t testing.TB, genesis Genesis, newAsset *Asset) *GroupKey { + groupKey, _ := RandGroupKeyWithSigner(t, genesis, newAsset) return groupKey } // RandGroupKeyWithSigner creates a random group key for testing, and provides // the signer for reissuing assets into the same group. -func RandGroupKeyWithSigner(t testing.TB, genesis Genesis) (*GroupKey, []byte) { +func RandGroupKeyWithSigner(t testing.TB, genesis Genesis, + newAsset *Asset) (*GroupKey, []byte) { + privateKey := test.RandPrivKey(t) - genSigner := NewRawKeyGenesisSigner(privateKey) + genSigner := NewMockGenesisSigner(privateKey) + genBuilder := MockGroupTxBuilder{} groupKey, err := DeriveGroupKey( - genSigner, test.PubToKeyDesc(privateKey.PubKey()), - genesis, nil, + genSigner, &genBuilder, test.PubToKeyDesc(privateKey.PubKey()), + genesis, newAsset, ) require.NoError(t, err) return groupKey, privateKey.Serialize() } +// MockGenesisSigner implements the GenesisSigner interface using a raw +// private key. +type MockGenesisSigner struct { + privKey *btcec.PrivateKey +} + +// NewMockGenesisSigner creates a new MockGenesisSigner instance given the +// passed public key. +func NewMockGenesisSigner(priv *btcec.PrivateKey) *MockGenesisSigner { + return &MockGenesisSigner{ + privKey: priv, + } +} + +// SignVirtualTx generates a signature according to the passed signing +// descriptor and virtual TX. +func (r *MockGenesisSigner) SignVirtualTx(signDesc *lndclient.SignDescriptor, + virtualTx *wire.MsgTx, prevOut *wire.TxOut) (*schnorr.Signature, + error) { + + signerPubKey := r.privKey.PubKey() + + if !signDesc.KeyDesc.PubKey.IsEqual(signerPubKey) { + return nil, fmt.Errorf("cannot sign with key") + } + + sig, err := SignVirtualTx(r.privKey, signDesc, virtualTx, prevOut) + if err != nil { + return nil, err + } + + return sig, nil +} + +// A compile-time assertion to ensure MockGenesisSigner meets the +// GenesisSigner interface. +var _ GenesisSigner = (*MockGenesisSigner)(nil) + +// Forked from tapscript/tx/virtualTxOut to remove checks for split commitments +// and witness stripping. +func virtualGenesisTxOut(newAsset *Asset) (*wire.TxOut, error) { + // Commit to the new asset directly. In this case, the output script is + // derived from the root of a MS-SMT containing the new asset. + groupKey := schnorr.SerializePubKey(&newAsset.GroupKey.GroupPubKey) + assetID := newAsset.Genesis.ID() + + h := sha256.New() + _, _ = h.Write(groupKey) + _, _ = h.Write(assetID[:]) + _, _ = h.Write(schnorr.SerializePubKey(newAsset.ScriptKey.PubKey)) + + key := *(*[32]byte)(h.Sum(nil)) + leaf, err := newAsset.Leaf() + if err != nil { + return nil, err + } + outputTree := mssmt.NewCompactedTree(mssmt.NewDefaultStore()) + + // TODO(bhandras): thread the context through. + tree, err := outputTree.Insert(context.TODO(), key, leaf) + if err != nil { + return nil, err + } + + treeRoot, err := tree.Root(context.Background()) + if err != nil { + return nil, err + } + + rootKey := treeRoot.NodeHash() + pkScript, err := test.ComputeTaprootScriptErr(rootKey[:]) + if err != nil { + return nil, err + } + return wire.NewTxOut(int64(newAsset.Amount), pkScript), nil +} + +// Forked from tapscript/tx/virtualTx to be used only with the +// MockGroupTxBuilder. +func virtualGenesisTx(newAsset *Asset) (*wire.MsgTx, error) { + var ( + txIn *wire.TxIn + err error + ) + + // We'll start by mapping all inputs into a MS-SMT. + txIn, _, err = VirtualGenesisTxIn(newAsset) + if err != nil { + return nil, err + } + + // Then we'll map all asset outputs into a single UTXO. + txOut, err := virtualGenesisTxOut(newAsset) + if err != nil { + return nil, err + } + + // With our single input and output mapped, we're ready to construct our + // virtual transaction. + virtualTx := wire.NewMsgTx(2) + virtualTx.AddTxIn(txIn) + virtualTx.AddTxOut(txOut) + return virtualTx, nil +} + +type MockGroupTxBuilder struct{} + +// BuildGenesisTx constructs a virtual transaction and prevOut that represent +// the genesis state transition for a grouped asset. This ouput is used to +// create a group witness for the grouped asset. +func (m *MockGroupTxBuilder) BuildGenesisTx(newAsset *Asset) (*wire.MsgTx, + *wire.TxOut, error) { + + // First, we check that the passed asset is a genesis grouped asset + // that has no group witness. + if !newAsset.NeedsGenesisWitnessForGroup() { + return nil, nil, fmt.Errorf("asset is not a genesis grouped" + + "asset") + } + + prevOut, err := InputGenesisAssetPrevOut(*newAsset) + if err != nil { + return nil, nil, err + } + + // Now, create the virtual transaction that represents this asset + // minting. + virtualTx, err := virtualGenesisTx(newAsset) + if err != nil { + return nil, nil, fmt.Errorf("cannot tweak group key: %w", err) + } + populatedVirtualTx := VirtualTxWithInput( + virtualTx, newAsset, 0, nil, + ) + + return populatedVirtualTx, prevOut, nil +} + +// A compile time assertion to ensure that MockGroupTxBuilder meets the +// GenesisTxBuilder interface. +var _ GenesisTxBuilder = (*MockGroupTxBuilder)(nil) + +// SignOutputRaw creates a signature for a single input. +// Taken from lnd/lnwallet/btcwallet/signer:L344, SignOutputRaw +func SignOutputRaw(priv *btcec.PrivateKey, tx *wire.MsgTx, + signDesc *input.SignDescriptor) (*schnorr.Signature, error) { + + witnessScript := signDesc.WitnessScript + + privKey := priv + var maybeTweakPrivKey *btcec.PrivateKey + + switch { + case signDesc.SingleTweak != nil: + maybeTweakPrivKey = input.TweakPrivKey( + privKey, signDesc.SingleTweak, + ) + + case signDesc.DoubleTweak != nil: + maybeTweakPrivKey = input.DeriveRevocationPrivKey( + privKey, signDesc.DoubleTweak, + ) + + default: + maybeTweakPrivKey = privKey + } + + privKey = maybeTweakPrivKey + + // In case of a taproot output any signature is always a Schnorr + // signature, based on the new tapscript sighash algorithm. + if !txscript.IsPayToTaproot(signDesc.Output.PkScript) { + return nil, fmt.Errorf("mock signer: output script not taproot") + } + + sigHashes := txscript.NewTxSigHashes( + tx, signDesc.PrevOutputFetcher, + ) + + // Are we spending a script path or the key path? The API is slightly + // different, so we need to account for that to get the raw signature. + var ( + rawSig []byte + err error + ) + switch signDesc.SignMethod { + case input.TaprootKeySpendBIP0086SignMethod, + input.TaprootKeySpendSignMethod: + + // This function tweaks the private key using the tap root key + // supplied as the tweak. + rawSig, err = txscript.RawTxInTaprootSignature( + tx, sigHashes, signDesc.InputIndex, + signDesc.Output.Value, signDesc.Output.PkScript, + signDesc.TapTweak, signDesc.HashType, privKey, + ) + + case input.TaprootScriptSpendSignMethod: + leaf := txscript.TapLeaf{ + LeafVersion: txscript.BaseLeafVersion, + Script: witnessScript, + } + rawSig, err = txscript.RawTxInTapscriptSignature( + tx, sigHashes, signDesc.InputIndex, + signDesc.Output.Value, signDesc.Output.PkScript, + leaf, signDesc.HashType, privKey, + ) + } + if err != nil { + return nil, err + } + + return schnorr.ParseSignature(rawSig) +} + +func SignVirtualTx(priv *btcec.PrivateKey, signDesc *lndclient.SignDescriptor, + tx *wire.MsgTx, prevOut *wire.TxOut) (*schnorr.Signature, error) { + + prevOutFetcher := txscript.NewCannedPrevOutputFetcher( + prevOut.PkScript, prevOut.Value, + ) + + sigHashes := txscript.NewTxSigHashes(tx, prevOutFetcher) + + fullSignDesc := input.SignDescriptor{ + KeyDesc: signDesc.KeyDesc, + SingleTweak: signDesc.SingleTweak, + DoubleTweak: signDesc.DoubleTweak, + TapTweak: signDesc.TapTweak, + WitnessScript: signDesc.WitnessScript, + SignMethod: signDesc.SignMethod, + Output: signDesc.Output, + HashType: signDesc.HashType, + SigHashes: sigHashes, + PrevOutputFetcher: prevOutFetcher, + InputIndex: signDesc.InputIndex, + } + + sig, err := SignOutputRaw(priv, tx, &fullSignDesc) + if err != nil { + return nil, err + } + + return sig, nil +} + // RandScriptKey creates a random script key for testing. func RandScriptKey(t testing.TB) ScriptKey { return NewScriptKey(test.RandPrivKey(t).PubKey()) @@ -73,15 +323,29 @@ func RandID(t testing.TB) ID { return a } +// NewAssetNoErr creates an asset and fails the test if asset creation fails. +func NewAssetNoErr(t testing.TB, gen Genesis, amt, locktime, relocktime uint64, + scriptKey ScriptKey, groupKey *GroupKey) *Asset { + + a, err := New(gen, amt, locktime, relocktime, scriptKey, groupKey) + require.NoError(t, err) + + return a +} + // RandAsset creates a random asset of the given type for testing. func RandAsset(t testing.TB, assetType Type) *Asset { t.Helper() genesis := RandGenesis(t, assetType) - familyKey := RandGroupKey(t, genesis) scriptKey := RandScriptKey(t) + protoAsset := RandAssetWithValues(t, genesis, nil, scriptKey) + familyKey := RandGroupKey(t, genesis, protoAsset) - return RandAssetWithValues(t, genesis, familyKey, scriptKey) + return NewAssetNoErr( + t, genesis, protoAsset.Amount, protoAsset.LockTime, + protoAsset.RelativeLockTime, scriptKey, familyKey, + ) } // RandAssetWithValues creates a random asset with the given genesis and keys @@ -381,3 +645,66 @@ type ValidBurnTestCase struct { type BurnTestVectors struct { ValidTestCases []*ValidBurnTestCase `json:"valid_test_cases"` } + +func NewTestFromGenesisReveal(t testing.TB, g *Genesis) *TestGenesisReveal { + t.Helper() + + return &TestGenesisReveal{ + FirstPrevOut: g.FirstPrevOut.String(), + Tag: g.Tag, + MetaHash: hex.EncodeToString(g.MetaHash[:]), + OutputIndex: g.OutputIndex, + Type: uint8(g.Type), + } +} + +type TestGenesisReveal struct { + FirstPrevOut string `json:"first_prev_out"` + Tag string `json:"tag"` + MetaHash string `json:"meta_hash"` + OutputIndex uint32 `json:"output_index"` + Type uint8 `json:"type"` +} + +func (tgr *TestGenesisReveal) ToGenesisReveal(t testing.TB) *Genesis { + t.Helper() + + return &Genesis{ + FirstPrevOut: test.ParseOutPoint( + t, tgr.FirstPrevOut, + ), + Tag: tgr.Tag, + MetaHash: test.Parse32Byte(t, tgr.MetaHash), + OutputIndex: tgr.OutputIndex, + Type: Type(tgr.Type), + } +} + +func NewTestFromGroupKeyReveal(t testing.TB, + gkr *GroupKeyReveal) *TestGroupKeyReveal { + + t.Helper() + + return &TestGroupKeyReveal{ + RawKey: hex.EncodeToString(gkr.RawKey[:]), + TapscriptRoot: hex.EncodeToString(gkr.TapscriptRoot), + } +} + +type TestGroupKeyReveal struct { + RawKey string `json:"raw_key"` + TapscriptRoot string `json:"tapscript_root"` +} + +func (tgkr *TestGroupKeyReveal) ToGroupKeyReveal(t testing.TB) *GroupKeyReveal { + t.Helper() + + rawKey := test.ParsePubKey(t, tgkr.RawKey) + tapscriptRoot, err := hex.DecodeString(tgkr.TapscriptRoot) + require.NoError(t, err) + + return &GroupKeyReveal{ + RawKey: ToSerialized(rawKey), + TapscriptRoot: tapscriptRoot, + } +} diff --git a/asset/tx.go b/asset/tx.go new file mode 100644 index 000000000..4d2f51956 --- /dev/null +++ b/asset/tx.go @@ -0,0 +1,147 @@ +package asset + +import ( + "context" + "crypto/sha256" + "encoding/binary" + + "github.com/btcsuite/btcd/btcec/v2/schnorr" + "github.com/btcsuite/btcd/chaincfg/chainhash" + "github.com/btcsuite/btcd/txscript" + "github.com/btcsuite/btcd/wire" + "github.com/lightninglabs/taproot-assets/mssmt" +) + +const ( + // zeroIndex is a constant that stores the usual zero index we use for + // the virtual prev outs created in the VM. + zeroIndex = 0 +) + +// ComputeTaprootScript computes the on-chain SegWit v1 script, known as +// Taproot, based on the given `witnessProgram`. +func ComputeTaprootScript(witnessProgram []byte) ([]byte, error) { + return txscript.NewScriptBuilder(). + AddOp(txscript.OP_1). + AddData(witnessProgram[:]). + Script() +} + +// VirtualTxInPrevOut returns the prevout of the Taproot Asset virtual +// transaction's single input as a hash of the root node's key concatenated by +// its sum. +func VirtualTxInPrevOut(root mssmt.Node) *wire.OutPoint { + // Grab the hash digest of the SMT node. This'll be used to generate + // the virtual prev out for this tx in. + // + // TODO(roasbeef): this already contains the sum, so can just use it + // directly? + rootKey := root.NodeHash() + + // Map this to: nodeHash || nodeSum. + h := sha256.New() + _, _ = h.Write(rootKey[:]) + _ = binary.Write(h, binary.BigEndian, root.NodeSum()) + + return wire.NewOutPoint( + (*chainhash.Hash)(h.Sum(nil)), zeroIndex, + ) +} + +// VirtualTxWithInput returns a copy of the `virtualTx` amended to include all +// input-specific details. +// +// This is used to further bind a given witness to the "true" input it spends. +// We'll use the index of the serialized input to bind the prev index, which +// represents the "leaf index" of the virtual input MS-SMT. +func VirtualTxWithInput(virtualTx *wire.MsgTx, input *Asset, + idx uint32, witness wire.TxWitness) *wire.MsgTx { + + txCopy := virtualTx.Copy() + txCopy.LockTime = uint32(input.LockTime) + txCopy.TxIn[zeroIndex].PreviousOutPoint.Index = idx + txCopy.TxIn[zeroIndex].Sequence = uint32(input.RelativeLockTime) + txCopy.TxIn[zeroIndex].Witness = witness + return txCopy +} + +// VirtualGenesisTxIn computes the single input of a Taproot Asset virtual +// transaction that represents a grouped asset genesis. The input prevout's hash +// is the root of a MS-SMT committing to only the genesis asset. +func VirtualGenesisTxIn(newAsset *Asset) (*wire.TxIn, mssmt.Tree, error) { + inputTree := mssmt.NewCompactedTree(mssmt.NewDefaultStore()) + + // TODO(bhandras): thread the context through. + ctx := context.TODO() + + // Strip any group witness if present. + copyNoWitness := newAsset.Copy() + if copyNoWitness.HasGenesisWitnessForGroup() { + copyNoWitness.PrevWitnesses[0].TxWitness = nil + } + + // For genesis grouped assets, we always use the ZeroPrevID for the + // MS-SMT key since the asset has no real PrevID to use. + key := ZeroPrevID.Hash() + leaf, err := copyNoWitness.Leaf() + if err != nil { + return nil, nil, err + } + + _, err = inputTree.Insert(ctx, key, leaf) + if err != nil { + return nil, nil, err + } + + treeRoot, err := inputTree.Root(context.Background()) + if err != nil { + return nil, nil, err + } + + prevOut := VirtualTxInPrevOut(treeRoot) + + return wire.NewTxIn(prevOut, nil, nil), inputTree, nil +} + +// GenesisPrevOutFetcher returns a Taproot Asset input's `PrevOutFetcher` to be +// used throughout signing when the input asset is a genesis grouped asset. +func GenesisPrevOutFetcher(prevAsset Asset) (*txscript.CannedPrevOutputFetcher, + error) { + + prevOut, err := InputGenesisAssetPrevOut(prevAsset) + if err != nil { + return nil, err + } + + return txscript.NewCannedPrevOutputFetcher( + prevOut.PkScript, prevOut.Value, + ), nil +} + +// InputGenesisAssetPrevOut returns a TxOut that represents the input asset in a +// Taproot Asset virtual TX, but uses tweaked group key of the input asset to +// enable group witness validation. +func InputGenesisAssetPrevOut(prevAsset Asset) (*wire.TxOut, error) { + switch prevAsset.ScriptVersion { + case ScriptV0: + // If the input asset is a genesis asset that is part of an + // asset group, we need to validate the group witness against + // the tweaked group key and not the genesis asset script key. + validationKey := &prevAsset.GroupKey.GroupPubKey + pkScript, err := txscript.NewScriptBuilder(). + AddOp(txscript.OP_1). + AddData(schnorr.SerializePubKey(validationKey)). + Script() + + if err != nil { + return nil, err + } + + return &wire.TxOut{ + Value: int64(prevAsset.Amount), + PkScript: pkScript, + }, nil + default: + return nil, ErrUnknownVersion + } +} diff --git a/commitment/asset.go b/commitment/asset.go index 7a5a161c7..f96a1de48 100644 --- a/commitment/asset.go +++ b/commitment/asset.go @@ -47,13 +47,6 @@ var ( ErrAssetDuplicateScriptKey = errors.New( "asset commitment: duplicate script key", ) - - // ErrAssetGenesisInvalidSig is an error returned when we attempt to - // create a new asset commitment from a genesis with an invalid - // signature with their group key. - ErrAssetGenesisInvalidSig = errors.New( - "asset commitment: invalid genesis signature", - ) ) // CommittedAssets is the set of Assets backing an AssetCommitment. @@ -135,25 +128,6 @@ func parseCommon(assets ...*asset.Asset) (*AssetCommitment, error) { if assetGenesis != newAsset.Genesis.ID() { return nil, ErrAssetGenesisMismatch } - - case assetGroupKey != nil: - // There should be a valid Schnorr sig over the asset ID - // in the group key struct. - groupSig, isSig := asset.IsGroupSig( - newAsset.GroupKey.Witness, - ) - - if !isSig { - return nil, fmt.Errorf("unsupported group " + - "witness") - } - - validSig := newAsset.Genesis.VerifySignature( - groupSig, &assetGroupKey.GroupPubKey, - ) - if !validSig { - return nil, ErrAssetGenesisInvalidSig - } } // Return error if the asset's tap commitment key doesn't match @@ -254,22 +228,6 @@ func (c *AssetCommitment) Upsert(newAsset *asset.Asset) error { return ErrAssetGenesisMismatch } - // There should be a valid Schnorr sig over the asset ID - // in the group key struct. - if newAsset.GroupKey != nil { - groupSig, isSig := asset.IsGroupSig(newAsset.GroupKey.Witness) - if !isSig { - return fmt.Errorf("unsupported group witness") - } - - validSig := newAsset.Genesis.VerifySignature( - groupSig, &newAsset.GroupKey.GroupPubKey, - ) - if !validSig { - return ErrAssetGenesisInvalidSig - } - } - key := newAsset.AssetCommitmentKey() // TODO(bhandras): thread the context through. diff --git a/commitment/commitment_test.go b/commitment/commitment_test.go index 7cdff6fe6..f4a98d1e6 100644 --- a/commitment/commitment_test.go +++ b/commitment/commitment_test.go @@ -23,6 +23,9 @@ var ( "511c4c1cfee543eac337024a6f13bb5f496e99209207a3792a74" + "89ccc21d4dbbe5ed180000000000001389", ) + + zeroAmt = uint64(0) + oneAmt = uint64(1) ) func randAssetDetails(t *testing.T, assetType asset.Type) *AssetDetails { @@ -63,22 +66,35 @@ func TestNewAssetCommitment(t *testing.T) { genesis1 := asset.RandGenesis(t, asset.Normal) genesis1Collectible := asset.RandGenesis(t, asset.Collectible) + genesis1CollectibleScriptKey := asset.RandScriptKey(t) + genesis1CollectibleProtoAsset := asset.NewAssetNoErr( + t, genesis1Collectible, 1, 0, 0, genesis1CollectibleScriptKey, + nil, + ) genesis2 := asset.RandGenesis(t, asset.Normal) - groupKey1, group1PrivBytes := asset.RandGroupKeyWithSigner(t, genesis1) - group1Priv, group1Pub := btcec.PrivKeyFromBytes(group1PrivBytes) + genesis2ProtoAsset := asset.RandAssetWithValues( + t, genesis2, nil, asset.RandScriptKey(t), + ) group1Anchor := randAsset(t, genesis1, nil) + groupKey1, group1PrivBytes := asset.RandGroupKeyWithSigner( + t, genesis1, group1Anchor, + ) + group1Priv, group1Pub := btcec.PrivKeyFromBytes(group1PrivBytes) group1Anchor.GroupKey = groupKey1 - groupKey1Collectible := asset.RandGroupKey(t, genesis1Collectible) - groupKey2 := asset.RandGroupKey(t, genesis2) + groupKey1Collectible := asset.RandGroupKey( + t, genesis1Collectible, genesis1CollectibleProtoAsset, + ) + groupKey2 := asset.RandGroupKey(t, genesis2, genesis2ProtoAsset) copyOfGroupKey1Collectible := &asset.GroupKey{ RawKey: groupKey1Collectible.RawKey, GroupPubKey: groupKey1Collectible.GroupPubKey, Witness: groupKey1Collectible.Witness, } group1Reissued := randAsset(t, genesis2, nil) + genTxBuilder := asset.MockGroupTxBuilder{} group1ReissuedGroupKey, err := asset.DeriveGroupKey( - asset.NewRawKeyGenesisSigner(group1Priv), - test.PubToKeyDesc(group1Pub), genesis1, &genesis2, + asset.NewMockGenesisSigner(group1Priv), &genTxBuilder, + test.PubToKeyDesc(group1Pub), genesis1, genesis2ProtoAsset, ) require.NoError(t, err) group1Reissued.GroupKey = group1ReissuedGroupKey @@ -108,16 +124,6 @@ func TestNewAssetCommitment(t *testing.T) { }, err: ErrAssetGenesisMismatch, }, - { - name: "same group with invalid signature", - f: func() []*asset.Asset { - return []*asset.Asset{ - randAsset(t, genesis1, groupKey1), - randAsset(t, genesis2, groupKey1), - } - }, - err: ErrAssetGenesisInvalidSig, - }, { name: "duplicate script key", f: func() []*asset.Asset { @@ -240,11 +246,10 @@ func TestMintTapCommitment(t *testing.T) { name: "normal with zero amount", g: genesisNormal, f: func() *AssetDetails { - zero := uint64(0) return &AssetDetails{ Type: asset.Normal, ScriptKey: pubKey, - Amount: &zero, + Amount: &zeroAmt, LockTime: 1337, RelativeLockTime: 6, } @@ -299,11 +304,10 @@ func TestMintTapCommitment(t *testing.T) { name: "collectible with one amount", g: genesisCollectible, f: func() *AssetDetails { - one := uint64(1) return &AssetDetails{ Type: asset.Collectible, ScriptKey: pubKey, - Amount: &one, + Amount: &oneAmt, LockTime: 1337, RelativeLockTime: 6, } @@ -329,8 +333,41 @@ func TestMintTapCommitment(t *testing.T) { for _, testCase := range testCases { success := t.Run(testCase.name, func(t *testing.T) { details := testCase.f() - groupKey := asset.RandGroupKey(t, testCase.g) - _, _, err := Mint(testCase.g, groupKey, details) + + // Test case concerns amount sanity checking, skip + // group key creation. + var err error + amt := details.Amount + invalidNormalAmt := details.Type != asset.Collectible && + ((amt != nil && *amt == zeroAmt) || amt == nil) + invalidCollctibleAmt := amt != nil && *amt != oneAmt && + details.Type == asset.Collectible + + switch { + case invalidNormalAmt || invalidCollctibleAmt: + _, _, err = Mint(testCase.g, nil, details) + + default: + trueAmt := amt + if amt == nil { + trueAmt = &oneAmt + } + + protoAsset := asset.NewAssetNoErr( + t, testCase.g, *trueAmt, + details.LockTime, + details.RelativeLockTime, + asset.NewScriptKeyBip86(details.ScriptKey), + nil, + ) + + groupKey := asset.RandGroupKey( + t, testCase.g, protoAsset, + ) + + _, _, err = Mint(testCase.g, groupKey, details) + } + if testCase.valid { require.NoError(t, err) } else { @@ -352,15 +389,25 @@ func TestMintAndDeriveTapCommitment(t *testing.T) { const assetType = asset.Normal const numAssets = 5 + var anchorDetails *AssetDetails genesis1 := asset.RandGenesis(t, assetType) - groupKey1 := asset.RandGroupKey(t, genesis1) assetDetails := make([]*AssetDetails, 0, numAssets) for i := 0; i < numAssets; i++ { details := randAssetDetails(t, assetType) assetDetails = append(assetDetails, details) + if i == 0 { + anchorDetails = details + } } + genesis1ProtoAsset := asset.NewAssetNoErr( + t, genesis1, *anchorDetails.Amount, anchorDetails.LockTime, + anchorDetails.RelativeLockTime, + asset.NewScriptKeyBip86(anchorDetails.ScriptKey), nil, + ) + groupKey1 := asset.RandGroupKey(t, genesis1, genesis1ProtoAsset) + // Mint a new Taproot Asset commitment with the included assets. commitment, assets, err := Mint(genesis1, groupKey1, assetDetails...) require.NoError(t, err) @@ -422,7 +469,12 @@ func TestMintAndDeriveTapCommitment(t *testing.T) { // proofs). We'll reuse the same asset details, except we'll mint them // with a distinct genesis and group key. genesis2 := asset.RandGenesis(t, assetType) - groupKey2 := asset.RandGroupKey(t, genesis2) + genesis2ProtoAsset := asset.NewAssetNoErr( + t, genesis2, *anchorDetails.Amount, anchorDetails.LockTime, + anchorDetails.RelativeLockTime, + asset.NewScriptKeyBip86(anchorDetails.ScriptKey), nil, + ) + groupKey2 := asset.RandGroupKey(t, genesis2, genesis2ProtoAsset) _, nonExistentAssetGroup, err := Mint( genesis2, groupKey2, assetDetails..., ) @@ -438,8 +490,16 @@ func TestSplitCommitment(t *testing.T) { outPoint := wire.OutPoint{} genesisNormal := asset.RandGenesis(t, asset.Normal) genesisCollectible := asset.RandGenesis(t, asset.Collectible) - groupKeyNormal := asset.RandGroupKey(t, genesisNormal) - groupKeyCollectible := asset.RandGroupKey(t, genesisCollectible) + normalProtoAsset := randAsset(t, genesisNormal, nil) + collectibleProtoAsset := randAsset(t, genesisCollectible, nil) + groupKeyNormal := asset.RandGroupKey(t, genesisNormal, normalProtoAsset) + groupKeyCollectible := asset.RandGroupKey( + t, genesisCollectible, collectibleProtoAsset, + ) + normalInputAsset := normalProtoAsset.Copy() + normalInputAsset.GroupKey = groupKeyNormal + collectibleInputAsset := collectibleProtoAsset.Copy() + collectibleInputAsset.GroupKey = groupKeyCollectible testCases := []struct { name string @@ -826,13 +886,14 @@ func TestTapCommitmentKeyPopulation(t *testing.T) { } genesis := asset.RandGenesis(t, assetType) + a := randAsset(t, genesis, nil) var groupKey *asset.GroupKey if assetDesc.HasGroupKey { - groupKey = asset.RandGroupKey(t, genesis) + groupKey = asset.RandGroupKey(t, genesis, a) + a.GroupKey = groupKey } - a := randAsset(t, genesis, groupKey) commitment, err := NewAssetCommitment(a) require.NoError(t, err) @@ -860,20 +921,19 @@ func TestUpdateAssetCommitment(t *testing.T) { genesis2 := asset.RandGenesis(t, asset.Normal) genesis1collect := genesis1 genesis1collect.Type = asset.Collectible - groupKey1, group1PrivBytes := asset.RandGroupKeyWithSigner(t, genesis1) - group1Priv, group1Pub := btcec.PrivKeyFromBytes(group1PrivBytes) group1Anchor := randAsset(t, genesis1, nil) + groupKey1, group1PrivBytes := asset.RandGroupKeyWithSigner( + t, genesis1, group1Anchor, + ) + group1Priv, group1Pub := btcec.PrivKeyFromBytes(group1PrivBytes) group1Anchor.GroupKey = groupKey1 - groupKey2 := asset.RandGroupKey(t, genesis2) - copyOfGroupKey1 := &asset.GroupKey{ - RawKey: groupKey1.RawKey, - GroupPubKey: groupKey1.GroupPubKey, - Witness: groupKey1.Witness, - } - group1Reissued := randAsset(t, genesis2, nil) + group2Anchor := randAsset(t, genesis2, nil) + groupKey2 := asset.RandGroupKey(t, genesis2, group2Anchor) + group1Reissued := group2Anchor.Copy() + genTxBuilder := asset.MockGroupTxBuilder{} group1ReissuedGroupKey, err := asset.DeriveGroupKey( - asset.NewRawKeyGenesisSigner(group1Priv), - test.PubToKeyDesc(group1Pub), genesis1, &genesis2, + asset.NewMockGenesisSigner(group1Priv), &genTxBuilder, + test.PubToKeyDesc(group1Pub), genesis1, group1Reissued, ) require.NoError(t, err) group1Reissued.GroupKey = group1ReissuedGroupKey @@ -912,15 +972,6 @@ func TestUpdateAssetCommitment(t *testing.T) { numAssets: 0, err: ErrAssetTypeMismatch, }, - { - name: "invalid group signature", - f: func() (*asset.Asset, error) { - mismatchedAsset := randAsset(t, genesis2, copyOfGroupKey1) - return nil, groupAssetCommitment.Upsert(mismatchedAsset) - }, - numAssets: 0, - err: ErrAssetGenesisInvalidSig, - }, { name: "fresh asset commitment", f: func() (*asset.Asset, error) { @@ -933,10 +984,15 @@ func TestUpdateAssetCommitment(t *testing.T) { name: "insertion of asset with group key", f: func() (*asset.Asset, error) { group1Reissued := randAsset(t, genesis2, nil) + genTxBuilder := asset.MockGroupTxBuilder{} + gen2ProtoAsset := asset.RandAssetWithValues( + t, genesis2, nil, asset.RandScriptKey(t), + ) group1ReissuedGroupKey, err := asset.DeriveGroupKey( - asset.NewRawKeyGenesisSigner(group1Priv), + asset.NewMockGenesisSigner(group1Priv), + &genTxBuilder, test.PubToKeyDesc(group1Priv.PubKey()), - genesis1, &genesis2, + genesis1, gen2ProtoAsset, ) require.NoError(t, err) group1Reissued.GroupKey = group1ReissuedGroupKey @@ -1014,11 +1070,15 @@ func TestUpdateTapCommitment(t *testing.T) { // they are not in the same AssetCommitment. genesis1 := asset.RandGenesis(t, asset.Normal) genesis2 := asset.RandGenesis(t, asset.Normal) - groupKey1 := asset.RandGroupKey(t, genesis1) - groupKey2 := asset.RandGroupKey(t, genesis2) - - asset1 := randAsset(t, genesis1, groupKey1) - asset2 := randAsset(t, genesis2, groupKey2) + protoAsset1 := randAsset(t, genesis1, nil) + protoAsset2 := randAsset(t, genesis2, nil) + groupKey1 := asset.RandGroupKey(t, genesis1, protoAsset1) + groupKey2 := asset.RandGroupKey(t, genesis2, protoAsset2) + + asset1 := protoAsset1.Copy() + asset1.GroupKey = groupKey1 + asset2 := protoAsset2.Copy() + asset2.GroupKey = groupKey2 assetCommitment1, err := NewAssetCommitment(asset1) require.NoError(t, err) commitmentKey1 := assetCommitment1.TapCommitmentKey() @@ -1138,12 +1198,16 @@ func TestTapCommitmentDeepCopy(t *testing.T) { // Fist, we'll make two asset commitments with a random asset, then // make a Taproot Asset commitment out of that. genesis1 := asset.RandGenesis(t, asset.Normal) - groupKey1 := asset.RandGroupKey(t, genesis1) - asset1 := randAsset(t, genesis1, groupKey1) + protoAsset1 := randAsset(t, genesis1, nil) + groupKey1 := asset.RandGroupKey(t, genesis1, protoAsset1) + asset1 := protoAsset1.Copy() + asset1.GroupKey = groupKey1 genesis2 := asset.RandGenesis(t, asset.Normal) - groupKey2 := asset.RandGroupKey(t, genesis2) - asset2 := randAsset(t, genesis2, groupKey2) + protoAsset2 := randAsset(t, genesis2, nil) + groupKey2 := asset.RandGroupKey(t, genesis2, protoAsset2) + asset2 := protoAsset2.Copy() + asset2.GroupKey = groupKey2 assetCommitment1, err := NewAssetCommitment(asset1) require.NoError(t, err) diff --git a/gen_signer.go b/gen_signer.go deleted file mode 100644 index 25f05950b..000000000 --- a/gen_signer.go +++ /dev/null @@ -1,75 +0,0 @@ -package taprootassets - -import ( - "context" - "fmt" - - "github.com/btcsuite/btcd/btcec/v2" - "github.com/btcsuite/btcd/btcec/v2/schnorr" - "github.com/btcsuite/btcd/txscript" - "github.com/lightninglabs/lndclient" - "github.com/lightninglabs/taproot-assets/asset" - "github.com/lightningnetwork/lnd/keychain" -) - -// LndRpcGenSigner is an implementation of the asset.GenesisSigner interface -// backed by an active lnd node. -type LndRpcGenSigner struct { - lnd *lndclient.LndServices -} - -// NewLndRpcGenSigner returns a new gen signer instance backed by the passed -// connection to a remote lnd node. -func NewLndRpcGenSigner(lnd *lndclient.LndServices) *LndRpcGenSigner { - return &LndRpcGenSigner{ - lnd: lnd, - } -} - -// SignGenesis tweaks the public key identified by the passed key -// descriptor with the the first passed Genesis description, and signs -// the second passed Genesis description with the tweaked public key. -// For minting the first asset in a group, only one Genesis object is -// needed, since we tweak with and sign over the same Genesis object. -// The final tweaked public key and the signature are returned. -func (l *LndRpcGenSigner) SignGenesis(keyDesc keychain.KeyDescriptor, - initialGen asset.Genesis, currentGen *asset.Genesis) (*btcec.PublicKey, - *schnorr.Signature, error) { - - tweakedPubKey := txscript.ComputeTaprootOutputKey( - keyDesc.PubKey, initialGen.GroupKeyTweak(), - ) - - // If the current genesis is not set, we are minting the first asset in - // the group. This means that we use the same Genesis object for both - // the key tweak and to create the asset ID we sign. If the current - // genesis is set, the asset type of the new asset must match the type - // of the first asset in the group. - id := initialGen.ID() - if currentGen != nil { - if initialGen.Type != currentGen.Type { - return nil, nil, fmt.Errorf("asset group type mismatch") - } - - id = currentGen.ID() - } - - sig, err := l.lnd.Signer.SignMessage( - context.Background(), id[:], keyDesc.KeyLocator, - lndclient.SignSchnorr(initialGen.GroupKeyTweak()), - ) - if err != nil { - return nil, nil, err - } - - schnorrSig, err := schnorr.ParseSignature(sig) - if err != nil { - return nil, nil, fmt.Errorf("unable to parse schnorr sig: %w", - err) - } - return tweakedPubKey, schnorrSig, nil -} - -// A compile time assertion to ensure LndRpcGenSigner meets the -// asset.GenesisSigner interface. -var _ asset.GenesisSigner = (*LndRpcGenSigner)(nil) diff --git a/internal/test/helpers.go b/internal/test/helpers.go index ee9a953d8..00c31be40 100644 --- a/internal/test/helpers.go +++ b/internal/test/helpers.go @@ -308,11 +308,17 @@ func HexTx(t testing.TB, tx *wire.MsgTx) string { return hex.EncodeToString(buf.Bytes()) } -func ComputeTaprootScript(t testing.TB, taprootKey *btcec.PublicKey) []byte { - script, err := txscript.NewScriptBuilder(). +func ComputeTaprootScriptErr(witnessProgram []byte) ([]byte, error) { + return txscript.NewScriptBuilder(). AddOp(txscript.OP_1). - AddData(schnorr.SerializePubKey(taprootKey)). + AddData(witnessProgram[:]). Script() +} + +func ComputeTaprootScript(t testing.TB, taprootKey *btcec.PublicKey) []byte { + script, err := ComputeTaprootScriptErr( + schnorr.SerializePubKey(taprootKey), + ) require.NoError(t, err) return script } diff --git a/itest/assertions.go b/itest/assertions.go index b5b4a6f29..a4d3e5a6d 100644 --- a/itest/assertions.go +++ b/itest/assertions.go @@ -14,7 +14,6 @@ import ( "github.com/btcsuite/btcd/btcec/v2/schnorr" "github.com/btcsuite/btcd/chaincfg/chainhash" "github.com/btcsuite/btcd/rpcclient" - "github.com/btcsuite/btcd/txscript" "github.com/btcsuite/btcd/wire" "github.com/lightninglabs/taproot-assets/asset" "github.com/lightninglabs/taproot-assets/fn" @@ -425,7 +424,27 @@ func VerifyProofBlob(t *testing.T, tapClient taprpc.TaprootAssetsClient, return err } - snapshot, err := f.Verify(ctxt, headerVerifier) + groupVerifier := func(groupKey *btcec.PublicKey) error { + assetGroupKey := hex.EncodeToString( + groupKey.SerializeCompressed(), + ) + + // The given group key should be listed as a known group. + assetGroups, err := tapClient.ListGroups( + ctxt, &taprpc.ListGroupsRequest{}, + ) + require.NoError(t, err) + + _, ok := assetGroups.Groups[assetGroupKey] + if !ok { + return fmt.Errorf("group key %s not known", + assetGroupKey) + } + + return nil + } + + snapshot, err := f.Verify(ctxt, headerVerifier, groupVerifier) require.NoError(t, err) return f, snapshot @@ -908,15 +927,20 @@ func AssertGroup(t *testing.T, a *taprpc.Asset, b *taprpc.AssetHumanReadable, // AssertGroupAnchor asserts that a specific asset genesis was used to create // a tweaked group key. func AssertGroupAnchor(t *testing.T, anchorGen *asset.Genesis, - internalKey, tweakedKey []byte) { + anchorGroup *taprpc.AssetGroup) { - internalPubKey, err := btcec.ParsePubKey(internalKey) + internalPubKey, err := btcec.ParsePubKey(anchorGroup.RawGroupKey) require.NoError(t, err) - computedGroupPubKey := txscript.ComputeTaprootOutputKey( - internalPubKey, anchorGen.GroupKeyTweak(), + + // TODO(jhb): add tapscript root support + anchorTweak := anchorGen.ID() + computedGroupPubKey, err := asset.GroupPubKey( + internalPubKey, anchorTweak[:], nil, ) + require.NoError(t, err) + computedGroupKey := computedGroupPubKey.SerializeCompressed() - require.Equal(t, tweakedKey, computedGroupKey) + require.Equal(t, anchorGroup.TweakedGroupKey, computedGroupKey) } // MatchRpcAsset is a function that returns true if the given RPC asset is a @@ -1210,10 +1234,7 @@ func VerifyGroupAnchor(t *testing.T, assets []*taprpc.Asset, anchorGen := ParseGenInfo(t, anchor.AssetGenesis) anchorGen.Type = asset.Type(anchor.AssetType) - AssertGroupAnchor( - t, anchorGen, anchor.AssetGroup.RawGroupKey, - anchor.AssetGroup.TweakedGroupKey, - ) + AssertGroupAnchor(t, anchorGen, anchor.AssetGroup) return anchor } diff --git a/proof/append.go b/proof/append.go index a41f4c86b..5cd0eb170 100644 --- a/proof/append.go +++ b/proof/append.go @@ -39,7 +39,8 @@ type TransitionParams struct { // the proof for. This method returns both the encoded full provenance (proof // chain) and the added latest proof. func AppendTransition(blob Blob, params *TransitionParams, - headerVerifier HeaderVerifier) (Blob, *Proof, error) { + headerVerifier HeaderVerifier, groupVerifier GroupVerifier) (Blob, + *Proof, error) { // Decode the proof blob into a proper file structure first. f := NewEmptyFile(V0) @@ -77,7 +78,7 @@ func AppendTransition(blob Blob, params *TransitionParams, if err := f.AppendProof(*newProof); err != nil { return nil, nil, fmt.Errorf("error appending proof: %w", err) } - if _, err := f.Verify(ctx, headerVerifier); err != nil { + if _, err := f.Verify(ctx, headerVerifier, groupVerifier); err != nil { return nil, nil, fmt.Errorf("error verifying proof: %w", err) } diff --git a/proof/append_test.go b/proof/append_test.go index 6ace753b4..4389ce5a8 100644 --- a/proof/append_test.go +++ b/proof/append_test.go @@ -23,7 +23,7 @@ func genTaprootKeySpend(t testing.TB, privKey btcec.PrivateKey, t.Helper() - virtualTxCopy := tapscript.VirtualTxWithInput( + virtualTxCopy := asset.VirtualTxWithInput( virtualTx, input, idx, nil, ) sigHash, err := tapscript.InputKeySpendSigHash( @@ -187,6 +187,7 @@ func runAppendTransitionTest(t *testing.T, assetType asset.Type, amt uint64, // Append the new transition to the genesis blob. transitionBlob, transitionProof, err := AppendTransition( genesisBlob, transitionParams, MockHeaderVerifier, + MockGroupVerifier, ) require.NoError(t, err) require.Greater(t, len(transitionBlob), len(genesisBlob)) @@ -379,6 +380,7 @@ func runAppendTransitionTest(t *testing.T, assetType asset.Type, amt uint64, split1Blob, split1Proof, err := AppendTransition( transitionBlob, split1Params, MockHeaderVerifier, + MockGroupVerifier, ) require.NoError(t, err) require.Greater(t, len(split1Blob), len(transitionBlob)) @@ -420,6 +422,7 @@ func runAppendTransitionTest(t *testing.T, assetType asset.Type, amt uint64, split2Blob, split2Proof, err := AppendTransition( transitionBlob, split2Params, MockHeaderVerifier, + MockGroupVerifier, ) require.NoError(t, err) require.Greater(t, len(split2Blob), len(transitionBlob)) @@ -462,6 +465,7 @@ func runAppendTransitionTest(t *testing.T, assetType asset.Type, amt uint64, split3Blob, split3Proof, err := AppendTransition( transitionBlob, split3Params, MockHeaderVerifier, + MockGroupVerifier, ) require.NoError(t, err) require.Greater(t, len(split3Blob), len(transitionBlob)) @@ -520,7 +524,9 @@ func verifyBlob(t testing.TB, blob Blob) *AssetSnapshot { f := NewEmptyFile(V0) require.NoError(t, f.Decode(bytes.NewReader(blob))) - finalSnapshot, err := f.Verify(context.Background(), MockHeaderVerifier) + finalSnapshot, err := f.Verify( + context.Background(), MockHeaderVerifier, MockGroupVerifier, + ) require.NoError(t, err) return finalSnapshot diff --git a/proof/archive.go b/proof/archive.go index 9d255c8f9..9dd38f472 100644 --- a/proof/archive.go +++ b/proof/archive.go @@ -118,7 +118,8 @@ type Archiver interface { // already be present, and we just update (replace) it with the new // proof. ImportProofs(ctx context.Context, headerVerifier HeaderVerifier, - replace bool, proofs ...*AnnotatedProof) error + groupVerifier GroupVerifier, replace bool, + proofs ...*AnnotatedProof) error } // NotifyArchiver is an Archiver that also allows callers to subscribe to @@ -278,7 +279,8 @@ func (f *FileArchiver) FetchProofs(_ context.Context, // // NOTE: This implements the Archiver interface. func (f *FileArchiver) ImportProofs(_ context.Context, - _ HeaderVerifier, replace bool, proofs ...*AnnotatedProof) error { + _ HeaderVerifier, _ GroupVerifier, replace bool, + proofs ...*AnnotatedProof) error { for _, proof := range proofs { proofPath, err := genProofFilePath(f.proofPath, proof.Locator) @@ -418,8 +420,8 @@ func (m *MultiArchiver) FetchProofs(ctx context.Context, // outpoint of the first state transition will be used as the Genesis point. // The final resting place of the asset will be used as the script key itself. func (m *MultiArchiver) ImportProofs(ctx context.Context, - headerVerifier HeaderVerifier, replace bool, - proofs ...*AnnotatedProof) error { + headerVerifier HeaderVerifier, groupVerifier GroupVerifier, + replace bool, proofs ...*AnnotatedProof) error { // Before we import the proofs into the archive, we want to make sure // that they're all valid. Along the way, we may augment the locator @@ -428,6 +430,7 @@ func (m *MultiArchiver) ImportProofs(ctx context.Context, // First, we'll decode and then also verify the proof. finalStateTransition, err := m.proofVerifier.Verify( c, bytes.NewReader(proof.Blob), headerVerifier, + groupVerifier, ) if err != nil { return fmt.Errorf("unable to verify proof: %w", err) @@ -467,7 +470,7 @@ func (m *MultiArchiver) ImportProofs(ctx context.Context, // to import each proof our archive backends. for _, archive := range m.backends { err := archive.ImportProofs( - ctx, headerVerifier, replace, proofs..., + ctx, headerVerifier, groupVerifier, replace, proofs..., ) if err != nil { return err @@ -534,7 +537,7 @@ var _ NotifyArchiver = (*MultiArchiver)(nil) // assets of the same ID. This is useful when we want to update the proof with a // new one after a re-org. func ReplaceProofInBlob(ctx context.Context, p *Proof, archive Archiver, - headerVerifier HeaderVerifier) error { + headerVerifier HeaderVerifier, groupVerifier GroupVerifier) error { // This is a bit of a hacky part. If we have a chain of transactions // that were re-organized, we can't verify the whole chain until all of @@ -607,11 +610,12 @@ func ReplaceProofInBlob(ctx context.Context, p *Proof, archive Archiver, } // We now update this direct proof in the archive. + directProof := &AnnotatedProof{ + Locator: existingProof.Locator, + Blob: buf.Bytes(), + } err = archive.ImportProofs( - ctx, headerVerifier, true, &AnnotatedProof{ - Locator: existingProof.Locator, - Blob: buf.Bytes(), - }, + ctx, headerVerifier, groupVerifier, true, directProof, ) if err != nil { return fmt.Errorf("unable to import updated proof: %w", diff --git a/proof/archive_test.go b/proof/archive_test.go index 3940b1e07..f1789abbe 100644 --- a/proof/archive_test.go +++ b/proof/archive_test.go @@ -113,7 +113,8 @@ func TestFileArchiver(t *testing.T) { } require.NoError( t, archive.ImportProofs( - ctx, MockHeaderVerifier, false, + ctx, MockHeaderVerifier, + MockGroupVerifier, false, proof, ), ) diff --git a/proof/mint.go b/proof/mint.go index 91b8fcb0b..8c73372e2 100644 --- a/proof/mint.go +++ b/proof/mint.go @@ -135,6 +135,7 @@ func WithAssetMetaReveals( // serialized proof files, which proves the creation/existence of each of the // assets within the batch. func NewMintingBlobs(params *MintParams, headerVerifier HeaderVerifier, + groupVerifier GroupVerifier, anchorVerifier GroupAnchorVerifier, blobOpts ...MintingBlobOption) (AssetProofs, error) { opts := defaultMintingBlobOpts() @@ -147,7 +148,9 @@ func NewMintingBlobs(params *MintParams, headerVerifier HeaderVerifier, return nil, err } - proofs, err := committedProofs(base, params.TaprootAssetRoot, opts) + proofs, err := committedProofs( + base, params.TaprootAssetRoot, anchorVerifier, opts, + ) if err != nil { return nil, err } @@ -158,7 +161,7 @@ func NewMintingBlobs(params *MintParams, headerVerifier HeaderVerifier, for key := range proofs { proof := proofs[key] - _, err := proof.Verify(ctx, nil, headerVerifier) + _, err := proof.Verify(ctx, nil, headerVerifier, groupVerifier) if err != nil { return nil, fmt.Errorf("invalid proof file generated: "+ "%w", err) @@ -210,12 +213,13 @@ func coreProof(params *BaseProofParams) (*Proof, error) { // committedProofs creates a map of proofs, keyed by the script key of each of // the assets committed to in the Taproot Asset root of the given params. -func committedProofs(baseProof *Proof, taprootAssetRoot *commitment.TapCommitment, +func committedProofs(baseProof *Proof, tapTreeRoot *commitment.TapCommitment, + groupAnchorVerifier GroupAnchorVerifier, opts *mintingBlobOpts) (AssetProofs, error) { // For each asset we'll construct the asset specific proof information, // then encode that as a proof file blob in the blobs map. - assets := taprootAssetRoot.CommittedAssets() + assets := tapTreeRoot.CommittedAssets() proofs := make(AssetProofs, len(assets)) for idx := range assets { // First, we'll copy over the base proof and also set the asset @@ -227,7 +231,7 @@ func committedProofs(baseProof *Proof, taprootAssetRoot *commitment.TapCommitmen // With the base information contained, we'll now need to // generate our series of MS-SMT inclusion proofs that prove // the existence of the asset. - _, assetMerkleProof, err := taprootAssetRoot.Proof( + _, assetMerkleProof, err := tapTreeRoot.Proof( newAsset.TapCommitmentKey(), newAsset.AssetCommitmentKey(), ) @@ -259,21 +263,20 @@ func committedProofs(baseProof *Proof, taprootAssetRoot *commitment.TapCommitmen // transition proofs. assetProof.GenesisReveal = &newAsset.Genesis - // We also need to reveal the group key. + // If the asset has a group key, we only need to populate the + // group key reveal if the asset is the group anchor. if newAsset.GroupKey != nil { groupKey := newAsset.GroupKey - // All zero tapscript root means there is none. - var tapscriptRoot []byte - if groupKey.TapscriptRoot != [32]byte{} { - tapscriptRoot = groupKey.TapscriptRoot[:] - } - - assetProof.GroupKeyReveal = &asset.GroupKeyReveal{ - RawKey: asset.ToSerialized( - groupKey.RawKey.PubKey, - ), - TapscriptRoot: tapscriptRoot, + err := groupAnchorVerifier(&newAsset.Genesis, groupKey) + if err == nil { + groupReveal := &asset.GroupKeyReveal{ + RawKey: asset.ToSerialized( + groupKey.RawKey.PubKey, + ), + TapscriptRoot: groupKey.TapscriptRoot, + } + assetProof.GroupKeyReveal = groupReveal } } diff --git a/proof/mint_test.go b/proof/mint_test.go index e438c505a..dc713af83 100644 --- a/proof/mint_test.go +++ b/proof/mint_test.go @@ -23,9 +23,7 @@ func TestNewMintingBlobs(t *testing.T) { // First, we'll create a fake, but legit looking set of minting params // to generate a proof with. genesisPrivKey := test.RandPrivKey(t) - genesisScriptKey := txscript.ComputeTaprootKeyNoScript( - genesisPrivKey.PubKey(), - ) + genesisScriptKey := test.PubToKeyDesc(genesisPrivKey.PubKey()) // We'll modify the returned genesis to instead commit to some actual // metadata (known pre-image). @@ -37,12 +35,17 @@ func TestNewMintingBlobs(t *testing.T) { } assetGenesis := asset.RandGenesis(t, asset.Collectible) assetGenesis.MetaHash = metaReveal.MetaHash() + assetGenesis.OutputIndex = 0 + protoAsset := asset.NewAssetNoErr( + t, assetGenesis, 1, 0, 0, + asset.NewScriptKeyBip86(genesisScriptKey), nil, + ) - assetGroupKey := asset.RandGroupKey(t, assetGenesis) + assetGroupKey := asset.RandGroupKey(t, assetGenesis, protoAsset) tapCommitment, _, err := commitment.Mint( assetGenesis, assetGroupKey, &commitment.AssetDetails{ Type: asset.Collectible, - ScriptKey: test.PubToKeyDesc(genesisScriptKey), + ScriptKey: genesisScriptKey, Amount: nil, LockTime: 0, RelativeLockTime: 0, @@ -64,7 +67,9 @@ func TestNewMintingBlobs(t *testing.T) { genesisTx := &wire.MsgTx{ Version: 2, - TxIn: []*wire.TxIn{{}}, + TxIn: []*wire.TxIn{{ + PreviousOutPoint: assetGenesis.FirstPrevOut, + }}, TxOut: []*wire.TxOut{{ PkScript: taprootScript, Value: 330, @@ -113,6 +118,8 @@ func TestNewMintingBlobs(t *testing.T) { }}, }, GenesisPoint: genesisTx.TxIn[0].PreviousOutPoint, - }, MockHeaderVerifier, WithAssetMetaReveals(metaReveals)) + }, MockHeaderVerifier, MockGroupVerifier, MockGroupAnchorVerifier, + WithAssetMetaReveals(metaReveals), + ) require.NoError(t, err) } diff --git a/proof/mock.go b/proof/mock.go index b63c2d4c2..55c5d1ea6 100644 --- a/proof/mock.go +++ b/proof/mock.go @@ -8,6 +8,7 @@ import ( "testing" "time" + "github.com/btcsuite/btcd/btcec/v2" "github.com/btcsuite/btcd/chaincfg/chainhash" "github.com/btcsuite/btcd/wire" "github.com/lightninglabs/taproot-assets/asset" @@ -27,7 +28,8 @@ func NewMockVerifier(t *testing.T) *MockVerifier { } func (m *MockVerifier) Verify(_ context.Context, _ io.Reader, - headerVerifier HeaderVerifier) (*AssetSnapshot, error) { + headerVerifier HeaderVerifier, + groupVerifier GroupVerifier) (*AssetSnapshot, error) { return &AssetSnapshot{ Asset: &asset.Asset{ @@ -49,6 +51,29 @@ func MockHeaderVerifier(header wire.BlockHeader, height uint32) error { return nil } +// MockGroupVerifier is a mock verifier which approves of all group keys. +// +// Group key verification usually involves having imported the group anchor +// before verification, and many unit tests are not focused on group key +// functionality but still use functions that require a group verifier. +// This function is used in those cases. +func MockGroupVerifier(groupKey *btcec.PublicKey) error { + return nil +} + +// MockGroupAnchorVerifier is a mock verifier which approves of all group anchor +// geneses. +// +// Group anchor verification usually involves accurately computing a group key, +// and many unit tests are not focused on group key functionality but still use +// functions that require a group anchor verifier. This function is used in +// those cases. +func MockGroupAnchorVerifier(gen *asset.Genesis, + groupKey *asset.GroupKey) error { + + return nil +} + type ValidTestCase struct { Proof *TestProof `json:"proof"` Expected string `json:"expected"` @@ -111,22 +136,36 @@ func NewTestFromProof(t testing.TB, p *Proof) *TestProof { ) } + if p.GenesisReveal != nil { + tp.GenesisReveal = asset.NewTestFromGenesisReveal( + t, p.GenesisReveal, + ) + } + + if p.GroupKeyReveal != nil { + tp.GroupKeyReveal = asset.NewTestFromGroupKeyReveal( + t, p.GroupKeyReveal, + ) + } + return tp } type TestProof struct { - PrevOut string `json:"prev_out"` - BlockHeader *TestBlockHeader `json:"block_header"` - BlockHeight uint32 `json:"block_height"` - AnchorTx string `json:"anchor_tx"` - TxMerkleProof *TestTxMerkleProof `json:"tx_merkle_proof"` - Asset *asset.TestAsset `json:"asset"` - InclusionProof *TestTaprootProof `json:"inclusion_proof"` - ExclusionProofs []*TestTaprootProof `json:"exclusion_proofs"` - SplitRootProof *TestTaprootProof `json:"split_root_proof"` - MetaReveal *TestMetaReveal `json:"meta_reveal"` - AdditionalInputs []string `json:"additional_inputs"` - ChallengeWitness []string `json:"challenge_witness"` + PrevOut string `json:"prev_out"` + BlockHeader *TestBlockHeader `json:"block_header"` + BlockHeight uint32 `json:"block_height"` + AnchorTx string `json:"anchor_tx"` + TxMerkleProof *TestTxMerkleProof `json:"tx_merkle_proof"` + Asset *asset.TestAsset `json:"asset"` + InclusionProof *TestTaprootProof `json:"inclusion_proof"` + ExclusionProofs []*TestTaprootProof `json:"exclusion_proofs"` + SplitRootProof *TestTaprootProof `json:"split_root_proof"` + MetaReveal *TestMetaReveal `json:"meta_reveal"` + AdditionalInputs []string `json:"additional_inputs"` + ChallengeWitness []string `json:"challenge_witness"` + GenesisReveal *asset.TestGenesisReveal `json:"genesis_reveal"` + GroupKeyReveal *asset.TestGroupKeyReveal `json:"group_key_reveal"` } func (tp *TestProof) ToProof(t testing.TB) *Proof { @@ -175,6 +214,14 @@ func (tp *TestProof) ToProof(t testing.TB) *Proof { p.ChallengeWitness = append(p.ChallengeWitness, b) } + if tp.GenesisReveal != nil { + p.GenesisReveal = tp.GenesisReveal.ToGenesisReveal(t) + } + + if tp.GroupKeyReveal != nil { + p.GroupKeyReveal = tp.GroupKeyReveal.ToGroupKeyReveal(t) + } + return p } diff --git a/proof/proof.go b/proof/proof.go index 25f3ec4b4..377a57a33 100644 --- a/proof/proof.go +++ b/proof/proof.go @@ -93,6 +93,12 @@ var ( // genesis asset is missing a group key when it should have one. ErrGroupKeyRequired = errors.New("group key required") + // ErrGroupKeyUnknown is an error returned if an asset proof for a + // group asset references an asset group that has not been previously + // verified. This can apply to genesis proofs for reissaunces into a + // group, and any further transfer of a grouped asset. + ErrGroupKeyUnknown = errors.New("group key not known") + // RegtestTestVectorName is the name of the test vector file that is // generated/updated by an actual integration test run on regtest. It is // exported here, so we can use it in the integration tests. diff --git a/proof/proof_test.go b/proof/proof_test.go index 1759a2df1..d22369bbe 100644 --- a/proof/proof_test.go +++ b/proof/proof_test.go @@ -145,7 +145,12 @@ func TestProofEncoding(t *testing.T) { require.NoError(t, err) genesis := asset.RandGenesis(t, asset.Collectible) - groupKey := asset.RandGroupKey(t, genesis) + scriptKey := test.RandPubKey(t) + tweakedScriptKey := asset.NewScriptKey(scriptKey) + protoAsset := asset.NewAssetNoErr( + t, genesis, 1, 0, 0, tweakedScriptKey, nil, + ) + groupKey := asset.RandGroupKey(t, genesis, protoAsset) groupReveal := asset.GroupKeyReveal{ RawKey: asset.ToSerialized(&groupKey.GroupPubKey), TapscriptRoot: test.RandBytes(32), @@ -154,7 +159,7 @@ func TestProofEncoding(t *testing.T) { mintCommitment, assets, err := commitment.Mint( genesis, groupKey, &commitment.AssetDetails{ Type: asset.Collectible, - ScriptKey: test.PubToKeyDesc(test.RandPubKey(t)), + ScriptKey: test.PubToKeyDesc(scriptKey), Amount: nil, LockTime: 1337, RelativeLockTime: 6, @@ -338,6 +343,7 @@ func genRandomGenesisWithProof(t testing.TB, assetType asset.Type, t.Helper() genesisPrivKey := test.RandPrivKey(t) + genesisPubKey := test.PubToKeyDesc(genesisPrivKey.PubKey()) // If we have a specified meta reveal, then we'll replace the meta hash // with the hash of the reveal instead. @@ -353,22 +359,27 @@ func genRandomGenesisWithProof(t testing.TB, assetType asset.Type, genesisMutator(&assetGenesis) } - assetGroupKey := asset.RandGroupKey(t, assetGenesis) + groupAmt := uint64(1) + if amt != nil { + groupAmt = *amt + } + + protoAsset := asset.NewAssetNoErr( + t, assetGenesis, groupAmt, 0, 0, + asset.NewScriptKeyBip86(genesisPubKey), nil, + ) + assetGroupKey := asset.RandGroupKey(t, assetGenesis, protoAsset) groupKeyReveal := asset.GroupKeyReveal{ RawKey: asset.ToSerialized( assetGroupKey.RawKey.PubKey, ), - } - if assetGroupKey.TapscriptRoot != [32]byte{} { - groupKeyReveal.TapscriptRoot = assetGroupKey.TapscriptRoot[:] + TapscriptRoot: assetGroupKey.TapscriptRoot, } tapCommitment, assets, err := commitment.Mint( assetGenesis, assetGroupKey, &commitment.AssetDetails{ - Type: assetType, - ScriptKey: test.PubToKeyDesc( - genesisPrivKey.PubKey(), - ), + Type: assetType, + ScriptKey: genesisPubKey, Amount: amt, LockTime: 0, RelativeLockTime: 0, @@ -569,6 +580,7 @@ func TestGenesisProofVerification(t *testing.T) { ) _, err := genesisProof.Verify( context.Background(), nil, MockHeaderVerifier, + MockGroupVerifier, ) require.ErrorIs(t, err, tc.expectedErr) @@ -629,7 +641,7 @@ func TestProofBlockHeaderVerification(t *testing.T) { // Verify that the original proof block header is as expected and // therefore an error is not returned. _, err := proof.Verify( - context.Background(), nil, headerVerifier, + context.Background(), nil, headerVerifier, MockGroupVerifier, ) require.NoError(t, err) @@ -637,7 +649,7 @@ func TestProofBlockHeaderVerification(t *testing.T) { // propagates the correct error. proof.BlockHeader.Nonce += 1 _, actualErr := proof.Verify( - context.Background(), nil, headerVerifier, + context.Background(), nil, headerVerifier, MockGroupVerifier, ) require.ErrorIs(t, actualErr, errHeaderVerifier) @@ -648,7 +660,7 @@ func TestProofBlockHeaderVerification(t *testing.T) { // propagates the correct error. proof.BlockHeight += 1 _, actualErr = proof.Verify( - context.Background(), nil, headerVerifier, + context.Background(), nil, headerVerifier, MockGroupVerifier, ) require.ErrorIs(t, actualErr, errHeaderVerifier) } @@ -668,13 +680,17 @@ func TestProofFileVerification(t *testing.T) { err = f.Decode(bytes.NewReader(proofBytes)) require.NoError(t, err) - _, err = f.Verify(context.Background(), MockHeaderVerifier) + _, err = f.Verify( + context.Background(), MockHeaderVerifier, MockGroupVerifier, + ) require.NoError(t, err) // Ensure that verification of a proof of unknown version fails. f.Version = Version(212) - lastAsset, err := f.Verify(context.Background(), MockHeaderVerifier) + lastAsset, err := f.Verify( + context.Background(), MockHeaderVerifier, MockGroupVerifier, + ) require.Nil(t, lastAsset) require.ErrorIs(t, err, ErrUnknownVersion) } @@ -718,6 +734,7 @@ func TestProofVerification(t *testing.T) { lastAsset, err := p.Verify( context.Background(), nil, MockHeaderVerifier, + MockGroupVerifier, ) require.Nil(t, lastAsset) require.ErrorIs(t, err, ErrUnknownVersion) @@ -738,7 +755,10 @@ func TestOwnershipProofVerification(t *testing.T) { err = p.Decode(bytes.NewReader(proofBytes)) require.NoError(t, err) - snapshot, err := p.Verify(context.Background(), nil, MockHeaderVerifier) + snapshot, err := p.Verify( + context.Background(), nil, MockHeaderVerifier, + MockGroupVerifier, + ) require.NoError(t, err) require.NotNil(t, snapshot) } diff --git a/proof/testdata/ownership-proof.hex b/proof/testdata/ownership-proof.hex index b0d3abc4c..b5b367150 100644 --- a/proof/testdata/ownership-proof.hex +++ b/proof/testdata/ownership-proof.hex @@ -1 +1 @@ -54415050000400000000012407381c1ad9d4abbf3d4664a80dc13df3a271f73621a4c476d5faa099093d5f08000000010250000040205c9c7f10746d49a143742948cacb2edc063481a6f1fa5492a9f0299346fce325629fa06a4bdb830586733e8351911235692d1fad7664894793de4d223017583a016a0865ffff7f200000000003fd018c0200000000010203f8ac0fa47f7eaf42dbf8ec9b135849dcd49b69ffe980b6ecf88293a0b143ba0000000000ffffffff07381c1ad9d4abbf3d4664a80dc13df3a271f73621a4c476d5faa099093d5f0801000000000000000003e803000000000000225120a914766a8a19bb8cc1fe8c17f411aae5fc6841fea6b807ce73d66ebdabf08d52e80300000000000022512087a21c8d7a5d3d0bea676166a83bfcf12ae3c92b7f14bc1fff7d54820eda441a25d0f50500000000225120fe19c6b74a18eccd85988ed33b3d3204e4ccc8f43c2a10b3958d0a9cf6d95f1a02473044022023174c06060685d720e6c711922a07245083222df195fb75524c89b14a30606d02203eea3947bb6bdc65dae743823ee358817a688b9d39271f149c770777933793b401210357ef09bf2d5c536341f759d7d2825e64a9f5954a750250e7cd1fe4d2cf92b3d501403b17cc53283398a529d534a70835d6fe22f45e30d48d9c87e2d3d83b9173670a5280636b53724dd7822692826274c7058a58016038e1a690c7e6366d69d9a6d900000000042201612328b275fe8b89ec246b5ea9f1ce906e512795cfbfb00132c14243dbbfaabd0005fd02b40001000159026aeb6852b9e126728173b095a689ef6d6b94bd3d9d61fec3b1047269bda94a000000000f66697273742d697465737462757878dedfcaf730cec72f6dbea97c64d4a4f3489edc3c2ff8413ad169e9717a3b058d00000000000201000303fd025806fd022301fd021f0065000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002fd01b44a000176db3c90a94d1d88883b15f2ea49cea0db1a6b99df666bdb2f4717cc259d3c310000000000000258ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7ffd01660001000159026aeb6852b9e126728173b095a689ef6d6b94bd3d9d61fec3b1047269bda94a000000000f66697273742d697465737462757878dedfcaf730cec72f6dbea97c64d4a4f3489edc3c2ff8413ad169e9717a3b058d00000000000201000303fd025806ad01ab006507381c1ad9d4abbf3d4664a80dc13df3a271f73621a4c476d5faa099093d5f0800000001ea7d47abcbf3935868eb78ecfa55bcee3b1baa50554582770b85cf94184de99c025dc1551a12879e464751c5d58adc47170366eec5ea474d4f08069faf0ec4a8460142014030a59f8083dbf0f9a2cecb670fdaeede2c8f7162cdf016d9125fd5826ac5f13e64b587ba9c9224c71af999d495388ef16a9c8f00c28c8487ed84d30c676ca9920728fcf3a9d2bf6a83827c22662bfa10d095aa5dbc8d0ec54f3bd6e2ee3ab23d211d00000000000004b008020000092102ada2da3880c78b716154464311235543576a4a25519c6d7408f16562706a4d6c08020000092102b16a1dabf41be280943e505ee522d4c349250ef1b7c4a0cb197516659eb72709069f00040000000101210205bd63c9712513e6b573490780fcaecbc9c3fe29807cf6eb9b65067415c77f3d027400490001000120ea7d47abcbf3935868eb78ecfa55bcee3b1baa50554582770b85cf94184de99c02220000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff012700010001220000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff07f802c70004000000000121030e0b3b55c02f39e7c4c9ab09ffc94a3329c64fff6ebae8848936dce9526e30fc029c00710001000120ea7d47abcbf3935868eb78ecfa55bcee3b1baa50554582770b85cf94184de99c024a000126d95df7e2348c05a2e1b0d7a48473f4dba9128a1b948ec8c885ed667f1e95eb0000000000000258ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbf012700010001220000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff2e000400000002012102649b305eb6b54187ff5acccc35bce9e47feea1bf3adbfcdc1be38d4c55cf249a0303020101089f0004000000000121030e0b3b55c02f39e7c4c9ab09ffc94a3329c64fff6ebae8848936dce9526e30fc027400490001000120ea7d47abcbf3935868eb78ecfa55bcee3b1baa50554582770b85cf94184de99c02220000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff012700010001220000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0b42014065c422d0fee12eeccef954a2a9cad87b75eaedce45bd09af98a0a16d073b748740effa361e055bb28344a0a1523665dc10442ef9847208d7ab33b26eeff616c50c04000001bc \ No newline at end of file +54415050000400000000012461ee8f0acfbfd5f6493a5caeb2d8394560384b2b0ec17d4e0990406cc6e3e75b0000000102500000402092a9256d4b85021548627deb2c43f36af17910072d708295b778f5ad3f5bb87dd83ea06c46664e4315f7de9ee8d3506c71d82b40200cfc2541e68b86c4146a67c21c1b65ffff7f200600000003fd018c0200000000010204478bc55a872d647f4b68a48f6d8d2240d18d03b9370a7f38743f4827cd99430000000000ffffffff61ee8f0acfbfd5f6493a5caeb2d8394560384b2b0ec17d4e0990406cc6e3e75b01000000000000000003e80300000000000022512028fb02ae7f93d46f673d798597985b2e26f3caeba668be40eb215e7e3b4583c7e80300000000000022512032b6eeb107b144586f1134b285d9f0dcb432233188851829e131aa4478264ef325d0f50500000000225120dec8af6483c79fa7ea39bea834b92024acfe5c1b6ccdd66889048c2ca0a206600247304402207820ce964c23db5429446ea89d666b45d1b3c4fae30aec6894d34214ad0ed089022044d895c3ba0b30babbe5f927795ab186e5384bb25596e2623caeb94029ee64af0121032cbea8ed49a89ee5c69276349fb9fa4a98613ced896cacc4019c02c97314e77001403aff7a5dc8b6501541c36ad1500c5dd84f59f0c3d732e0417fe7bc28371704a5981b0a8bdfd57c592efaad8e0913b29b43ff97a0822d7ee6b65d3d4fdb1d3f9f000000000422015aa0323cf2cc7f34962f63618b77c9bb44c26c7d69fb7b25c9774e36b914f1890005fd02b40001000159000edf94014e8e647be631dc8f23a1a2ac762babf95e2110a04cc6d11c9039ff000000000f66697273742d69746573746275787872055b46e57b82693def0aab2e58eb4b78068238f3d62b84d89050b92fc2a6e500000000000201000303fd025806fd022301fd021f0065000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002fd01b44a0001e829447f0dd17d26880ba56a672caa4de2859a5d732799f39077d1ee48595d7b0000000000000258ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdffd01660001000159000edf94014e8e647be631dc8f23a1a2ac762babf95e2110a04cc6d11c9039ff000000000f66697273742d69746573746275787872055b46e57b82693def0aab2e58eb4b78068238f3d62b84d89050b92fc2a6e500000000000201000303fd025806ad01ab006561ee8f0acfbfd5f6493a5caeb2d8394560384b2b0ec17d4e0990406cc6e3e75b00000001e304927a992c3a1d81f50586301c1f055f59923c236b93704097d02fdcd9eb7802aee2739664013a7de5c6c324f520af0dda900e53fdde79d97caae61f53b8634b01420140cc16977679b45a50b64c03b363b95ca3389590495ca742018735f531d5ce3fe6b88dfda0637e06e6eba86e1cdd9f2df4e4cb96ff7c36effd1b50a73334674bd607281c6319db0fc74f357d435e6efd4406c54d6473fa35face18d29b47ecdf63a8c200000000000004b00802000009210294aab4886e65569873d588d86dbbb9a8785576b251261170a378a30b2af2d3d208020000092102995eefdf358055573f2f70106f09c208f86277e7ab7038edfe52a7e2003c06d9069f000400000001012103cdff2a9995874b27e2dc83ae878b7753c925d996339455982250d6c237adecba027400490001000120e304927a992c3a1d81f50586301c1f055f59923c236b93704097d02fdcd9eb7802220000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff012700010001220000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff07f802c700040000000001210260037c3b9987798745c48397b4651f2ee73d433f27aa3bb33f96744a6607b9f5029c00710001000120e304927a992c3a1d81f50586301c1f055f59923c236b93704097d02fdcd9eb78024a000111bf752ef14c9095b14932062e5be15755cecbcd8cd5f26473dbb0a6db1373630000000000000258ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f012700010001220000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff2e000400000002012102ff7b62b0ada51df1a354f19f71dd957868b062515f7c1ae5f6e63a4643f4170b0303020101089f00040000000001210260037c3b9987798745c48397b4651f2ee73d433f27aa3bb33f96744a6607b9f5027400490001000120e304927a992c3a1d81f50586301c1f055f59923c236b93704097d02fdcd9eb7802220000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff012700010001220000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0b4201400e5788a6d685c0aae69e29cc1178411d42e86d846505eec1b945c4ad24b88707b1fff685d69243efb70054852398881a4775c3fcd6178cda5347a60e84d3bd760c04000001bc \ No newline at end of file diff --git a/proof/testdata/proof-file.hex b/proof/testdata/proof-file.hex index e9dd3c6da..bcb9252ff 100644 --- a/proof/testdata/proof-file.hex +++ b/proof/testdata/proof-file.hex @@ -1 +1 @@ -544150460000000003fd03ae544150500004000000000124026aeb6852b9e126728173b095a689ef6d6b94bd3d9d61fec3b1047269bda94a0000000002500000402059b0e6557fb2b856b15fd4d4c2639330d33b0bd9afec7d631d2cdbd01cb1f657f1d6e23dbb05ec9f685635bf1bb7e1ab8fcd57652e34c24eba5ee0ac59e51b5a016a0865ffff7f200000000003f602000000000101026aeb6852b9e126728173b095a689ef6d6b94bd3d9d61fec3b1047269bda94a0000000000ffffffff02e803000000000000225120236c5808b93f883f906ca0376aff708bf134201050b312296a4288f42ddb23fd5cd5f505000000002251200b2278f01c9a023299df781e97d1b1b0b3439074520b3d04af5037276e53b3b40247304402207afd360d401e9f3b9b65a625a6acc811fb3aa2e156bada2b9351a86cd0388240022023d60132ee2337a56a4d0857f8f58a027b34ffadd15375c50c0f2dae728422e6012102609f61c627ecef1d03917f9c3a5bd1538aa41ead964495acd0809b79f265b1be00000000042201fc3b7a723b49db37b512d0cfa3c7a82cc7c3ec876b78db981689d6e0767316e40005f80001000159026aeb6852b9e126728173b095a689ef6d6b94bd3d9d61fec3b1047269bda94a000000000f66697273742d697465737462757878dedfcaf730cec72f6dbea97c64d4a4f3489edc3c2ff8413ad169e9717a3b058d00000000000201000303fd05dc06690167006500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000802000009210238d9be0d7b1927e9668fc1780c57fc393f98d82e0f4b342be0787d3c2ee706f906c700040000000001210211d51ac1ce0db381304040cd098adbfb0c0ff4f5bb858dd0f601d9ba403a194c029c00490001000120ea7d47abcbf3935868eb78ecfa55bcee3b1baa50554582770b85cf94184de99c02220000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff014f000100014a00010af283fc2adee4aa40c4b2ed45b042d43d10a72c5e5f75d6c2a9ffb9fec5372400000000000007d0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f0730012e000400000001012102f79b0250bf95d352830296036208cb71afd87b17194ed8d10dc53452b034162403030201010913000100010e69746573742d6d657461646174610c04000001b902f917f4cb24aac0a4bbe49a8904369c565770034dff3b68e08c91b7d6d096e5fd078354415050000400000000012435b5828c631487594abf9bf93afe6f32228f19230c74d9f5c6c3025cb61805d6000000000250000040207f03dbadf3fe48f8197c542f8672d8a08fc25a6197334ad25f0c883b9a4e3d2bc14c773343aeb483f76ce7984c1fae4c16ca10ac6775a303c23c09728af24c75016a0865ffff7f200200000003fd018d020000000001020680d31d053e99fd4d7a05629714af8965179a10817119235b9d65b15d543e2c0000000000ffffffff35b5828c631487594abf9bf93afe6f32228f19230c74d9f5c6c3025cb61805d600000000000000000003e8030000000000002251203026afffa7c1ae44bfc8be0dd4330e1b39dc3c24643687df9a6ac39f6784fbe6e8030000000000002251208233c433a3ed62870bbd76ddb75cef159e7e7620d84c53426178dea384d38c5725d0f5050000000022512064bc6a13119fba156f9151b314ee27d2475504c5b55dfbb67ab15bbe1a17090602483045022100894ed4d986076ee45d0aabd189d47b69791e55c860ccd78f86c8fecf270ca0d8022015cc3da88b7b76581358b642a9c6cb512315b4b7a5f6273b1e1d2fef7d5d01b1012102ce4b86727aa44c70ec1bb03808d0d18346adb4bca9f0e84ee16de53c7bf498c70140fdd3e845797fd13bceef5d226555e9a593e601224dadb9fde1a70cef8154f049f59c0cb930a7313778258bfbcc40dd4675bc86b06c7b9ae14cd6a4551b284b120000000004220192cf57460c5344edca33932b286f16042ea5921f11b71218601762c2f923e9420005fd02b40001000159026aeb6852b9e126728173b095a689ef6d6b94bd3d9d61fec3b1047269bda94a000000000f66697273742d697465737462757878dedfcaf730cec72f6dbea97c64d4a4f3489edc3c2ff8413ad169e9717a3b058d00000000000201000303fd04b006fd022301fd021f0065000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002fd01b44a0001be0fe4b9e225cbb4f4ddfe05048a23e7469f52599f46f23bf53ac2ad795811c6000000000000012cffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7ffd01660001000159026aeb6852b9e126728173b095a689ef6d6b94bd3d9d61fec3b1047269bda94a000000000f66697273742d697465737462757878dedfcaf730cec72f6dbea97c64d4a4f3489edc3c2ff8413ad169e9717a3b058d00000000000201000303fd012c06ad01ab006535b5828c631487594abf9bf93afe6f32228f19230c74d9f5c6c3025cb61805d600000000ea7d47abcbf3935868eb78ecfa55bcee3b1baa50554582770b85cf94184de99c0238d9be0d7b1927e9668fc1780c57fc393f98d82e0f4b342be0787d3c2ee706f901420140972817a9848b677b44232f2d67b62b609eb36024389bdb11365a484cbf00a2d79eb13409aeb12883e35c739f7e934fe88d05020c75f148fdbbf618fce69a2f620728e37e4f2dd531f4cce52f9f1e19dda65e6db1b3fcff797eb4aafd4bdc26d36abc00000000000005dc080200000921025afa47611c1083b459846b54c6f17da8e188a323e0c0e2a15be0c188aae8ad14080200000921025dc1551a12879e464751c5d58adc47170366eec5ea474d4f08069faf0ec4a846069f000400000001012102aa01ca611dcc3ac2054da4d48ed1e304409e3fa28f109b9b267efe57791dc9c3027400490001000120ea7d47abcbf3935868eb78ecfa55bcee3b1baa50554582770b85cf94184de99c02220000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff012700010001220000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff07fd012002ef000400000000012103d40f66bd36bb9fd86c93e01e37667f9dd464f7de4eaa7bcdd8ff9d8e844e6e4f02c400710001000120ea7d47abcbf3935868eb78ecfa55bcee3b1baa50554582770b85cf94184de99c024a000123687967d493575aa2b80a0444e4d7d29e01cd9253a36273340ef90f31c65843000000000000012cffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f014f000100014a0001667067559e7e7080a9a275e7daa660c6656980a683e36d2c8dce71dbcd0bc74100000000000007d0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f2e000400000002012102cd39142f8263fbdcb58ff1b26a1ef6334d0c7da96da4e6ebffa268e059817023030302010108c7000400000000012103d40f66bd36bb9fd86c93e01e37667f9dd464f7de4eaa7bcdd8ff9d8e844e6e4f029c00490001000120ea7d47abcbf3935868eb78ecfa55bcee3b1baa50554582770b85cf94184de99c02220000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff014f000100014a0001667067559e7e7080a9a275e7daa660c6656980a683e36d2c8dce71dbcd0bc74100000000000007d0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f0c04000001ba48d5c560fd9bd72b09c083a322934fdeaaad25a3cd902610e81fd4eab2313052fd073054415050000400000000012407381c1ad9d4abbf3d4664a80dc13df3a271f73621a4c476d5faa099093d5f08000000010250000040205c9c7f10746d49a143742948cacb2edc063481a6f1fa5492a9f0299346fce325629fa06a4bdb830586733e8351911235692d1fad7664894793de4d223017583a016a0865ffff7f200000000003fd018c0200000000010203f8ac0fa47f7eaf42dbf8ec9b135849dcd49b69ffe980b6ecf88293a0b143ba0000000000ffffffff07381c1ad9d4abbf3d4664a80dc13df3a271f73621a4c476d5faa099093d5f0801000000000000000003e803000000000000225120a914766a8a19bb8cc1fe8c17f411aae5fc6841fea6b807ce73d66ebdabf08d52e80300000000000022512087a21c8d7a5d3d0bea676166a83bfcf12ae3c92b7f14bc1fff7d54820eda441a25d0f50500000000225120fe19c6b74a18eccd85988ed33b3d3204e4ccc8f43c2a10b3958d0a9cf6d95f1a02473044022023174c06060685d720e6c711922a07245083222df195fb75524c89b14a30606d02203eea3947bb6bdc65dae743823ee358817a688b9d39271f149c770777933793b401210357ef09bf2d5c536341f759d7d2825e64a9f5954a750250e7cd1fe4d2cf92b3d501403b17cc53283398a529d534a70835d6fe22f45e30d48d9c87e2d3d83b9173670a5280636b53724dd7822692826274c7058a58016038e1a690c7e6366d69d9a6d900000000042201612328b275fe8b89ec246b5ea9f1ce906e512795cfbfb00132c14243dbbfaabd0005fd02b40001000159026aeb6852b9e126728173b095a689ef6d6b94bd3d9d61fec3b1047269bda94a000000000f66697273742d697465737462757878dedfcaf730cec72f6dbea97c64d4a4f3489edc3c2ff8413ad169e9717a3b058d00000000000201000303fd025806fd022301fd021f0065000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002fd01b44a000176db3c90a94d1d88883b15f2ea49cea0db1a6b99df666bdb2f4717cc259d3c310000000000000258ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7ffd01660001000159026aeb6852b9e126728173b095a689ef6d6b94bd3d9d61fec3b1047269bda94a000000000f66697273742d697465737462757878dedfcaf730cec72f6dbea97c64d4a4f3489edc3c2ff8413ad169e9717a3b058d00000000000201000303fd025806ad01ab006507381c1ad9d4abbf3d4664a80dc13df3a271f73621a4c476d5faa099093d5f0800000001ea7d47abcbf3935868eb78ecfa55bcee3b1baa50554582770b85cf94184de99c025dc1551a12879e464751c5d58adc47170366eec5ea474d4f08069faf0ec4a8460142014030a59f8083dbf0f9a2cecb670fdaeede2c8f7162cdf016d9125fd5826ac5f13e64b587ba9c9224c71af999d495388ef16a9c8f00c28c8487ed84d30c676ca9920728fcf3a9d2bf6a83827c22662bfa10d095aa5dbc8d0ec54f3bd6e2ee3ab23d211d00000000000004b008020000092102ada2da3880c78b716154464311235543576a4a25519c6d7408f16562706a4d6c08020000092102b16a1dabf41be280943e505ee522d4c349250ef1b7c4a0cb197516659eb72709069f00040000000101210205bd63c9712513e6b573490780fcaecbc9c3fe29807cf6eb9b65067415c77f3d027400490001000120ea7d47abcbf3935868eb78ecfa55bcee3b1baa50554582770b85cf94184de99c02220000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff012700010001220000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff07f802c70004000000000121030e0b3b55c02f39e7c4c9ab09ffc94a3329c64fff6ebae8848936dce9526e30fc029c00710001000120ea7d47abcbf3935868eb78ecfa55bcee3b1baa50554582770b85cf94184de99c024a000126d95df7e2348c05a2e1b0d7a48473f4dba9128a1b948ec8c885ed667f1e95eb0000000000000258ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbf012700010001220000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff2e000400000002012102649b305eb6b54187ff5acccc35bce9e47feea1bf3adbfcdc1be38d4c55cf249a0303020101089f0004000000000121030e0b3b55c02f39e7c4c9ab09ffc94a3329c64fff6ebae8848936dce9526e30fc027400490001000120ea7d47abcbf3935868eb78ecfa55bcee3b1baa50554582770b85cf94184de99c02220000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff012700010001220000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0c04000001bc01451f0494a722cdc9293af0349f3e7b357bcaa29e4bd8ee663b3bbfc08d3a48 \ No newline at end of file +544150460000000003fd0409544150500004000000000124000edf94014e8e647be631dc8f23a1a2ac762babf95e2110a04cc6d11c9039ff000000000250000040206d90e787c44222007fa2df8e64ec650e9ba64ed648736185577b25e5d5e06d576751a9b27c13a580b3219f2bef54e0655e7e152b315efc1611fa601103d1b400c21c1b65ffff7f200000000003f602000000000101000edf94014e8e647be631dc8f23a1a2ac762babf95e2110a04cc6d11c9039ff0000000000ffffffff02e8030000000000002251209f19d16ebf0c9db6bcd66c20bdec8ce77686cf2e60ce98166921bd83fe03ad055cd5f50500000000225120acc12eab663fb6f8f90dcf3d91c483037a67fdd75d3216490d5611e7f200aebb0247304402203c15338ec7b6d08f7b2e420bfcab4949daa20e14b447c55c438b5275b774ab66022057d834bc625fe1e99cfe9bc2cf9dbe4b54c81d1afe299574cc45a9a8560901e101210393c4b6c16602cd15501cd7d4621bb1d76d7ff6cf17b936ba9a0d18502ac176c800000000042201128458ebad6cea222ea2e72730cc0bebea65f5468b66ab51f4ab78a8036aeae20005f80001000159000edf94014e8e647be631dc8f23a1a2ac762babf95e2110a04cc6d11c9039ff000000000f66697273742d69746573746275787872055b46e57b82693def0aab2e58eb4b78068238f3d62b84d89050b92fc2a6e500000000000201000303fd05dc066901670065000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008020000092102c06945dc5098fb3e2de9cd4b9aa02dfaf1858cf41199304059c91cafdeadffa906c7000400000000012103362012747699f7831e77c94521bf9fe0c2ac5c0531fa1564325e635291014699029c00490001000120e304927a992c3a1d81f50586301c1f055f59923c236b93704097d02fdcd9eb7802220000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff014f000100014a00010dd71200ea8127c566c152d000934e4092b4dc21127637980ac2294a19fe7d2200000000000007d0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbf0730012e0004000000010121027c2a94ef87bc6410a98e7334db8898a4dee8687cf2306ace7fd6a2720947ac9603030201010913000101010e69746573742d6d657461646174610c04000001b90d59000edf94014e8e647be631dc8f23a1a2ac762babf95e2110a04cc6d11c9039ff000000000f66697273742d69746573746275787872055b46e57b82693def0aab2e58eb4b78068238f3d62b84d89050b92fc2a6e500000000002d09be86b8d537e3434ee0f35c2178f1d2b1ff4318ca14f0ec0b12bb4f47081efd078254415050000400000000012484dd2562af1bca18f71bb72c54faa9464344fb822767c028b4945a100db695cd000000000250000040206ac527aa0f3ff4e880c7dfcb2f0b95f5e05b4380eae337a02f15cd2b1a8bc0446ffd76fbc54c437c8424fc17e6f8e2d81b0cfa83014ee31c41bb2f6ef5ec1a1fc21c1b65ffff7f200100000003fd018c020000000001028a46df72ee521269648983dac8216d0d6925590b83b157263e45244aeb8302040000000000ffffffff84dd2562af1bca18f71bb72c54faa9464344fb822767c028b4945a100db695cd00000000000000000003e8030000000000002251209c107483f86a56f53e9f6bfb02be5b8c1b01fb8a579a80128a89c5f0534ffd6ce803000000000000225120e016af66bb25dec6174eb55094ed7e901c82dd82d9c4dc4a65f7a268a53a408925d0f5050000000022512047b4284f3d5b066a61acf172d27814392a41729b6cec0b721ff450f26e77454f0247304402202fa5096b8561d841ccb48308495072180cf29ce1eb3072838e5fe860bdf0cbf102200da38e6bc0b13feb6bcab2917af1ed32d006a29e04de5806446888cb9bcfccfe012102597566522e2ea567e32bad2329119c6d34597ced654179ea28f99328d86addb30140b602be182cbae6779c7260c9c2f418751b2c36e9eb7ef9061b1705713c6813b524bda304c436d45af383fc59d366a12137929e7ec32c3e73b9dd5d6fdfea2f8100000000042201ec7ca1e248a085a7f4923e75a2aca9261363f69da30fea64b3216312b7c51a3c0005fd02b40001000159000edf94014e8e647be631dc8f23a1a2ac762babf95e2110a04cc6d11c9039ff000000000f66697273742d69746573746275787872055b46e57b82693def0aab2e58eb4b78068238f3d62b84d89050b92fc2a6e500000000000201000303fd04b006fd022301fd021f0065000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002fd01b44a0001283e580e7adec8cd31c6de2731d02a66805e9fdee68dc431ddd91abefe88ae46000000000000012cffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7ffd01660001000159000edf94014e8e647be631dc8f23a1a2ac762babf95e2110a04cc6d11c9039ff000000000f66697273742d69746573746275787872055b46e57b82693def0aab2e58eb4b78068238f3d62b84d89050b92fc2a6e500000000000201000303fd012c06ad01ab006584dd2562af1bca18f71bb72c54faa9464344fb822767c028b4945a100db695cd00000000e304927a992c3a1d81f50586301c1f055f59923c236b93704097d02fdcd9eb7802c06945dc5098fb3e2de9cd4b9aa02dfaf1858cf41199304059c91cafdeadffa9014201405ecbbad87c0d10eb4add9fad29855cac988b00aec245e280279e41f00dc1d7058366a1640ae62ae13ea999dec1eaf0bd3ec6294d0856880a21dd6cb74c2da7020728780d3433f32490d520b08c284474dd7a466884bd30b699f91ed26d0954eebfba00000000000005dc08020000092102a249cc2b97c7e9177be1618f0bb0e198df9255742fc43535b62a74a28665dd2208020000092102aee2739664013a7de5c6c324f520af0dda900e53fdde79d97caae61f53b8634b069f000400000001012102841246205825ef81c3ff94c0a06e54729478969021b56d3f12bc5c03cb05a2d8027400490001000120e304927a992c3a1d81f50586301c1f055f59923c236b93704097d02fdcd9eb7802220000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff012700010001220000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff07fd012002ef000400000000012102877e26cda63f3132fdc8c8014a7c7e3af61fc0a65fd53a7aa3e29e9bc61f1f0e02c400710001000120e304927a992c3a1d81f50586301c1f055f59923c236b93704097d02fdcd9eb78024a00016d94f8a19c6342c684b4ef2aadf0501ef73e2241b22cc9450732e1a8b768424a000000000000012cffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdf014f000100014a00016b23e7898ae748e0535d806f4db0d0e76489849c2b149ba4498a7f054f72aad800000000000007d0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbf2e000400000002012102c151dec9d86d14ee166c98859e54324bbf7e1f07921ab0a6feaad10c3f2780af030302010108c7000400000000012102877e26cda63f3132fdc8c8014a7c7e3af61fc0a65fd53a7aa3e29e9bc61f1f0e029c00490001000120e304927a992c3a1d81f50586301c1f055f59923c236b93704097d02fdcd9eb7802220000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff014f000100014a00016b23e7898ae748e0535d806f4db0d0e76489849c2b149ba4498a7f054f72aad800000000000007d0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbf0c04000001ba83779e6b009aa3b564c5c273cd3ae0969df8395442897b683cfe7a0cfd3fc833fd073054415050000400000000012461ee8f0acfbfd5f6493a5caeb2d8394560384b2b0ec17d4e0990406cc6e3e75b0000000102500000402092a9256d4b85021548627deb2c43f36af17910072d708295b778f5ad3f5bb87dd83ea06c46664e4315f7de9ee8d3506c71d82b40200cfc2541e68b86c4146a67c21c1b65ffff7f200600000003fd018c0200000000010204478bc55a872d647f4b68a48f6d8d2240d18d03b9370a7f38743f4827cd99430000000000ffffffff61ee8f0acfbfd5f6493a5caeb2d8394560384b2b0ec17d4e0990406cc6e3e75b01000000000000000003e80300000000000022512028fb02ae7f93d46f673d798597985b2e26f3caeba668be40eb215e7e3b4583c7e80300000000000022512032b6eeb107b144586f1134b285d9f0dcb432233188851829e131aa4478264ef325d0f50500000000225120dec8af6483c79fa7ea39bea834b92024acfe5c1b6ccdd66889048c2ca0a206600247304402207820ce964c23db5429446ea89d666b45d1b3c4fae30aec6894d34214ad0ed089022044d895c3ba0b30babbe5f927795ab186e5384bb25596e2623caeb94029ee64af0121032cbea8ed49a89ee5c69276349fb9fa4a98613ced896cacc4019c02c97314e77001403aff7a5dc8b6501541c36ad1500c5dd84f59f0c3d732e0417fe7bc28371704a5981b0a8bdfd57c592efaad8e0913b29b43ff97a0822d7ee6b65d3d4fdb1d3f9f000000000422015aa0323cf2cc7f34962f63618b77c9bb44c26c7d69fb7b25c9774e36b914f1890005fd02b40001000159000edf94014e8e647be631dc8f23a1a2ac762babf95e2110a04cc6d11c9039ff000000000f66697273742d69746573746275787872055b46e57b82693def0aab2e58eb4b78068238f3d62b84d89050b92fc2a6e500000000000201000303fd025806fd022301fd021f0065000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002fd01b44a0001e829447f0dd17d26880ba56a672caa4de2859a5d732799f39077d1ee48595d7b0000000000000258ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdffd01660001000159000edf94014e8e647be631dc8f23a1a2ac762babf95e2110a04cc6d11c9039ff000000000f66697273742d69746573746275787872055b46e57b82693def0aab2e58eb4b78068238f3d62b84d89050b92fc2a6e500000000000201000303fd025806ad01ab006561ee8f0acfbfd5f6493a5caeb2d8394560384b2b0ec17d4e0990406cc6e3e75b00000001e304927a992c3a1d81f50586301c1f055f59923c236b93704097d02fdcd9eb7802aee2739664013a7de5c6c324f520af0dda900e53fdde79d97caae61f53b8634b01420140cc16977679b45a50b64c03b363b95ca3389590495ca742018735f531d5ce3fe6b88dfda0637e06e6eba86e1cdd9f2df4e4cb96ff7c36effd1b50a73334674bd607281c6319db0fc74f357d435e6efd4406c54d6473fa35face18d29b47ecdf63a8c200000000000004b00802000009210294aab4886e65569873d588d86dbbb9a8785576b251261170a378a30b2af2d3d208020000092102995eefdf358055573f2f70106f09c208f86277e7ab7038edfe52a7e2003c06d9069f000400000001012103cdff2a9995874b27e2dc83ae878b7753c925d996339455982250d6c237adecba027400490001000120e304927a992c3a1d81f50586301c1f055f59923c236b93704097d02fdcd9eb7802220000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff012700010001220000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff07f802c700040000000001210260037c3b9987798745c48397b4651f2ee73d433f27aa3bb33f96744a6607b9f5029c00710001000120e304927a992c3a1d81f50586301c1f055f59923c236b93704097d02fdcd9eb78024a000111bf752ef14c9095b14932062e5be15755cecbcd8cd5f26473dbb0a6db1373630000000000000258ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f012700010001220000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff2e000400000002012102ff7b62b0ada51df1a354f19f71dd957868b062515f7c1ae5f6e63a4643f4170b0303020101089f00040000000001210260037c3b9987798745c48397b4651f2ee73d433f27aa3bb33f96744a6607b9f5027400490001000120e304927a992c3a1d81f50586301c1f055f59923c236b93704097d02fdcd9eb7802220000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff012700010001220000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0c04000001bcd40ac5e6265312abaf3165622c02bfa402a1c659d966914a54e1074bba5df754 \ No newline at end of file diff --git a/proof/testdata/proof.hex b/proof/testdata/proof.hex index 6247321fa..dbd819a24 100644 --- a/proof/testdata/proof.hex +++ b/proof/testdata/proof.hex @@ -1 +1 @@ -54415050000400000000012435b5828c631487594abf9bf93afe6f32228f19230c74d9f5c6c3025cb61805d6000000000250000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000096e88000000000000000003fd018d020000000001020680d31d053e99fd4d7a05629714af8965179a10817119235b9d65b15d543e2c0000000000ffffffff35b5828c631487594abf9bf93afe6f32228f19230c74d9f5c6c3025cb61805d600000000000000000003e8030000000000002251203026afffa7c1ae44bfc8be0dd4330e1b39dc3c24643687df9a6ac39f6784fbe6e8030000000000002251208233c433a3ed62870bbd76ddb75cef159e7e7620d84c53426178dea384d38c5725d0f5050000000022512064bc6a13119fba156f9151b314ee27d2475504c5b55dfbb67ab15bbe1a17090602483045022100894ed4d986076ee45d0aabd189d47b69791e55c860ccd78f86c8fecf270ca0d8022015cc3da88b7b76581358b642a9c6cb512315b4b7a5f6273b1e1d2fef7d5d01b1012102ce4b86727aa44c70ec1bb03808d0d18346adb4bca9f0e84ee16de53c7bf498c70140fdd3e845797fd13bceef5d226555e9a593e601224dadb9fde1a70cef8154f049f59c0cb930a7313778258bfbcc40dd4675bc86b06c7b9ae14cd6a4551b284b120000000004010005fd01660001000159026aeb6852b9e126728173b095a689ef6d6b94bd3d9d61fec3b1047269bda94a000000000f66697273742d697465737462757878dedfcaf730cec72f6dbea97c64d4a4f3489edc3c2ff8413ad169e9717a3b058d00000000000201000303fd012c06ad01ab006535b5828c631487594abf9bf93afe6f32228f19230c74d9f5c6c3025cb61805d600000000ea7d47abcbf3935868eb78ecfa55bcee3b1baa50554582770b85cf94184de99c0238d9be0d7b1927e9668fc1780c57fc393f98d82e0f4b342be0787d3c2ee706f901420140972817a9848b677b44232f2d67b62b609eb36024389bdb11365a484cbf00a2d79eb13409aeb12883e35c739f7e934fe88d05020c75f148fdbbf618fce69a2f620728e37e4f2dd531f4cce52f9f1e19dda65e6db1b3fcff797eb4aafd4bdc26d36abc00000000000005dc080200000921025afa47611c1083b459846b54c6f17da8e188a323e0c0e2a15be0c188aae8ad1406c7000400000000012103d40f66bd36bb9fd86c93e01e37667f9dd464f7de4eaa7bcdd8ff9d8e844e6e4f029c00490001000120ea7d47abcbf3935868eb78ecfa55bcee3b1baa50554582770b85cf94184de99c02220000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff014f000100014a0001667067559e7e7080a9a275e7daa660c6656980a683e36d2c8dce71dbcd0bc74100000000000007d0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f07f802c7000400000001012102aa01ca611dcc3ac2054da4d48ed1e304409e3fa28f109b9b267efe57791dc9c3029c00710001000120ea7d47abcbf3935868eb78ecfa55bcee3b1baa50554582770b85cf94184de99c024a0001b42fc7a58d9b915d5bfd72c45193cf7c49a848db1ae5126372921e9807a63d9f00000000000004b0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f012700010001220000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff2e000400000002012102cd39142f8263fbdcb58ff1b26a1ef6334d0c7da96da4e6ebffa268e05981702303030201010c0400000000 \ No newline at end of file +54415050000400000000012484dd2562af1bca18f71bb72c54faa9464344fb822767c028b4945a100db695cd000000000250000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000096e88000000000000000003fd018c020000000001028a46df72ee521269648983dac8216d0d6925590b83b157263e45244aeb8302040000000000ffffffff84dd2562af1bca18f71bb72c54faa9464344fb822767c028b4945a100db695cd00000000000000000003e8030000000000002251209c107483f86a56f53e9f6bfb02be5b8c1b01fb8a579a80128a89c5f0534ffd6ce803000000000000225120e016af66bb25dec6174eb55094ed7e901c82dd82d9c4dc4a65f7a268a53a408925d0f5050000000022512047b4284f3d5b066a61acf172d27814392a41729b6cec0b721ff450f26e77454f0247304402202fa5096b8561d841ccb48308495072180cf29ce1eb3072838e5fe860bdf0cbf102200da38e6bc0b13feb6bcab2917af1ed32d006a29e04de5806446888cb9bcfccfe012102597566522e2ea567e32bad2329119c6d34597ced654179ea28f99328d86addb30140b602be182cbae6779c7260c9c2f418751b2c36e9eb7ef9061b1705713c6813b524bda304c436d45af383fc59d366a12137929e7ec32c3e73b9dd5d6fdfea2f810000000004010005fd01660001000159000edf94014e8e647be631dc8f23a1a2ac762babf95e2110a04cc6d11c9039ff000000000f66697273742d69746573746275787872055b46e57b82693def0aab2e58eb4b78068238f3d62b84d89050b92fc2a6e500000000000201000303fd012c06ad01ab006584dd2562af1bca18f71bb72c54faa9464344fb822767c028b4945a100db695cd00000000e304927a992c3a1d81f50586301c1f055f59923c236b93704097d02fdcd9eb7802c06945dc5098fb3e2de9cd4b9aa02dfaf1858cf41199304059c91cafdeadffa9014201405ecbbad87c0d10eb4add9fad29855cac988b00aec245e280279e41f00dc1d7058366a1640ae62ae13ea999dec1eaf0bd3ec6294d0856880a21dd6cb74c2da7020728780d3433f32490d520b08c284474dd7a466884bd30b699f91ed26d0954eebfba00000000000005dc08020000092102a249cc2b97c7e9177be1618f0bb0e198df9255742fc43535b62a74a28665dd2206c7000400000000012102877e26cda63f3132fdc8c8014a7c7e3af61fc0a65fd53a7aa3e29e9bc61f1f0e029c00490001000120e304927a992c3a1d81f50586301c1f055f59923c236b93704097d02fdcd9eb7802220000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff014f000100014a00016b23e7898ae748e0535d806f4db0d0e76489849c2b149ba4498a7f054f72aad800000000000007d0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbf07f802c7000400000001012102841246205825ef81c3ff94c0a06e54729478969021b56d3f12bc5c03cb05a2d8029c00710001000120e304927a992c3a1d81f50586301c1f055f59923c236b93704097d02fdcd9eb78024a0001a048be6ca5cebfe16843a018f64bccafd0b08fab3b3fe2098256d3a37e60663600000000000004b0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdf012700010001220000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff2e000400000002012102c151dec9d86d14ee166c98859e54324bbf7e1f07921ab0a6feaad10c3f2780af03030201010c0400000000 \ No newline at end of file diff --git a/proof/testdata/proof_tlv_encoding_generated.json b/proof/testdata/proof_tlv_encoding_generated.json index 68a1f6225..ffe15c375 100644 --- a/proof/testdata/proof_tlv_encoding_generated.json +++ b/proof/testdata/proof_tlv_encoding_generated.json @@ -2,17 +2,17 @@ "valid_test_cases": [ { "proof": { - "prev_out": "0000000000000000000000000000000000000000000000000000000000000000:0", + "prev_out": "8d73ec3f2525632186845c95d4491d1b3a768b7c4e0b6804951aa42655d9b95f:2092150027", "block_header": { "version": 0, "prev_block": "000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f", - "merkle_root": "7c398ca415b53c871396d26bbc2a7143724f86636c24dee99ca3770b08c74d59", + "merkle_root": "f39a9499680a05f4394194865476f11839cfb7aec210f768ca83d28cb997b1f5", "timestamp": 1473417797, "bits": 0, "nonce": 0 }, "block_height": 1, - "anchor_tx": "02000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000014a010000000000002251209875adf76b8b09e6bb3a93203aedfcd3b2700e682d50d5589f906cfe29a82dea00000000", + "anchor_tx": "02000000015fb9d95526a41a9504680b4e7c8b763a1b1d49d4955c8486216325253fec738d0badb37c0000000000014a010000000000002251203384f104e01f413b89d7d9fb03f4766b9013dd6b1866509a7b7886f2a1ae103000000000", "tx_merkle_proof": { "nodes": [], "bits": [] @@ -22,7 +22,7 @@ "genesis_first_prev_out": "8d73ec3f2525632186845c95d4491d1b3a768b7c4e0b6804951aa42655d9b95f:2092150027", "genesis_tag": "eb9d18a44784045d87f3c67cf22746e995af5a25367951baa2ff6cd471c483f1", "genesis_meta_hash": "0000000000000000000000000000000000000000000000000000000000000000", - "genesis_output_index": 379326753, + "genesis_output_index": 0, "genesis_type": 1, "amount": 1, "lock_time": 0, @@ -34,7 +34,9 @@ "asset_id": "0000000000000000000000000000000000000000000000000000000000000000", "script_key": "000000000000000000000000000000000000000000000000000000000000000000" }, - "tx_witness": null, + "tx_witness": [ + "77cd8c7f71035ac619023bedeab474a0c68779403143173b620e0beb6f73088ccb01458003e502daa2ac1994804404aee1e6f305310fedcdb05a5047bd8dae1e" + ], "split_commitment": null } ], @@ -42,7 +44,7 @@ "script_version": 0, "script_key": "0250fb435f8fc76fc75736ac89956406e882a468e929da69ca596a716ebcfa8516", "group_key": { - "group_key": "02f51bdc1380b8021dca065edf24ee521a4d6d5ceba51abb7877df544e93acc319" + "group_key": "02a9d7d88008817398f9d8b47f6b954139f23f3cb235eaa701395fb0efa6e11ccd" } }, "inclusion_proof": { @@ -53,7 +55,7 @@ "asset_proof": { "proof": "0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "version": 0, - "asset_id": "af542dec7585eaac495164faeb9c68ebc8b4d8e571a553d6732006063466b65d" + "asset_id": "1624d9703a0fea948dd97385753c57c8225b9421af0ec87d4c92a4832a01b03c" }, "taproot_asset_proof": { "proof": "0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", @@ -68,24 +70,35 @@ "split_root_proof": null, "meta_reveal": null, "additional_inputs": null, - "challenge_witness": null + "challenge_witness": null, + "genesis_reveal": { + "first_prev_out": "8d73ec3f2525632186845c95d4491d1b3a768b7c4e0b6804951aa42655d9b95f:2092150027", + "tag": "eb9d18a44784045d87f3c67cf22746e995af5a25367951baa2ff6cd471c483f1", + "meta_hash": "0000000000000000000000000000000000000000000000000000000000000000", + "output_index": 0, + "type": 1 + }, + "group_key_reveal": { + "raw_key": "03133c4a2dd92ef1f92fe3bd78e080dcb50e03057acdecf0365143b69687f7ea3a", + "tapscript_root": "" + } }, - "expected": "5441505000040000000001240000000000000000000000000000000000000000000000000000000000000000000000000250000000006fe28c0ab6f1b372c1a6a246ae63f74f931e8365e15a089c68d6190000000000594dc7080b77a39ce9de246c63864f7243712abc6bd29613873cb515a48c397c4592d2570000000000000000035e02000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000014a010000000000002251209875adf76b8b09e6bb3a93203aedfcd3b2700e682d50d5589f906cfe29a82dea0000000004010005fd014a000100018a5fb9d95526a41a9504680b4e7c8b763a1b1d49d4955c8486216325253fec738d7cb3ad0b40656239643138613434373834303435643837663363363763663232373436653939356166356132353336373935316261613266663663643437316334383366310000000000000000000000000000000000000000000000000000000000000000169c11210102010103010106690167006500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000802000009210250fb435f8fc76fc75736ac89956406e882a468e929da69ca596a716ebcfa85160a2102f51bdc1380b8021dca065edf24ee521a4d6d5ceba51abb7877df544e93acc319069f0004000000000121024a821d5ec008712983929de448b8afb6c24e5a1b97367b9a65b6220d7f083fe3027400490001000120af542dec7585eaac495164faeb9c68ebc8b4d8e571a553d6732006063466b65d02220000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff012700010001220000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0c0400000001", + "expected": "5441505000040000000001245fb9d95526a41a9504680b4e7c8b763a1b1d49d4955c8486216325253fec738d7cb3ad0b0250000000006fe28c0ab6f1b372c1a6a246ae63f74f931e8365e15a089c68d6190000000000f5b197b98cd283ca68f710c2aeb7cf3918f1765486944139f4050a6899949af34592d2570000000000000000035e02000000015fb9d95526a41a9504680b4e7c8b763a1b1d49d4955c8486216325253fec738d0badb37c0000000000014a010000000000002251203384f104e01f413b89d7d9fb03f4766b9013dd6b1866509a7b7886f2a1ae10300000000004010005fd018e000100018a5fb9d95526a41a9504680b4e7c8b763a1b1d49d4955c8486216325253fec738d7cb3ad0b40656239643138613434373834303435643837663363363763663232373436653939356166356132353336373935316261613266663663643437316334383366310000000000000000000000000000000000000000000000000000000000000000000000000102010103010106ad01ab006500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000142014077cd8c7f71035ac619023bedeab474a0c68779403143173b620e0beb6f73088ccb01458003e502daa2ac1994804404aee1e6f305310fedcdb05a5047bd8dae1e0802000009210250fb435f8fc76fc75736ac89956406e882a468e929da69ca596a716ebcfa85160a2102a9d7d88008817398f9d8b47f6b954139f23f3cb235eaa701395fb0efa6e11ccd069f0004000000000121024a821d5ec008712983929de448b8afb6c24e5a1b97367b9a65b6220d7f083fe30274004900010001201624d9703a0fea948dd97385753c57c8225b9421af0ec87d4c92a4832a01b03c02220000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff012700010001220000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0c04000000010d8a5fb9d95526a41a9504680b4e7c8b763a1b1d49d4955c8486216325253fec738d7cb3ad0b4065623964313861343437383430343564383766336336376366323237343665393935616635613235333637393531626161326666366364343731633438336631000000000000000000000000000000000000000000000000000000000000000000000000010e2103133c4a2dd92ef1f92fe3bd78e080dcb50e03057acdecf0365143b69687f7ea3a", "comment": "collectible genesis" }, { "proof": { - "prev_out": "0000000000000000000000000000000000000000000000000000000000000000:0", + "prev_out": "3f71f8cb984b92f67403049442fd5ad145f49143f7f4a5ee3b22b02936d4ff9b:4165004363", "block_header": { "version": 0, "prev_block": "000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f", - "merkle_root": "0e75350a1a5e343176c9f624bf8a278b437aa2a437e6e271460c59fe979855ba", + "merkle_root": "b7eb3c9c5b61c64dde9fb8b248cc254baa9185c4290faa9d7ff0dad2313f725f", "timestamp": 424111158, "bits": 0, "nonce": 0 }, "block_height": 1, - "anchor_tx": "02000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000014a010000000000002251208fce04edce8bf1a34b382a3c402e0067edcd84cbfc533e4b270f55f5171ca1d600000000", + "anchor_tx": "02000000019bffd43629b0223beea5f4f74391f445d15afd4294040374f6924b98cbf8713f4bec40f80000000000014a01000000000000225120da9d7845eb9b2a597edd6c818c59506a061c95747b897a49519468410ce4a86a00000000", "tx_merkle_proof": { "nodes": [], "bits": [] @@ -95,7 +108,7 @@ "genesis_first_prev_out": "3f71f8cb984b92f67403049442fd5ad145f49143f7f4a5ee3b22b02936d4ff9b:4165004363", "genesis_tag": "bb358b0c3b525da1786f9fff094279db1944ebd7a19d0f7bbacbe0255aa5b7d4", "genesis_meta_hash": "0000000000000000000000000000000000000000000000000000000000000000", - "genesis_output_index": 2432798076, + "genesis_output_index": 0, "genesis_type": 1, "amount": 1, "lock_time": 0, @@ -107,7 +120,9 @@ "asset_id": "0000000000000000000000000000000000000000000000000000000000000000", "script_key": "000000000000000000000000000000000000000000000000000000000000000000" }, - "tx_witness": null, + "tx_witness": [ + "76a254fd7d122acd85e6b1032f2ed53965c1f5f6b82973e0374ffcc11778b01074e9bd594c19f6715f9ea097a33f0faf6ca3b36923fbf6b2c4f5ce33712d2f83" + ], "split_commitment": null } ], @@ -115,7 +130,7 @@ "script_version": 0, "script_key": "02661e637f64d8d63f45a25890073502387b18f3f8aa7fd7704348f35ced5423fa", "group_key": { - "group_key": "02475ad4761032ee378dff99a4bf0d1f63636d5f0e4df935ba0f117af249628e8c" + "group_key": "03a4a34fd1ee1a575f7b101caf0e6d472ec4d6e2801b69a301f1cacee0949ee5f6" } }, "inclusion_proof": { @@ -126,7 +141,7 @@ "asset_proof": { "proof": "0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "version": 0, - "asset_id": "af9b4888e4061d2fc1980cc7e3eac3f144dd99602b76a159605147a3180a0393" + "asset_id": "4c3b9aff77396d1ff1d5470229b11164512a56d86db16be09c26b890512e349d" }, "taproot_asset_proof": { "proof": "0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", @@ -141,24 +156,35 @@ "split_root_proof": null, "meta_reveal": null, "additional_inputs": null, - "challenge_witness": null + "challenge_witness": null, + "genesis_reveal": { + "first_prev_out": "3f71f8cb984b92f67403049442fd5ad145f49143f7f4a5ee3b22b02936d4ff9b:4165004363", + "tag": "bb358b0c3b525da1786f9fff094279db1944ebd7a19d0f7bbacbe0255aa5b7d4", + "meta_hash": "0000000000000000000000000000000000000000000000000000000000000000", + "output_index": 0, + "type": 1 + }, + "group_key_reveal": { + "raw_key": "03c4d2d8eb8d64e9d2b888aead034f78ffc52ec30b28b64b596b902eb7c6418817", + "tapscript_root": "" + } }, - "expected": "5441505000040000000001240000000000000000000000000000000000000000000000000000000000000000000000000250000000006fe28c0ab6f1b372c1a6a246ae63f74f931e8365e15a089c68d6190000000000ba559897fe590c4671e2e637a4a27a438b278abf24f6c97631345e1a0a35750e366c47190000000000000000035e02000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000014a010000000000002251208fce04edce8bf1a34b382a3c402e0067edcd84cbfc533e4b270f55f5171ca1d60000000004010005fd014a000100018a9bffd43629b0223beea5f4f74391f445d15afd4294040374f6924b98cbf8713ff840ec4b4062623335386230633362353235646131373836663966666630393432373964623139343465626437613139643066376262616362653032353561613562376434000000000000000000000000000000000000000000000000000000000000000091018d7c01020101030101066901670065000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008020000092102661e637f64d8d63f45a25890073502387b18f3f8aa7fd7704348f35ced5423fa0a2102475ad4761032ee378dff99a4bf0d1f63636d5f0e4df935ba0f117af249628e8c06bc000400000000012102af086d6428c5621941450bbefec061b5056d8706d659f9eebd7043400a4c0f93029100490001000120af9b4888e4061d2fc1980cc7e3eac3f144dd99602b76a159605147a3180a039302220000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff012700010001220000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff021b00c01876a914f6c97547d73156abb300ae059905c4acaadd09dd880c0400000001", + "expected": "5441505000040000000001249bffd43629b0223beea5f4f74391f445d15afd4294040374f6924b98cbf8713ff840ec4b0250000000006fe28c0ab6f1b372c1a6a246ae63f74f931e8365e15a089c68d61900000000005f723f31d2daf07f9daa0f29c48591aa4b25cc48b2b89fde4dc6615b9c3cebb7366c47190000000000000000035e02000000019bffd43629b0223beea5f4f74391f445d15afd4294040374f6924b98cbf8713f4bec40f80000000000014a01000000000000225120da9d7845eb9b2a597edd6c818c59506a061c95747b897a49519468410ce4a86a0000000004010005fd018e000100018a9bffd43629b0223beea5f4f74391f445d15afd4294040374f6924b98cbf8713ff840ec4b40626233353862306333623532356461313738366639666666303934323739646231393434656264376131396430663762626163626530323535616135623764340000000000000000000000000000000000000000000000000000000000000000000000000102010103010106ad01ab006500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000142014076a254fd7d122acd85e6b1032f2ed53965c1f5f6b82973e0374ffcc11778b01074e9bd594c19f6715f9ea097a33f0faf6ca3b36923fbf6b2c4f5ce33712d2f8308020000092102661e637f64d8d63f45a25890073502387b18f3f8aa7fd7704348f35ced5423fa0a2103a4a34fd1ee1a575f7b101caf0e6d472ec4d6e2801b69a301f1cacee0949ee5f606bc000400000000012102af086d6428c5621941450bbefec061b5056d8706d659f9eebd7043400a4c0f930291004900010001204c3b9aff77396d1ff1d5470229b11164512a56d86db16be09c26b890512e349d02220000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff012700010001220000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff021b00c01876a914f6c97547d73156abb300ae059905c4acaadd09dd880c04000000010d8a9bffd43629b0223beea5f4f74391f445d15afd4294040374f6924b98cbf8713ff840ec4b4062623335386230633362353235646131373836663966666630393432373964623139343465626437613139643066376262616362653032353561613562376434000000000000000000000000000000000000000000000000000000000000000000000000010e2103c4d2d8eb8d64e9d2b888aead034f78ffc52ec30b28b64b596b902eb7c6418817", "comment": "collectible with leaf preimage" }, { "proof": { - "prev_out": "0000000000000000000000000000000000000000000000000000000000000000:0", + "prev_out": "e81ede4561ad67830356aa6b86dff7ab244fcd36e9f7676678e7aa73fac82541:3738690577", "block_header": { "version": 0, "prev_block": "000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f", - "merkle_root": "1f9a3a35a37b0b2811e78f06bc84fdaf93c1dd1eb276266227a94b46aedf754d", + "merkle_root": "6c13f2b46ee5f4f27b74d44d055f78b923c1907b541cd65b428d3b4207f96bc3", "timestamp": 2783629501, "bits": 0, "nonce": 0 }, "block_height": 1, - "anchor_tx": "02000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000014a010000000000002251204926275e159a7e10dd361bbc51ca3b759561e0ace35bdf8ccc65a6a3d25bdc4f00000000", + "anchor_tx": "02000000014125c8fa73aae7786667f7e936cd4f24abf7df866baa56038367ad6145de1ee811e4d7de0000000000014a010000000000002251204267658338d80247d571e80413d284d1ee4cafc53340541ec9f5c7573ad6defb00000000", "tx_merkle_proof": { "nodes": [], "bits": [] @@ -168,7 +194,7 @@ "genesis_first_prev_out": "e81ede4561ad67830356aa6b86dff7ab244fcd36e9f7676678e7aa73fac82541:3738690577", "genesis_tag": "c6077dbb5722f5717a289a266f97647981998ebea89c0b4b373970115e82ed6f", "genesis_meta_hash": "0000000000000000000000000000000000000000000000000000000000000000", - "genesis_output_index": 1050259624, + "genesis_output_index": 0, "genesis_type": 1, "amount": 1, "lock_time": 0, @@ -180,7 +206,9 @@ "asset_id": "0000000000000000000000000000000000000000000000000000000000000000", "script_key": "000000000000000000000000000000000000000000000000000000000000000000" }, - "tx_witness": null, + "tx_witness": [ + "2c41a0c9e197a5cdd7a87c6991ef25c5fe59a7e401fa05a75d62a944a5f4efdd6b35baba200bd6a3467e1f566d8e04225de37c114088df1eb82db320a618c64e" + ], "split_commitment": null } ], @@ -188,7 +216,7 @@ "script_version": 0, "script_key": "02bc9c371fa4e83557a1844db0a9e636dea420ebc1620a9b6cd499557bb20f5b3e", "group_key": { - "group_key": "032964eeba96725a8373fa55867fe0a6d01994d9c8822d8a76ac00181b65b1dd9a" + "group_key": "02db10bf007da6be53b694e716477d7707c32fea8815b9bd898fec0e42f84988b1" } }, "inclusion_proof": { @@ -199,7 +227,7 @@ "asset_proof": { "proof": "0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "version": 0, - "asset_id": "9d6d650760287dd9a16d719df2303da025dfb675f02a3c5ea525664831646214" + "asset_id": "c2b2144031c7f0158c9b080b3d4f28533c8bd79f3371fa2d486305cb32d52919" }, "taproot_asset_proof": { "proof": "0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", @@ -214,24 +242,35 @@ "split_root_proof": null, "meta_reveal": null, "additional_inputs": null, - "challenge_witness": null + "challenge_witness": null, + "genesis_reveal": { + "first_prev_out": "e81ede4561ad67830356aa6b86dff7ab244fcd36e9f7676678e7aa73fac82541:3738690577", + "tag": "c6077dbb5722f5717a289a266f97647981998ebea89c0b4b373970115e82ed6f", + "meta_hash": "0000000000000000000000000000000000000000000000000000000000000000", + "output_index": 0, + "type": 1 + }, + "group_key_reveal": { + "raw_key": "0216610ef68ae6f054474ee2b8f4069e18335aae6a24104a27f54274096965c9c6", + "tapscript_root": "" + } }, - "expected": "5441505000040000000001240000000000000000000000000000000000000000000000000000000000000000000000000250000000006fe28c0ab6f1b372c1a6a246ae63f74f931e8365e15a089c68d61900000000004d75dfae464ba927622676b21eddc193affd84bc068fe711280b7ba3353a9a1fbdd0eaa50000000000000000035e02000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000014a010000000000002251204926275e159a7e10dd361bbc51ca3b759561e0ace35bdf8ccc65a6a3d25bdc4f0000000004010005fd014a000100018a4125c8fa73aae7786667f7e936cd4f24abf7df866baa56038367ad6145de1ee8ded7e411406336303737646262353732326635373137613238396132363666393736343739383139393865626561383963306234623337333937303131356538326564366600000000000000000000000000000000000000000000000000000000000000003e99b0a801020101030101066901670065000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008020000092102bc9c371fa4e83557a1844db0a9e636dea420ebc1620a9b6cd499557bb20f5b3e0a21032964eeba96725a8373fa55867fe0a6d01994d9c8822d8a76ac00181b65b1dd9a06e20004000000000121021af16655f63c4b9f95b5961ad1c97ef0e8fa7f9218801870e5b2252a6427db8d02b7004900010001209d6d650760287dd9a16d719df2303da025dfb675f02a3c5ea52566483164621402220000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff012700010001220000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0241016c2e4bb01e316abaaee288d69c06cc608cedefd6e1a06813786c4ec51b6e1d3868ba2662554025b18af167c2ab17cd720b0c46ac7bd5750800b93c0b26a4af430c0400000001", + "expected": "5441505000040000000001244125c8fa73aae7786667f7e936cd4f24abf7df866baa56038367ad6145de1ee8ded7e4110250000000006fe28c0ab6f1b372c1a6a246ae63f74f931e8365e15a089c68d6190000000000c36bf907423b8d425bd61c547b90c123b9785f054dd4747bf2f4e56eb4f2136cbdd0eaa50000000000000000035e02000000014125c8fa73aae7786667f7e936cd4f24abf7df866baa56038367ad6145de1ee811e4d7de0000000000014a010000000000002251204267658338d80247d571e80413d284d1ee4cafc53340541ec9f5c7573ad6defb0000000004010005fd018e000100018a4125c8fa73aae7786667f7e936cd4f24abf7df866baa56038367ad6145de1ee8ded7e41140633630373764626235373232663537313761323839613236366639373634373938313939386562656138396330623462333733393730313135653832656436660000000000000000000000000000000000000000000000000000000000000000000000000102010103010106ad01ab00650000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014201402c41a0c9e197a5cdd7a87c6991ef25c5fe59a7e401fa05a75d62a944a5f4efdd6b35baba200bd6a3467e1f566d8e04225de37c114088df1eb82db320a618c64e08020000092102bc9c371fa4e83557a1844db0a9e636dea420ebc1620a9b6cd499557bb20f5b3e0a2102db10bf007da6be53b694e716477d7707c32fea8815b9bd898fec0e42f84988b106e20004000000000121021af16655f63c4b9f95b5961ad1c97ef0e8fa7f9218801870e5b2252a6427db8d02b700490001000120c2b2144031c7f0158c9b080b3d4f28533c8bd79f3371fa2d486305cb32d5291902220000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff012700010001220000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0241016c2e4bb01e316abaaee288d69c06cc608cedefd6e1a06813786c4ec51b6e1d3868ba2662554025b18af167c2ab17cd720b0c46ac7bd5750800b93c0b26a4af430c04000000010d8a4125c8fa73aae7786667f7e936cd4f24abf7df866baa56038367ad6145de1ee8ded7e4114063363037376462623537323266353731376132383961323636663937363437393831393938656265613839633062346233373339373031313565383265643666000000000000000000000000000000000000000000000000000000000000000000000000010e210216610ef68ae6f054474ee2b8f4069e18335aae6a24104a27f54274096965c9c6", "comment": "collectible with branch preimage" }, { "proof": { - "prev_out": "0000000000000000000000000000000000000000000000000000000000000000:0", + "prev_out": "2db92d0169a39144afd37941439089bed31f1cb9e6c6a03cb44af864ba29ee07:737360203", "block_header": { "version": 0, "prev_block": "000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f", - "merkle_root": "acf27bfbe19a84bf8b6b416609e8a51267ba69f118bc37222c6576361ce975ea", + "merkle_root": "182d2c9ff817c50ce19f3967452baeb0e349e518128fb6149aa7cfe44136ed16", "timestamp": 3929885861, "bits": 0, "nonce": 0 }, "block_height": 1, - "anchor_tx": "02000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000014a01000000000000225120776b5157ae2a3cdf3a771be464402e600b0a7271170dc1f9739e47d8c98958cf00000000", + "anchor_tx": "020000000107ee29ba64f84ab43ca0c6e6b91c1fd3be8990434179d3af4491a369012db92d4b39f32b0000000000014a0100000000000022512046eb899c5f788c852963feea741ca77da1a3738c2b6cca55f5e94b4b58dc233e00000000", "tx_merkle_proof": { "nodes": [], "bits": [] @@ -241,7 +280,7 @@ "genesis_first_prev_out": "2db92d0169a39144afd37941439089bed31f1cb9e6c6a03cb44af864ba29ee07:737360203", "genesis_tag": "a665f606f6a63b7f3dfd2567c18979e4d60f26686d9bf2fb26c901ff354cde16", "genesis_meta_hash": "0000000000000000000000000000000000000000000000000000000000000000", - "genesis_output_index": 1108760575, + "genesis_output_index": 0, "genesis_type": 0, "amount": 5000, "lock_time": 0, @@ -253,7 +292,9 @@ "asset_id": "0000000000000000000000000000000000000000000000000000000000000000", "script_key": "000000000000000000000000000000000000000000000000000000000000000000" }, - "tx_witness": null, + "tx_witness": [ + "341bbc98c55e94e3a15b35d00f2428278b99ef0497ba07663bdf70c09f99ef858e6584d312e41656f93e39c271a516d8783d957920d3232c6da17af2446f9a88" + ], "split_commitment": null } ], @@ -261,7 +302,7 @@ "script_version": 0, "script_key": "02610f4ad4f6fcb2f75b10b9674cfc140dd97921b53a2f5db4b7f807a5a87d2187", "group_key": { - "group_key": "02f2a1617673e0d62a2dfe09f6a7faa670f170256288cfabe4ff98dd993f988a5e" + "group_key": "02bac92fcda17b78998ef6c50c13762f327e15aef228f35030375666ad142bf71b" } }, "inclusion_proof": { @@ -272,7 +313,7 @@ "asset_proof": { "proof": "0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "version": 0, - "asset_id": "a0319d51ea16813396aed95d9a89abbd4478d3ce39b41ac0c1a086dfe89c5fef" + "asset_id": "a5f89a2a92613927aea2658e73889bd84cf6bc6f577578826aef7968d38e5da6" }, "taproot_asset_proof": { "proof": "0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", @@ -287,24 +328,35 @@ "split_root_proof": null, "meta_reveal": null, "additional_inputs": null, - "challenge_witness": null + "challenge_witness": null, + "genesis_reveal": { + "first_prev_out": "2db92d0169a39144afd37941439089bed31f1cb9e6c6a03cb44af864ba29ee07:737360203", + "tag": "a665f606f6a63b7f3dfd2567c18979e4d60f26686d9bf2fb26c901ff354cde16", + "meta_hash": "0000000000000000000000000000000000000000000000000000000000000000", + "output_index": 0, + "type": 0 + }, + "group_key_reveal": { + "raw_key": "0236520442fe6f17887ab3b7d5cecc513482b5e52fbf4c18e35f9bad97d99f2970", + "tapscript_root": "" + } }, - "expected": "5441505000040000000001240000000000000000000000000000000000000000000000000000000000000000000000000250000000006fe28c0ab6f1b372c1a6a246ae63f74f931e8365e15a089c68d6190000000000ea75e91c3676652c2237bc18f169ba6712a5e80966416b8bbf849ae1fb7bf2aca54c3dea0000000000000000035e02000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000014a01000000000000225120776b5157ae2a3cdf3a771be464402e600b0a7271170dc1f9739e47d8c98958cf0000000004010005fd014c000100018a07ee29ba64f84ab43ca0c6e6b91c1fd3be8990434179d3af4491a369012db92d2bf3394b40613636356636303666366136336237663364666432353637633138393739653464363066323636383664396266326662323663393031666633353463646531360000000000000000000000000000000000000000000000000000000000000000421657ff000201000303fd1388066901670065000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008020000092102610f4ad4f6fcb2f75b10b9674cfc140dd97921b53a2f5db4b7f807a5a87d21870a2102f2a1617673e0d62a2dfe09f6a7faa670f170256288cfabe4ff98dd993f988a5e069f000400000000012102f7fd86c602d2ac12d72a7ee0422749b1bfe555c0ee8f24f5ea885a39e36f8cf9027400490001000120a0319d51ea16813396aed95d9a89abbd4478d3ce39b41ac0c1a086dfe89c5fef02220000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff012700010001220000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0c0400000001", + "expected": "54415050000400000000012407ee29ba64f84ab43ca0c6e6b91c1fd3be8990434179d3af4491a369012db92d2bf3394b0250000000006fe28c0ab6f1b372c1a6a246ae63f74f931e8365e15a089c68d619000000000016ed3641e4cfa79a14b68f1218e549e3b0ae2b4567399fe10cc517f89f2c2d18a54c3dea0000000000000000035e020000000107ee29ba64f84ab43ca0c6e6b91c1fd3be8990434179d3af4491a369012db92d4b39f32b0000000000014a0100000000000022512046eb899c5f788c852963feea741ca77da1a3738c2b6cca55f5e94b4b58dc233e0000000004010005fd0190000100018a07ee29ba64f84ab43ca0c6e6b91c1fd3be8990434179d3af4491a369012db92d2bf3394b4061363635663630366636613633623766336466643235363763313839373965346436306632363638366439626632666232366339303166663335346364653136000000000000000000000000000000000000000000000000000000000000000000000000000201000303fd138806ad01ab0065000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001420140341bbc98c55e94e3a15b35d00f2428278b99ef0497ba07663bdf70c09f99ef858e6584d312e41656f93e39c271a516d8783d957920d3232c6da17af2446f9a8808020000092102610f4ad4f6fcb2f75b10b9674cfc140dd97921b53a2f5db4b7f807a5a87d21870a2102bac92fcda17b78998ef6c50c13762f327e15aef228f35030375666ad142bf71b069f000400000000012102f7fd86c602d2ac12d72a7ee0422749b1bfe555c0ee8f24f5ea885a39e36f8cf9027400490001000120a5f89a2a92613927aea2658e73889bd84cf6bc6f577578826aef7968d38e5da602220000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff012700010001220000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0c04000000010d8a07ee29ba64f84ab43ca0c6e6b91c1fd3be8990434179d3af4491a369012db92d2bf3394b4061363635663630366636613633623766336466643235363763313839373965346436306632363638366439626632666232366339303166663335346364653136000000000000000000000000000000000000000000000000000000000000000000000000000e210236520442fe6f17887ab3b7d5cecc513482b5e52fbf4c18e35f9bad97d99f2970", "comment": "normal genesis" }, { "proof": { - "prev_out": "0000000000000000000000000000000000000000000000000000000000000000:0", + "prev_out": "41e52ad269fd8e5f04756b36dbc9b344e9031d27b8b352f7ab3641fe3dea7902:2817351063", "block_header": { "version": 0, "prev_block": "000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f", - "merkle_root": "c34ef14370afbfef58afa4f8f64e764c0e10e431ce302e873b83d50867398c27", + "merkle_root": "115117287d2ada274043dad6604e88d90c2b011021116589dfb05350f98eca9d", "timestamp": 1729403804, "bits": 0, "nonce": 0 }, "block_height": 1, - "anchor_tx": "02000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000014a01000000000000225120a16d4e7190cd39dbfda57aedb0c9f0ae16f757c73a1a097d7c38d69aef36eee300000000", + "anchor_tx": "02000000010279ea3dfe4136abf752b3b8271d03e944b3c9db366b75045f8efd69d22ae541975deda70000000000014a01000000000000225120e8c6553ba53345ba3469de0f2102a9f0a4daf39339526c56edbb5715302d458f00000000", "tx_merkle_proof": { "nodes": [], "bits": [] @@ -314,7 +366,7 @@ "genesis_first_prev_out": "41e52ad269fd8e5f04756b36dbc9b344e9031d27b8b352f7ab3641fe3dea7902:2817351063", "genesis_tag": "17e924aef78ae151c00755925836b7075885650c30ec29a3703934bf50a28da1", "genesis_meta_hash": "0000000000000000000000000000000000000000000000000000000000000000", - "genesis_output_index": 647263805, + "genesis_output_index": 0, "genesis_type": 0, "amount": 5000, "lock_time": 0, @@ -326,7 +378,9 @@ "asset_id": "0000000000000000000000000000000000000000000000000000000000000000", "script_key": "000000000000000000000000000000000000000000000000000000000000000000" }, - "tx_witness": null, + "tx_witness": [ + "be2809b83c04943a45dc97b7cde970a43f8bf41cf5ab388b9581be75852e0d11e21cd321b30c7dc22f3e93639d1a541e921e66f52b3a7a5dcb6cbf722fd7e739" + ], "split_commitment": null } ], @@ -334,7 +388,7 @@ "script_version": 0, "script_key": "029e47e906bfa2ee6cbba2c920b6f80d679928c40fe0c147d33c68cc5543f14637", "group_key": { - "group_key": "030785de067c85d0cd3d27a4fdebe7394c1d18520a4303a415d3ba00f9429b2ef3" + "group_key": "025d03198cebb64f4ecacd13ec61f8209b4d4025ddf47ccd74554d5e369c735235" } }, "inclusion_proof": { @@ -345,7 +399,7 @@ "asset_proof": { "proof": "0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "version": 0, - "asset_id": "7440c1f12cf25120108c1b827e62ccfcde709a664cb3fb8396ab70aa18546f8a" + "asset_id": "c4fd51257eced9f6bb3f5918545d257fa7a490b129189d0d8096117341b87425" }, "taproot_asset_proof": { "proof": "0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", @@ -360,24 +414,35 @@ "split_root_proof": null, "meta_reveal": null, "additional_inputs": null, - "challenge_witness": null + "challenge_witness": null, + "genesis_reveal": { + "first_prev_out": "41e52ad269fd8e5f04756b36dbc9b344e9031d27b8b352f7ab3641fe3dea7902:2817351063", + "tag": "17e924aef78ae151c00755925836b7075885650c30ec29a3703934bf50a28da1", + "meta_hash": "0000000000000000000000000000000000000000000000000000000000000000", + "output_index": 0, + "type": 0 + }, + "group_key_reveal": { + "raw_key": "02d6e2de50d0d66ef724a48e26000a4ddcbd58da3ec8d13354c025cca8e8b8da13", + "tapscript_root": "" + } }, - "expected": "5441505000040000000001240000000000000000000000000000000000000000000000000000000000000000000000000250000000006fe28c0ab6f1b372c1a6a246ae63f74f931e8365e15a089c68d6190000000000278c396708d5833b872e30ce31e4100e4c764ef6f8a4af58efbfaf7043f14ec39c9b14670000000000000000035e02000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000014a01000000000000225120a16d4e7190cd39dbfda57aedb0c9f0ae16f757c73a1a097d7c38d69aef36eee30000000004010005fd014c000100018a0279ea3dfe4136abf752b3b8271d03e944b3c9db366b75045f8efd69d22ae541a7ed5d97403137653932346165663738616531353163303037353539323538333662373037353838353635306333306563323961333730333933346266353061323864613100000000000000000000000000000000000000000000000000000000000000002694763d000201000303fd13880669016700650000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080200000921029e47e906bfa2ee6cbba2c920b6f80d679928c40fe0c147d33c68cc5543f146370a21030785de067c85d0cd3d27a4fdebe7394c1d18520a4303a415d3ba00f9429b2ef306bc000400000000012102f820ac404967c0e36fcd7a0d6d8e8a3150801f18947c2299a2e024bf8aa253410291004900010001207440c1f12cf25120108c1b827e62ccfcde709a664cb3fb8396ab70aa18546f8a02220000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff012700010001220000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff021b00c01876a914f6c97547d73156abb300ae059905c4acaadd09dd880c0400000001", + "expected": "5441505000040000000001240279ea3dfe4136abf752b3b8271d03e944b3c9db366b75045f8efd69d22ae541a7ed5d970250000000006fe28c0ab6f1b372c1a6a246ae63f74f931e8365e15a089c68d61900000000009dca8ef95053b0df8965112110012b0cd9884e60d6da434027da2a7d281751119c9b14670000000000000000035e02000000010279ea3dfe4136abf752b3b8271d03e944b3c9db366b75045f8efd69d22ae541975deda70000000000014a01000000000000225120e8c6553ba53345ba3469de0f2102a9f0a4daf39339526c56edbb5715302d458f0000000004010005fd0190000100018a0279ea3dfe4136abf752b3b8271d03e944b3c9db366b75045f8efd69d22ae541a7ed5d974031376539323461656637386165313531633030373535393235383336623730373538383536353063333065633239613337303339333462663530613238646131000000000000000000000000000000000000000000000000000000000000000000000000000201000303fd138806ad01ab0065000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001420140be2809b83c04943a45dc97b7cde970a43f8bf41cf5ab388b9581be75852e0d11e21cd321b30c7dc22f3e93639d1a541e921e66f52b3a7a5dcb6cbf722fd7e739080200000921029e47e906bfa2ee6cbba2c920b6f80d679928c40fe0c147d33c68cc5543f146370a21025d03198cebb64f4ecacd13ec61f8209b4d4025ddf47ccd74554d5e369c73523506bc000400000000012102f820ac404967c0e36fcd7a0d6d8e8a3150801f18947c2299a2e024bf8aa25341029100490001000120c4fd51257eced9f6bb3f5918545d257fa7a490b129189d0d8096117341b8742502220000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff012700010001220000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff021b00c01876a914f6c97547d73156abb300ae059905c4acaadd09dd880c04000000010d8a0279ea3dfe4136abf752b3b8271d03e944b3c9db366b75045f8efd69d22ae541a7ed5d974031376539323461656637386165313531633030373535393235383336623730373538383536353063333065633239613337303339333462663530613238646131000000000000000000000000000000000000000000000000000000000000000000000000000e2102d6e2de50d0d66ef724a48e26000a4ddcbd58da3ec8d13354c025cca8e8b8da13", "comment": "normal with leaf preimage" }, { "proof": { - "prev_out": "0000000000000000000000000000000000000000000000000000000000000000:0", + "prev_out": "d6090ec04ff5f26283efc6c6443faf8eb3e4a15ca80d72521a90ae3e3e4a3056:210616852", "block_header": { "version": 0, "prev_block": "000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f", - "merkle_root": "9caed32f342d64eef1278b4c9da36e1e62854de2b46bf2ee173ffc73d2691acc", + "merkle_root": "1d995f1e3cda2c4c89ed7cddb2f40940afb826e7560e2d85b1fa38a93ab797a2", "timestamp": 1018572551, "bits": 0, "nonce": 0 }, "block_height": 1, - "anchor_tx": "02000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000014a01000000000000225120f55f7306ae92cc55fda6d22955e0dbaedc6cf092fff3badcd09a0902eaa0c69a00000000", + "anchor_tx": "020000000156304a3e3eae901a52720da85ca1e4b38eaf3f44c6c6ef8362f2f54fc00e09d614c28d0c0000000000014a01000000000000225120d7c2463670c0afbddec2517412afe4aa2f3c062bd0bc4406887f684f68a1879b00000000", "tx_merkle_proof": { "nodes": [], "bits": [] @@ -387,7 +452,7 @@ "genesis_first_prev_out": "d6090ec04ff5f26283efc6c6443faf8eb3e4a15ca80d72521a90ae3e3e4a3056:210616852", "genesis_tag": "01a239c4365854c3af7f6b41d631f92b9a8d12f41257325fff332f7576b06205", "genesis_meta_hash": "0000000000000000000000000000000000000000000000000000000000000000", - "genesis_output_index": 3243509860, + "genesis_output_index": 0, "genesis_type": 0, "amount": 5000, "lock_time": 0, @@ -399,7 +464,9 @@ "asset_id": "0000000000000000000000000000000000000000000000000000000000000000", "script_key": "000000000000000000000000000000000000000000000000000000000000000000" }, - "tx_witness": null, + "tx_witness": [ + "06c375da112066bf92e73e026f51b37f07fc1e757169eec6304fb5c3439fae56e87d962c788ab453f88f92c4af4656cc9c88e7276ae944b9aad93f30446133e5" + ], "split_commitment": null } ], @@ -407,7 +474,7 @@ "script_version": 0, "script_key": "02ca32de61e7923279664dc4d609b8e68cd88fcd096bcfc5fcbd9d5e20ed14f455", "group_key": { - "group_key": "03f072d865cd42fbd6290c62c0a7067a403c9557fb998bd9736ceea5a774b974af" + "group_key": "02d6ea7085ab81dd03ba0bbe3b3d0aca297d3f54e2d0a7752d8e921dc318619760" } }, "inclusion_proof": { @@ -418,7 +485,7 @@ "asset_proof": { "proof": "0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "version": 0, - "asset_id": "f15e3049ab9c051ddf9d5e5cba119339708418231d3ce06789174e4e3c682271" + "asset_id": "cb74bf55f8cd601b17db37abc586a01b59533caa2e1ecd629f840a9d416423c6" }, "taproot_asset_proof": { "proof": "0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", @@ -433,24 +500,35 @@ "split_root_proof": null, "meta_reveal": null, "additional_inputs": null, - "challenge_witness": null + "challenge_witness": null, + "genesis_reveal": { + "first_prev_out": "d6090ec04ff5f26283efc6c6443faf8eb3e4a15ca80d72521a90ae3e3e4a3056:210616852", + "tag": "01a239c4365854c3af7f6b41d631f92b9a8d12f41257325fff332f7576b06205", + "meta_hash": "0000000000000000000000000000000000000000000000000000000000000000", + "output_index": 0, + "type": 0 + }, + "group_key_reveal": { + "raw_key": "033f9f8e88dcf745e9387b5da3c01cc4395db319f6d5b36a923db0af2ab8d0dc97", + "tapscript_root": "" + } }, - "expected": "5441505000040000000001240000000000000000000000000000000000000000000000000000000000000000000000000250000000006fe28c0ab6f1b372c1a6a246ae63f74f931e8365e15a089c68d6190000000000cc1a69d273fc3f17eef26bb4e24d85621e6ea39d4c8b27f1ee642d342fd3ae9c072fb63c0000000000000000035e02000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000014a01000000000000225120f55f7306ae92cc55fda6d22955e0dbaedc6cf092fff3badcd09a0902eaa0c69a0000000004010005fd014c000100018a56304a3e3eae901a52720da85ca1e4b38eaf3f44c6c6ef8362f2f54fc00e09d60c8dc21440303161323339633433363538353463336166376636623431643633316639326239613864313266343132353733323566666633333266373537366230363230350000000000000000000000000000000000000000000000000000000000000000c1540864000201000303fd1388066901670065000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008020000092102ca32de61e7923279664dc4d609b8e68cd88fcd096bcfc5fcbd9d5e20ed14f4550a2103f072d865cd42fbd6290c62c0a7067a403c9557fb998bd9736ceea5a774b974af06e2000400000000012102210ce45fef3bc702f0878323249c0263e0288217f9374a3661ec361d5261474f02b700490001000120f15e3049ab9c051ddf9d5e5cba119339708418231d3ce06789174e4e3c68227102220000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff012700010001220000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0241016c2e4bb01e316abaaee288d69c06cc608cedefd6e1a06813786c4ec51b6e1d3868ba2662554025b18af167c2ab17cd720b0c46ac7bd5750800b93c0b26a4af430c0400000001", + "expected": "54415050000400000000012456304a3e3eae901a52720da85ca1e4b38eaf3f44c6c6ef8362f2f54fc00e09d60c8dc2140250000000006fe28c0ab6f1b372c1a6a246ae63f74f931e8365e15a089c68d6190000000000a297b73aa938fab1852d0e56e726b8af4009f4b2dd7ced894c2cda3c1e5f991d072fb63c0000000000000000035e020000000156304a3e3eae901a52720da85ca1e4b38eaf3f44c6c6ef8362f2f54fc00e09d614c28d0c0000000000014a01000000000000225120d7c2463670c0afbddec2517412afe4aa2f3c062bd0bc4406887f684f68a1879b0000000004010005fd0190000100018a56304a3e3eae901a52720da85ca1e4b38eaf3f44c6c6ef8362f2f54fc00e09d60c8dc2144030316132333963343336353835346333616637663662343164363331663932623961386431326634313235373332356666663333326637353736623036323035000000000000000000000000000000000000000000000000000000000000000000000000000201000303fd138806ad01ab006500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000142014006c375da112066bf92e73e026f51b37f07fc1e757169eec6304fb5c3439fae56e87d962c788ab453f88f92c4af4656cc9c88e7276ae944b9aad93f30446133e508020000092102ca32de61e7923279664dc4d609b8e68cd88fcd096bcfc5fcbd9d5e20ed14f4550a2102d6ea7085ab81dd03ba0bbe3b3d0aca297d3f54e2d0a7752d8e921dc31861976006e2000400000000012102210ce45fef3bc702f0878323249c0263e0288217f9374a3661ec361d5261474f02b700490001000120cb74bf55f8cd601b17db37abc586a01b59533caa2e1ecd629f840a9d416423c602220000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff012700010001220000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0241016c2e4bb01e316abaaee288d69c06cc608cedefd6e1a06813786c4ec51b6e1d3868ba2662554025b18af167c2ab17cd720b0c46ac7bd5750800b93c0b26a4af430c04000000010d8a56304a3e3eae901a52720da85ca1e4b38eaf3f44c6c6ef8362f2f54fc00e09d60c8dc2144030316132333963343336353835346333616637663662343164363331663932623961386431326634313235373332356666663333326637353736623036323035000000000000000000000000000000000000000000000000000000000000000000000000000e21033f9f8e88dcf745e9387b5da3c01cc4395db319f6d5b36a923db0af2ab8d0dc97", "comment": "normal with branch preimage" }, { "proof": { - "prev_out": "0000000000000000000000000000000000000000000000000000000000000000:0", + "prev_out": "70e7ac7417bf383423cfcde2c269398e40b01aa47d7fbfbcafd915bb5ce263e2:1058894887", "block_header": { "version": 0, "prev_block": "000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f", - "merkle_root": "df86eec2671984f450b979b555566bfaf7c50702d752192420856d856992b459", + "merkle_root": "f39e4cc9ee26a8204916a91de1e4dbe449c0538a84413292d681e6e544b18360", "timestamp": 3691164560, "bits": 0, "nonce": 0 }, "block_height": 1, - "anchor_tx": "02000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000014a010000000000002251209668d37f2f1e75263b986d5102971a48a11ececbcb3f0543c109c0a20637331400000000", + "anchor_tx": "0200000001e263e25cbb15d9afbcbf7f7da41ab0408e3969c2e2cdcf233438bf1774ace77027741d3f0000000000014a010000000000002251200193f44d6eafa8ced7bb67951583c1fa1c4090bfa1fdf0b3732156ffb69de60d00000000", "tx_merkle_proof": { "nodes": [], "bits": [] @@ -460,7 +538,7 @@ "genesis_first_prev_out": "70e7ac7417bf383423cfcde2c269398e40b01aa47d7fbfbcafd915bb5ce263e2:1058894887", "genesis_tag": "6710a7960732ca52cf53c3f520c889b79bf504cfb57c7601232d589baccea9d6", "genesis_meta_hash": "a34a4bd8a261e96320dcd1e43f134b84f3421a5433336724de1aa5d07cef6d13", - "genesis_output_index": 503926682, + "genesis_output_index": 0, "genesis_type": 0, "amount": 5000, "lock_time": 0, @@ -472,7 +550,9 @@ "asset_id": "0000000000000000000000000000000000000000000000000000000000000000", "script_key": "000000000000000000000000000000000000000000000000000000000000000000" }, - "tx_witness": null, + "tx_witness": [ + "896391d533d035ab0856b089ccfb37bb1aef1c371e88e05d89b5aa86fbe9f1d8dd9a2fac24e126c1966e2179ce3ef4ca989ced0fa2e3be687757d0cdddcc8d74" + ], "split_commitment": null } ], @@ -480,7 +560,7 @@ "script_version": 0, "script_key": "024236a05cff1fc479f8a2abc0fb95874b4e416bb9f4e617e85a8ea8b492189a56", "group_key": { - "group_key": "02b6f3ea9dbc2aec162b5c5461fde8e000e8ce33e75e71e9053edb4564dea457cd" + "group_key": "02011a525dba93809b010e6e6cb29bea024bbf7133df5892d8ff8fa86df84f7732" } }, "inclusion_proof": { @@ -491,7 +571,7 @@ "asset_proof": { "proof": "0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "version": 0, - "asset_id": "3e3ac273be361ad0f51e35fe02af232e01de9043d7d701594387c556877ac537" + "asset_id": "a510ff0bda51bc65fe06efb04ef58a3c1c834039c87c6b4480915798ee66364f" }, "taproot_asset_proof": { "proof": "0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", @@ -509,24 +589,35 @@ "data": "6d65616e7420696e2063726f6b696e67206e657665726d6f7265" }, "additional_inputs": null, - "challenge_witness": null + "challenge_witness": null, + "genesis_reveal": { + "first_prev_out": "70e7ac7417bf383423cfcde2c269398e40b01aa47d7fbfbcafd915bb5ce263e2:1058894887", + "tag": "6710a7960732ca52cf53c3f520c889b79bf504cfb57c7601232d589baccea9d6", + "meta_hash": "a34a4bd8a261e96320dcd1e43f134b84f3421a5433336724de1aa5d07cef6d13", + "output_index": 0, + "type": 0 + }, + "group_key_reveal": { + "raw_key": "034175f1f609feba5dbeb3c37ad30bcec6686450cfc0d1ec51a2d99671f718195c", + "tapscript_root": "" + } }, - "expected": "5441505000040000000001240000000000000000000000000000000000000000000000000000000000000000000000000250000000006fe28c0ab6f1b372c1a6a246ae63f74f931e8365e15a089c68d619000000000059b49269856d8520241952d70207c5f7fa6b5655b579b950f4841967c2ee86df90b302dc0000000000000000035e02000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000014a010000000000002251209668d37f2f1e75263b986d5102971a48a11ececbcb3f0543c109c0a2063733140000000004010005fd014c000100018ae263e25cbb15d9afbcbf7f7da41ab0408e3969c2e2cdcf233438bf1774ace7703f1d74274036373130613739363037333263613532636635336333663532306338383962373962663530346366623537633736303132333264353839626163636561396436a34a4bd8a261e96320dcd1e43f134b84f3421a5433336724de1aa5d07cef6d131e094f9a000201000303fd13880669016700650000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080200000921024236a05cff1fc479f8a2abc0fb95874b4e416bb9f4e617e85a8ea8b492189a560a2102b6f3ea9dbc2aec162b5c5461fde8e000e8ce33e75e71e9053edb4564dea457cd069f000400000000012102a1581b958162db9a2ab8b13079694ab91ea08ba74e99635af948e7141dcdcdfe0274004900010001203e3ac273be361ad0f51e35fe02af232e01de9043d7d701594387c556877ac53702220000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff012700010001220000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff091f000100011a6d65616e7420696e2063726f6b696e67206e657665726d6f72650c0400000001", + "expected": "544150500004000000000124e263e25cbb15d9afbcbf7f7da41ab0408e3969c2e2cdcf233438bf1774ace7703f1d74270250000000006fe28c0ab6f1b372c1a6a246ae63f74f931e8365e15a089c68d61900000000006083b144e5e681d6923241848a53c049e4dbe4e11da9164920a826eec94c9ef390b302dc0000000000000000035e0200000001e263e25cbb15d9afbcbf7f7da41ab0408e3969c2e2cdcf233438bf1774ace77027741d3f0000000000014a010000000000002251200193f44d6eafa8ced7bb67951583c1fa1c4090bfa1fdf0b3732156ffb69de60d0000000004010005fd0190000100018ae263e25cbb15d9afbcbf7f7da41ab0408e3969c2e2cdcf233438bf1774ace7703f1d74274036373130613739363037333263613532636635336333663532306338383962373962663530346366623537633736303132333264353839626163636561396436a34a4bd8a261e96320dcd1e43f134b84f3421a5433336724de1aa5d07cef6d1300000000000201000303fd138806ad01ab0065000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001420140896391d533d035ab0856b089ccfb37bb1aef1c371e88e05d89b5aa86fbe9f1d8dd9a2fac24e126c1966e2179ce3ef4ca989ced0fa2e3be687757d0cdddcc8d74080200000921024236a05cff1fc479f8a2abc0fb95874b4e416bb9f4e617e85a8ea8b492189a560a2102011a525dba93809b010e6e6cb29bea024bbf7133df5892d8ff8fa86df84f7732069f000400000000012102a1581b958162db9a2ab8b13079694ab91ea08ba74e99635af948e7141dcdcdfe027400490001000120a510ff0bda51bc65fe06efb04ef58a3c1c834039c87c6b4480915798ee66364f02220000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff012700010001220000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff091f000100011a6d65616e7420696e2063726f6b696e67206e657665726d6f72650c04000000010d8ae263e25cbb15d9afbcbf7f7da41ab0408e3969c2e2cdcf233438bf1774ace7703f1d74274036373130613739363037333263613532636635336333663532306338383962373962663530346366623537633736303132333264353839626163636561396436a34a4bd8a261e96320dcd1e43f134b84f3421a5433336724de1aa5d07cef6d1300000000000e21034175f1f609feba5dbeb3c37ad30bcec6686450cfc0d1ec51a2d99671f718195c", "comment": "normal asset with a meta reveal" }, { "proof": { - "prev_out": "0000000000000000000000000000000000000000000000000000000000000000:0", + "prev_out": "0cb058bd10f13e41b7c09a3e6f241c576f9ac7070f0914c3f10e0f21255197d7:1325329117", "block_header": { "version": 0, "prev_block": "000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f", - "merkle_root": "b6553d0aa7a045b817da24441cf619703e34bc6335a1c1d6ea74d5781e4b05ba", + "merkle_root": "26a502ad0da8985aebcf5dc3d7079d638466559521a1c4d4dcad1978a9a8cdb3", "timestamp": 1084726331, "bits": 0, "nonce": 0 }, "block_height": 1, - "anchor_tx": "02000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000014a0100000000000022512093239bd9ab04293896c7e513faa3a2e27460c6f971c784464e292e6482e857a200000000", + "anchor_tx": "0200000001d7975125210f0ef1c314090f07c79a6f571c246f3e9ac0b7413ef110bd58b00cddeafe4e0000000000014a0100000000000022512056bd4e2920f34465c10f9e78be4c7dae04d8b54242b2fd06f3dacd4c8cd714fb00000000", "tx_merkle_proof": { "nodes": [], "bits": [] @@ -536,7 +627,7 @@ "genesis_first_prev_out": "0cb058bd10f13e41b7c09a3e6f241c576f9ac7070f0914c3f10e0f21255197d7:1325329117", "genesis_tag": "8f8921a266b11d0f334c62fe52ba53af19779cb2948b6570ffa0b773963c130a", "genesis_meta_hash": "691a588e330c10a4ec7261f0b571486a8223f13fd7594e60eee6ce8013bf232f", - "genesis_output_index": 4105630847, + "genesis_output_index": 0, "genesis_type": 1, "amount": 1, "lock_time": 0, @@ -548,7 +639,9 @@ "asset_id": "0000000000000000000000000000000000000000000000000000000000000000", "script_key": "000000000000000000000000000000000000000000000000000000000000000000" }, - "tx_witness": null, + "tx_witness": [ + "f950eaac2d303d039e089bda0e8739fa38383f21fc75bf7245c5272125f1e8887e6995eb0cd4a55074a2d3b7064c39df57bff0abd794df4a1b77e5dd35634c2b" + ], "split_commitment": null } ], @@ -556,7 +649,7 @@ "script_version": 0, "script_key": "020aca705bbfdaea0fdaa052837c3801953a2642ca7009a99fe2884cb616bce3a5", "group_key": { - "group_key": "02c59d39e7c47626d9b9153495b5ce750716818a19938d2730692ed8bbafce5f21" + "group_key": "02532be57af750935525704043adcfd3deb611aafdfc49d6d2e6b3f4449fb706b0" } }, "inclusion_proof": { @@ -567,7 +660,7 @@ "asset_proof": { "proof": "0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "version": 0, - "asset_id": "99539548cd53af1920671ef2c07d9078ad6ffd2646563197fecb125a687f9548" + "asset_id": "d56171676e46d0c338b0adf7b35da75d50257cfc12c85c2454bb0c97d340701f" }, "taproot_asset_proof": { "proof": "0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", @@ -585,9 +678,20 @@ "data": "7368616c6c206265206c6966746564206e657665726d6f7265" }, "additional_inputs": null, - "challenge_witness": null + "challenge_witness": null, + "genesis_reveal": { + "first_prev_out": "0cb058bd10f13e41b7c09a3e6f241c576f9ac7070f0914c3f10e0f21255197d7:1325329117", + "tag": "8f8921a266b11d0f334c62fe52ba53af19779cb2948b6570ffa0b773963c130a", + "meta_hash": "691a588e330c10a4ec7261f0b571486a8223f13fd7594e60eee6ce8013bf232f", + "output_index": 0, + "type": 1 + }, + "group_key_reveal": { + "raw_key": "02fef70a63d6c8833d975ab289b70b84f14486c831dd5c9dc1e2b1c0346aa60c4e", + "tapscript_root": "" + } }, - "expected": "5441505000040000000001240000000000000000000000000000000000000000000000000000000000000000000000000250000000006fe28c0ab6f1b372c1a6a246ae63f74f931e8365e15a089c68d6190000000000ba054b1e78d574ead6c1a13563bc343e7019f61c4424da17b845a0a70a3d55b63b9ca7400000000000000000035e02000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000014a0100000000000022512093239bd9ab04293896c7e513faa3a2e27460c6f971c784464e292e6482e857a20000000004010005fd014a000100018ad7975125210f0ef1c314090f07c79a6f571c246f3e9ac0b7413ef110bd58b00c4efeeadd4038663839323161323636623131643066333334633632666535326261353361663139373739636232393438623635373066666130623737333936336331333061691a588e330c10a4ec7261f0b571486a8223f13fd7594e60eee6ce8013bf232ff4b6f47f010201010301010669016700650000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080200000921020aca705bbfdaea0fdaa052837c3801953a2642ca7009a99fe2884cb616bce3a50a2102c59d39e7c47626d9b9153495b5ce750716818a19938d2730692ed8bbafce5f21069f00040000000001210265c2da862edf7e730c69c5f1677ce0104a81adda912cc97f54a7aeec9e1b094302740049000100012099539548cd53af1920671ef2c07d9078ad6ffd2646563197fecb125a687f954802220000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff012700010001220000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff091e00010001197368616c6c206265206c6966746564206e657665726d6f72650c0400000001", + "expected": "544150500004000000000124d7975125210f0ef1c314090f07c79a6f571c246f3e9ac0b7413ef110bd58b00c4efeeadd0250000000006fe28c0ab6f1b372c1a6a246ae63f74f931e8365e15a089c68d6190000000000b3cda8a97819addcd4c4a12195556684639d07d7c35dcfeb5a98a80dad02a5263b9ca7400000000000000000035e0200000001d7975125210f0ef1c314090f07c79a6f571c246f3e9ac0b7413ef110bd58b00cddeafe4e0000000000014a0100000000000022512056bd4e2920f34465c10f9e78be4c7dae04d8b54242b2fd06f3dacd4c8cd714fb0000000004010005fd018e000100018ad7975125210f0ef1c314090f07c79a6f571c246f3e9ac0b7413ef110bd58b00c4efeeadd4038663839323161323636623131643066333334633632666535326261353361663139373739636232393438623635373066666130623737333936336331333061691a588e330c10a4ec7261f0b571486a8223f13fd7594e60eee6ce8013bf232f000000000102010103010106ad01ab0065000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001420140f950eaac2d303d039e089bda0e8739fa38383f21fc75bf7245c5272125f1e8887e6995eb0cd4a55074a2d3b7064c39df57bff0abd794df4a1b77e5dd35634c2b080200000921020aca705bbfdaea0fdaa052837c3801953a2642ca7009a99fe2884cb616bce3a50a2102532be57af750935525704043adcfd3deb611aafdfc49d6d2e6b3f4449fb706b0069f00040000000001210265c2da862edf7e730c69c5f1677ce0104a81adda912cc97f54a7aeec9e1b0943027400490001000120d56171676e46d0c338b0adf7b35da75d50257cfc12c85c2454bb0c97d340701f02220000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff012700010001220000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff091e00010001197368616c6c206265206c6966746564206e657665726d6f72650c04000000010d8ad7975125210f0ef1c314090f07c79a6f571c246f3e9ac0b7413ef110bd58b00c4efeeadd4038663839323161323636623131643066333334633632666535326261353361663139373739636232393438623635373066666130623737333936336331333061691a588e330c10a4ec7261f0b571486a8223f13fd7594e60eee6ce8013bf232f00000000010e2102fef70a63d6c8833d975ab289b70b84f14486c831dd5c9dc1e2b1c0346aa60c4e", "comment": "collectible with a meta reveal" } ], diff --git a/proof/testdata/proof_tlv_encoding_regtest.json b/proof/testdata/proof_tlv_encoding_regtest.json index 0ed5f76f7..f920ab82f 100644 --- a/proof/testdata/proof_tlv_encoding_regtest.json +++ b/proof/testdata/proof_tlv_encoding_regtest.json @@ -2,20 +2,20 @@ "valid_test_cases": [ { "proof": { - "prev_out": "4aa9bd697204b1c3fe619d3dbd946b6def89a695b073817226e1b95268eb6a02:0", + "prev_out": "ff39901cd1c64ca010215ef9ab2b76aca2a1238fdc31e67b648e4e0194df0e00:0", "block_header": { "version": 541065216, - "prev_block": "57f6b11cd0db2c1d637decafd90b3bd3309363c2d4d45fb156b8b27f55e6b059", - "merkle_root": "5a1be559ace05eba4ec2342e6557cd8fabe1b71bbf3556689fec05bb3de2d6f1", - "timestamp": 1695050241, + "prev_block": "576de0d5e5257b5785617348d64ea69b0e65ec648edfa27f002242c487e7906d", + "merkle_root": "00b4d1031160fa1116fc5e312b157e5e65e054ef2b9f21b380a5137cb2a95167", + "timestamp": 1696275650, "bits": 545259519, "nonce": 0 }, "block_height": 441, - "anchor_tx": "02000000000101026aeb6852b9e126728173b095a689ef6d6b94bd3d9d61fec3b1047269bda94a0000000000ffffffff02e803000000000000225120236c5808b93f883f906ca0376aff708bf134201050b312296a4288f42ddb23fd5cd5f505000000002251200b2278f01c9a023299df781e97d1b1b0b3439074520b3d04af5037276e53b3b40247304402207afd360d401e9f3b9b65a625a6acc811fb3aa2e156bada2b9351a86cd0388240022023d60132ee2337a56a4d0857f8f58a027b34ffadd15375c50c0f2dae728422e6012102609f61c627ecef1d03917f9c3a5bd1538aa41ead964495acd0809b79f265b1be00000000", + "anchor_tx": "02000000000101000edf94014e8e647be631dc8f23a1a2ac762babf95e2110a04cc6d11c9039ff0000000000ffffffff02e8030000000000002251209f19d16ebf0c9db6bcd66c20bdec8ce77686cf2e60ce98166921bd83fe03ad055cd5f50500000000225120acc12eab663fb6f8f90dcf3d91c483037a67fdd75d3216490d5611e7f200aebb0247304402203c15338ec7b6d08f7b2e420bfcab4949daa20e14b447c55c438b5275b774ab66022057d834bc625fe1e99cfe9bc2cf9dbe4b54c81d1afe299574cc45a9a8560901e101210393c4b6c16602cd15501cd7d4621bb1d76d7ff6cf17b936ba9a0d18502ac176c800000000", "tx_merkle_proof": { "nodes": [ - "e4167376e0d6891698db786b87ecc3c72ca8c7a3cfd012b537db493b727a3bfc" + "e2ea6a03a878abf451ab668b46f565eaeb0bcc3027e7a22e22ea6cadeb588412" ], "bits": [ false @@ -23,9 +23,9 @@ }, "asset": { "version": 0, - "genesis_first_prev_out": "4aa9bd697204b1c3fe619d3dbd946b6def89a695b073817226e1b95268eb6a02:0", + "genesis_first_prev_out": "ff39901cd1c64ca010215ef9ab2b76aca2a1238fdc31e67b648e4e0194df0e00:0", "genesis_tag": "first-itestbuxx", - "genesis_meta_hash": "dedfcaf730cec72f6dbea97c64d4a4f3489edc3c2ff8413ad169e9717a3b058d", + "genesis_meta_hash": "72055b46e57b82693def0aab2e58eb4b78068238f3d62b84d89050b92fc2a6e5", "genesis_output_index": 0, "genesis_type": 0, "amount": 1500, @@ -44,21 +44,21 @@ ], "split_commitment_root": null, "script_version": 0, - "script_key": "0238d9be0d7b1927e9668fc1780c57fc393f98d82e0f4b342be0787d3c2ee706f9", + "script_key": "02c06945dc5098fb3e2de9cd4b9aa02dfaf1858cf41199304059c91cafdeadffa9", "group_key": null }, "inclusion_proof": { "output_index": 0, - "internal_key": "0211d51ac1ce0db381304040cd098adbfb0c0ff4f5bb858dd0f601d9ba403a194c", + "internal_key": "03362012747699f7831e77c94521bf9fe0c2ac5c0531fa1564325e635291014699", "commitment_proof": { "proof": { "asset_proof": { "proof": "0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "version": 0, - "asset_id": "ea7d47abcbf3935868eb78ecfa55bcee3b1baa50554582770b85cf94184de99c" + "asset_id": "e304927a992c3a1d81f50586301c1f055f59923c236b93704097d02fdcd9eb78" }, "taproot_asset_proof": { - "proof": "00010af283fc2adee4aa40c4b2ed45b042d43d10a72c5e5f75d6c2a9ffb9fec5372400000000000007d0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f", + "proof": "00010dd71200ea8127c566c152d000934e4092b4dc21127637980ac2294a19fe7d2200000000000007d0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbf", "version": 0 } }, @@ -69,7 +69,7 @@ "exclusion_proofs": [ { "output_index": 1, - "internal_key": "02f79b0250bf95d352830296036208cb71afd87b17194ed8d10dc53452b0341624", + "internal_key": "027c2a94ef87bc6410a98e7334db8898a4dee8687cf2306ace7fd6a2720947ac96", "commitment_proof": null, "tapscript_proof": { "tap_preimage_1": "", @@ -80,18 +80,26 @@ ], "split_root_proof": null, "meta_reveal": { - "type": 0, + "type": 1, "data": "69746573742d6d65746164617461" }, "additional_inputs": null, - "challenge_witness": null + "challenge_witness": null, + "genesis_reveal": { + "first_prev_out": "ff39901cd1c64ca010215ef9ab2b76aca2a1238fdc31e67b648e4e0194df0e00:0", + "tag": "first-itestbuxx", + "meta_hash": "72055b46e57b82693def0aab2e58eb4b78068238f3d62b84d89050b92fc2a6e5", + "output_index": 0, + "type": 0 + }, + "group_key_reveal": null }, - "expected": "544150500004000000000124026aeb6852b9e126728173b095a689ef6d6b94bd3d9d61fec3b1047269bda94a0000000002500000402059b0e6557fb2b856b15fd4d4c2639330d33b0bd9afec7d631d2cdbd01cb1f657f1d6e23dbb05ec9f685635bf1bb7e1ab8fcd57652e34c24eba5ee0ac59e51b5a016a0865ffff7f200000000003f602000000000101026aeb6852b9e126728173b095a689ef6d6b94bd3d9d61fec3b1047269bda94a0000000000ffffffff02e803000000000000225120236c5808b93f883f906ca0376aff708bf134201050b312296a4288f42ddb23fd5cd5f505000000002251200b2278f01c9a023299df781e97d1b1b0b3439074520b3d04af5037276e53b3b40247304402207afd360d401e9f3b9b65a625a6acc811fb3aa2e156bada2b9351a86cd0388240022023d60132ee2337a56a4d0857f8f58a027b34ffadd15375c50c0f2dae728422e6012102609f61c627ecef1d03917f9c3a5bd1538aa41ead964495acd0809b79f265b1be00000000042201fc3b7a723b49db37b512d0cfa3c7a82cc7c3ec876b78db981689d6e0767316e40005f80001000159026aeb6852b9e126728173b095a689ef6d6b94bd3d9d61fec3b1047269bda94a000000000f66697273742d697465737462757878dedfcaf730cec72f6dbea97c64d4a4f3489edc3c2ff8413ad169e9717a3b058d00000000000201000303fd05dc06690167006500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000802000009210238d9be0d7b1927e9668fc1780c57fc393f98d82e0f4b342be0787d3c2ee706f906c700040000000001210211d51ac1ce0db381304040cd098adbfb0c0ff4f5bb858dd0f601d9ba403a194c029c00490001000120ea7d47abcbf3935868eb78ecfa55bcee3b1baa50554582770b85cf94184de99c02220000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff014f000100014a00010af283fc2adee4aa40c4b2ed45b042d43d10a72c5e5f75d6c2a9ffb9fec5372400000000000007d0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f0730012e000400000001012102f79b0250bf95d352830296036208cb71afd87b17194ed8d10dc53452b034162403030201010913000100010e69746573742d6d657461646174610c04000001b9", + "expected": "544150500004000000000124000edf94014e8e647be631dc8f23a1a2ac762babf95e2110a04cc6d11c9039ff000000000250000040206d90e787c44222007fa2df8e64ec650e9ba64ed648736185577b25e5d5e06d576751a9b27c13a580b3219f2bef54e0655e7e152b315efc1611fa601103d1b400c21c1b65ffff7f200000000003f602000000000101000edf94014e8e647be631dc8f23a1a2ac762babf95e2110a04cc6d11c9039ff0000000000ffffffff02e8030000000000002251209f19d16ebf0c9db6bcd66c20bdec8ce77686cf2e60ce98166921bd83fe03ad055cd5f50500000000225120acc12eab663fb6f8f90dcf3d91c483037a67fdd75d3216490d5611e7f200aebb0247304402203c15338ec7b6d08f7b2e420bfcab4949daa20e14b447c55c438b5275b774ab66022057d834bc625fe1e99cfe9bc2cf9dbe4b54c81d1afe299574cc45a9a8560901e101210393c4b6c16602cd15501cd7d4621bb1d76d7ff6cf17b936ba9a0d18502ac176c800000000042201128458ebad6cea222ea2e72730cc0bebea65f5468b66ab51f4ab78a8036aeae20005f80001000159000edf94014e8e647be631dc8f23a1a2ac762babf95e2110a04cc6d11c9039ff000000000f66697273742d69746573746275787872055b46e57b82693def0aab2e58eb4b78068238f3d62b84d89050b92fc2a6e500000000000201000303fd05dc066901670065000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008020000092102c06945dc5098fb3e2de9cd4b9aa02dfaf1858cf41199304059c91cafdeadffa906c7000400000000012103362012747699f7831e77c94521bf9fe0c2ac5c0531fa1564325e635291014699029c00490001000120e304927a992c3a1d81f50586301c1f055f59923c236b93704097d02fdcd9eb7802220000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff014f000100014a00010dd71200ea8127c566c152d000934e4092b4dc21127637980ac2294a19fe7d2200000000000007d0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbf0730012e0004000000010121027c2a94ef87bc6410a98e7334db8898a4dee8687cf2306ace7fd6a2720947ac9603030201010913000101010e69746573742d6d657461646174610c04000001b90d59000edf94014e8e647be631dc8f23a1a2ac762babf95e2110a04cc6d11c9039ff000000000f66697273742d69746573746275787872055b46e57b82693def0aab2e58eb4b78068238f3d62b84d89050b92fc2a6e50000000000", "comment": "valid regtest genesis proof with meta reveal" }, { "proof": { - "prev_out": "d60518b65c02c3c6f5d9740c23198f22326ffe3af99bbf4a598714638c82b535:0", + "prev_out": "cd95b60d105a94b428c0672782fb444346a9fa542cb71bf718ca1baf6225dd84:0", "block_header": { "version": 0, "prev_block": "0000000000000000000000000000000000000000000000000000000000000000", @@ -101,16 +109,16 @@ "nonce": 0 }, "block_height": 0, - "anchor_tx": "020000000001020680d31d053e99fd4d7a05629714af8965179a10817119235b9d65b15d543e2c0000000000ffffffff35b5828c631487594abf9bf93afe6f32228f19230c74d9f5c6c3025cb61805d600000000000000000003e8030000000000002251203026afffa7c1ae44bfc8be0dd4330e1b39dc3c24643687df9a6ac39f6784fbe6e8030000000000002251208233c433a3ed62870bbd76ddb75cef159e7e7620d84c53426178dea384d38c5725d0f5050000000022512064bc6a13119fba156f9151b314ee27d2475504c5b55dfbb67ab15bbe1a17090602483045022100894ed4d986076ee45d0aabd189d47b69791e55c860ccd78f86c8fecf270ca0d8022015cc3da88b7b76581358b642a9c6cb512315b4b7a5f6273b1e1d2fef7d5d01b1012102ce4b86727aa44c70ec1bb03808d0d18346adb4bca9f0e84ee16de53c7bf498c70140fdd3e845797fd13bceef5d226555e9a593e601224dadb9fde1a70cef8154f049f59c0cb930a7313778258bfbcc40dd4675bc86b06c7b9ae14cd6a4551b284b1200000000", + "anchor_tx": "020000000001028a46df72ee521269648983dac8216d0d6925590b83b157263e45244aeb8302040000000000ffffffff84dd2562af1bca18f71bb72c54faa9464344fb822767c028b4945a100db695cd00000000000000000003e8030000000000002251209c107483f86a56f53e9f6bfb02be5b8c1b01fb8a579a80128a89c5f0534ffd6ce803000000000000225120e016af66bb25dec6174eb55094ed7e901c82dd82d9c4dc4a65f7a268a53a408925d0f5050000000022512047b4284f3d5b066a61acf172d27814392a41729b6cec0b721ff450f26e77454f0247304402202fa5096b8561d841ccb48308495072180cf29ce1eb3072838e5fe860bdf0cbf102200da38e6bc0b13feb6bcab2917af1ed32d006a29e04de5806446888cb9bcfccfe012102597566522e2ea567e32bad2329119c6d34597ced654179ea28f99328d86addb30140b602be182cbae6779c7260c9c2f418751b2c36e9eb7ef9061b1705713c6813b524bda304c436d45af383fc59d366a12137929e7ec32c3e73b9dd5d6fdfea2f8100000000", "tx_merkle_proof": { "nodes": [], "bits": [] }, "asset": { "version": 0, - "genesis_first_prev_out": "4aa9bd697204b1c3fe619d3dbd946b6def89a695b073817226e1b95268eb6a02:0", + "genesis_first_prev_out": "ff39901cd1c64ca010215ef9ab2b76aca2a1238fdc31e67b648e4e0194df0e00:0", "genesis_tag": "first-itestbuxx", - "genesis_meta_hash": "dedfcaf730cec72f6dbea97c64d4a4f3489edc3c2ff8413ad169e9717a3b058d", + "genesis_meta_hash": "72055b46e57b82693def0aab2e58eb4b78068238f3d62b84d89050b92fc2a6e5", "genesis_output_index": 0, "genesis_type": 0, "amount": 300, @@ -119,36 +127,36 @@ "prev_witnesses": [ { "prev_id": { - "out_point": "d60518b65c02c3c6f5d9740c23198f22326ffe3af99bbf4a598714638c82b535:0", - "asset_id": "ea7d47abcbf3935868eb78ecfa55bcee3b1baa50554582770b85cf94184de99c", - "script_key": "0238d9be0d7b1927e9668fc1780c57fc393f98d82e0f4b342be0787d3c2ee706f9" + "out_point": "cd95b60d105a94b428c0672782fb444346a9fa542cb71bf718ca1baf6225dd84:0", + "asset_id": "e304927a992c3a1d81f50586301c1f055f59923c236b93704097d02fdcd9eb78", + "script_key": "02c06945dc5098fb3e2de9cd4b9aa02dfaf1858cf41199304059c91cafdeadffa9" }, "tx_witness": [ - "972817a9848b677b44232f2d67b62b609eb36024389bdb11365a484cbf00a2d79eb13409aeb12883e35c739f7e934fe88d05020c75f148fdbbf618fce69a2f62" + "5ecbbad87c0d10eb4add9fad29855cac988b00aec245e280279e41f00dc1d7058366a1640ae62ae13ea999dec1eaf0bd3ec6294d0856880a21dd6cb74c2da702" ], "split_commitment": null } ], "split_commitment_root": { - "hash": "e37e4f2dd531f4cce52f9f1e19dda65e6db1b3fcff797eb4aafd4bdc26d36abc", + "hash": "780d3433f32490d520b08c284474dd7a466884bd30b699f91ed26d0954eebfba", "sum": "1500" }, "script_version": 0, - "script_key": "025afa47611c1083b459846b54c6f17da8e188a323e0c0e2a15be0c188aae8ad14", + "script_key": "02a249cc2b97c7e9177be1618f0bb0e198df9255742fc43535b62a74a28665dd22", "group_key": null }, "inclusion_proof": { "output_index": 0, - "internal_key": "03d40f66bd36bb9fd86c93e01e37667f9dd464f7de4eaa7bcdd8ff9d8e844e6e4f", + "internal_key": "02877e26cda63f3132fdc8c8014a7c7e3af61fc0a65fd53a7aa3e29e9bc61f1f0e", "commitment_proof": { "proof": { "asset_proof": { "proof": "0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "version": 0, - "asset_id": "ea7d47abcbf3935868eb78ecfa55bcee3b1baa50554582770b85cf94184de99c" + "asset_id": "e304927a992c3a1d81f50586301c1f055f59923c236b93704097d02fdcd9eb78" }, "taproot_asset_proof": { - "proof": "0001667067559e7e7080a9a275e7daa660c6656980a683e36d2c8dce71dbcd0bc74100000000000007d0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f", + "proof": "00016b23e7898ae748e0535d806f4db0d0e76489849c2b149ba4498a7f054f72aad800000000000007d0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbf", "version": 0 } }, @@ -159,13 +167,13 @@ "exclusion_proofs": [ { "output_index": 1, - "internal_key": "02aa01ca611dcc3ac2054da4d48ed1e304409e3fa28f109b9b267efe57791dc9c3", + "internal_key": "02841246205825ef81c3ff94c0a06e54729478969021b56d3f12bc5c03cb05a2d8", "commitment_proof": { "proof": { "asset_proof": { - "proof": "0001b42fc7a58d9b915d5bfd72c45193cf7c49a848db1ae5126372921e9807a63d9f00000000000004b0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f", + "proof": "0001a048be6ca5cebfe16843a018f64bccafd0b08fab3b3fe2098256d3a37e60663600000000000004b0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdf", "version": 0, - "asset_id": "ea7d47abcbf3935868eb78ecfa55bcee3b1baa50554582770b85cf94184de99c" + "asset_id": "e304927a992c3a1d81f50586301c1f055f59923c236b93704097d02fdcd9eb78" }, "taproot_asset_proof": { "proof": "0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", @@ -178,7 +186,7 @@ }, { "output_index": 2, - "internal_key": "02cd39142f8263fbdcb58ff1b26a1ef6334d0c7da96da4e6ebffa268e059817023", + "internal_key": "02c151dec9d86d14ee166c98859e54324bbf7e1f07921ab0a6feaad10c3f2780af", "commitment_proof": null, "tapscript_proof": { "tap_preimage_1": "", @@ -190,14 +198,16 @@ "split_root_proof": null, "meta_reveal": null, "additional_inputs": null, - "challenge_witness": null + "challenge_witness": null, + "genesis_reveal": null, + "group_key_reveal": null }, - "expected": "54415050000400000000012435b5828c631487594abf9bf93afe6f32228f19230c74d9f5c6c3025cb61805d6000000000250000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000096e88000000000000000003fd018d020000000001020680d31d053e99fd4d7a05629714af8965179a10817119235b9d65b15d543e2c0000000000ffffffff35b5828c631487594abf9bf93afe6f32228f19230c74d9f5c6c3025cb61805d600000000000000000003e8030000000000002251203026afffa7c1ae44bfc8be0dd4330e1b39dc3c24643687df9a6ac39f6784fbe6e8030000000000002251208233c433a3ed62870bbd76ddb75cef159e7e7620d84c53426178dea384d38c5725d0f5050000000022512064bc6a13119fba156f9151b314ee27d2475504c5b55dfbb67ab15bbe1a17090602483045022100894ed4d986076ee45d0aabd189d47b69791e55c860ccd78f86c8fecf270ca0d8022015cc3da88b7b76581358b642a9c6cb512315b4b7a5f6273b1e1d2fef7d5d01b1012102ce4b86727aa44c70ec1bb03808d0d18346adb4bca9f0e84ee16de53c7bf498c70140fdd3e845797fd13bceef5d226555e9a593e601224dadb9fde1a70cef8154f049f59c0cb930a7313778258bfbcc40dd4675bc86b06c7b9ae14cd6a4551b284b120000000004010005fd01660001000159026aeb6852b9e126728173b095a689ef6d6b94bd3d9d61fec3b1047269bda94a000000000f66697273742d697465737462757878dedfcaf730cec72f6dbea97c64d4a4f3489edc3c2ff8413ad169e9717a3b058d00000000000201000303fd012c06ad01ab006535b5828c631487594abf9bf93afe6f32228f19230c74d9f5c6c3025cb61805d600000000ea7d47abcbf3935868eb78ecfa55bcee3b1baa50554582770b85cf94184de99c0238d9be0d7b1927e9668fc1780c57fc393f98d82e0f4b342be0787d3c2ee706f901420140972817a9848b677b44232f2d67b62b609eb36024389bdb11365a484cbf00a2d79eb13409aeb12883e35c739f7e934fe88d05020c75f148fdbbf618fce69a2f620728e37e4f2dd531f4cce52f9f1e19dda65e6db1b3fcff797eb4aafd4bdc26d36abc00000000000005dc080200000921025afa47611c1083b459846b54c6f17da8e188a323e0c0e2a15be0c188aae8ad1406c7000400000000012103d40f66bd36bb9fd86c93e01e37667f9dd464f7de4eaa7bcdd8ff9d8e844e6e4f029c00490001000120ea7d47abcbf3935868eb78ecfa55bcee3b1baa50554582770b85cf94184de99c02220000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff014f000100014a0001667067559e7e7080a9a275e7daa660c6656980a683e36d2c8dce71dbcd0bc74100000000000007d0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f07f802c7000400000001012102aa01ca611dcc3ac2054da4d48ed1e304409e3fa28f109b9b267efe57791dc9c3029c00710001000120ea7d47abcbf3935868eb78ecfa55bcee3b1baa50554582770b85cf94184de99c024a0001b42fc7a58d9b915d5bfd72c45193cf7c49a848db1ae5126372921e9807a63d9f00000000000004b0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f012700010001220000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff2e000400000002012102cd39142f8263fbdcb58ff1b26a1ef6334d0c7da96da4e6ebffa268e05981702303030201010c0400000000", + "expected": "54415050000400000000012484dd2562af1bca18f71bb72c54faa9464344fb822767c028b4945a100db695cd000000000250000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000096e88000000000000000003fd018c020000000001028a46df72ee521269648983dac8216d0d6925590b83b157263e45244aeb8302040000000000ffffffff84dd2562af1bca18f71bb72c54faa9464344fb822767c028b4945a100db695cd00000000000000000003e8030000000000002251209c107483f86a56f53e9f6bfb02be5b8c1b01fb8a579a80128a89c5f0534ffd6ce803000000000000225120e016af66bb25dec6174eb55094ed7e901c82dd82d9c4dc4a65f7a268a53a408925d0f5050000000022512047b4284f3d5b066a61acf172d27814392a41729b6cec0b721ff450f26e77454f0247304402202fa5096b8561d841ccb48308495072180cf29ce1eb3072838e5fe860bdf0cbf102200da38e6bc0b13feb6bcab2917af1ed32d006a29e04de5806446888cb9bcfccfe012102597566522e2ea567e32bad2329119c6d34597ced654179ea28f99328d86addb30140b602be182cbae6779c7260c9c2f418751b2c36e9eb7ef9061b1705713c6813b524bda304c436d45af383fc59d366a12137929e7ec32c3e73b9dd5d6fdfea2f810000000004010005fd01660001000159000edf94014e8e647be631dc8f23a1a2ac762babf95e2110a04cc6d11c9039ff000000000f66697273742d69746573746275787872055b46e57b82693def0aab2e58eb4b78068238f3d62b84d89050b92fc2a6e500000000000201000303fd012c06ad01ab006584dd2562af1bca18f71bb72c54faa9464344fb822767c028b4945a100db695cd00000000e304927a992c3a1d81f50586301c1f055f59923c236b93704097d02fdcd9eb7802c06945dc5098fb3e2de9cd4b9aa02dfaf1858cf41199304059c91cafdeadffa9014201405ecbbad87c0d10eb4add9fad29855cac988b00aec245e280279e41f00dc1d7058366a1640ae62ae13ea999dec1eaf0bd3ec6294d0856880a21dd6cb74c2da7020728780d3433f32490d520b08c284474dd7a466884bd30b699f91ed26d0954eebfba00000000000005dc08020000092102a249cc2b97c7e9177be1618f0bb0e198df9255742fc43535b62a74a28665dd2206c7000400000000012102877e26cda63f3132fdc8c8014a7c7e3af61fc0a65fd53a7aa3e29e9bc61f1f0e029c00490001000120e304927a992c3a1d81f50586301c1f055f59923c236b93704097d02fdcd9eb7802220000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff014f000100014a00016b23e7898ae748e0535d806f4db0d0e76489849c2b149ba4498a7f054f72aad800000000000007d0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbf07f802c7000400000001012102841246205825ef81c3ff94c0a06e54729478969021b56d3f12bc5c03cb05a2d8029c00710001000120e304927a992c3a1d81f50586301c1f055f59923c236b93704097d02fdcd9eb78024a0001a048be6ca5cebfe16843a018f64bccafd0b08fab3b3fe2098256d3a37e60663600000000000004b0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdf012700010001220000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff2e000400000002012102c151dec9d86d14ee166c98859e54324bbf7e1f07921ab0a6feaad10c3f2780af03030201010c0400000000", "comment": "valid regtest proof for split root" }, { "proof": { - "prev_out": "d60518b65c02c3c6f5d9740c23198f22326ffe3af99bbf4a598714638c82b535:0", + "prev_out": "cd95b60d105a94b428c0672782fb444346a9fa542cb71bf718ca1baf6225dd84:0", "block_header": { "version": 0, "prev_block": "0000000000000000000000000000000000000000000000000000000000000000", @@ -207,16 +217,16 @@ "nonce": 0 }, "block_height": 0, - "anchor_tx": "020000000001020680d31d053e99fd4d7a05629714af8965179a10817119235b9d65b15d543e2c0000000000ffffffff35b5828c631487594abf9bf93afe6f32228f19230c74d9f5c6c3025cb61805d600000000000000000003e8030000000000002251203026afffa7c1ae44bfc8be0dd4330e1b39dc3c24643687df9a6ac39f6784fbe6e8030000000000002251208233c433a3ed62870bbd76ddb75cef159e7e7620d84c53426178dea384d38c5725d0f5050000000022512064bc6a13119fba156f9151b314ee27d2475504c5b55dfbb67ab15bbe1a17090602483045022100894ed4d986076ee45d0aabd189d47b69791e55c860ccd78f86c8fecf270ca0d8022015cc3da88b7b76581358b642a9c6cb512315b4b7a5f6273b1e1d2fef7d5d01b1012102ce4b86727aa44c70ec1bb03808d0d18346adb4bca9f0e84ee16de53c7bf498c70140fdd3e845797fd13bceef5d226555e9a593e601224dadb9fde1a70cef8154f049f59c0cb930a7313778258bfbcc40dd4675bc86b06c7b9ae14cd6a4551b284b1200000000", + "anchor_tx": "020000000001028a46df72ee521269648983dac8216d0d6925590b83b157263e45244aeb8302040000000000ffffffff84dd2562af1bca18f71bb72c54faa9464344fb822767c028b4945a100db695cd00000000000000000003e8030000000000002251209c107483f86a56f53e9f6bfb02be5b8c1b01fb8a579a80128a89c5f0534ffd6ce803000000000000225120e016af66bb25dec6174eb55094ed7e901c82dd82d9c4dc4a65f7a268a53a408925d0f5050000000022512047b4284f3d5b066a61acf172d27814392a41729b6cec0b721ff450f26e77454f0247304402202fa5096b8561d841ccb48308495072180cf29ce1eb3072838e5fe860bdf0cbf102200da38e6bc0b13feb6bcab2917af1ed32d006a29e04de5806446888cb9bcfccfe012102597566522e2ea567e32bad2329119c6d34597ced654179ea28f99328d86addb30140b602be182cbae6779c7260c9c2f418751b2c36e9eb7ef9061b1705713c6813b524bda304c436d45af383fc59d366a12137929e7ec32c3e73b9dd5d6fdfea2f8100000000", "tx_merkle_proof": { "nodes": [], "bits": [] }, "asset": { "version": 0, - "genesis_first_prev_out": "4aa9bd697204b1c3fe619d3dbd946b6def89a695b073817226e1b95268eb6a02:0", + "genesis_first_prev_out": "ff39901cd1c64ca010215ef9ab2b76aca2a1238fdc31e67b648e4e0194df0e00:0", "genesis_tag": "first-itestbuxx", - "genesis_meta_hash": "dedfcaf730cec72f6dbea97c64d4a4f3489edc3c2ff8413ad169e9717a3b058d", + "genesis_meta_hash": "72055b46e57b82693def0aab2e58eb4b78068238f3d62b84d89050b92fc2a6e5", "genesis_output_index": 0, "genesis_type": 0, "amount": 1200, @@ -231,12 +241,12 @@ }, "tx_witness": null, "split_commitment": { - "proof": "0001be0fe4b9e225cbb4f4ddfe05048a23e7469f52599f46f23bf53ac2ad795811c6000000000000012cffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f", + "proof": "0001283e580e7adec8cd31c6de2731d02a66805e9fdee68dc431ddd91abefe88ae46000000000000012cffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f", "root_asset": { "version": 0, - "genesis_first_prev_out": "4aa9bd697204b1c3fe619d3dbd946b6def89a695b073817226e1b95268eb6a02:0", + "genesis_first_prev_out": "ff39901cd1c64ca010215ef9ab2b76aca2a1238fdc31e67b648e4e0194df0e00:0", "genesis_tag": "first-itestbuxx", - "genesis_meta_hash": "dedfcaf730cec72f6dbea97c64d4a4f3489edc3c2ff8413ad169e9717a3b058d", + "genesis_meta_hash": "72055b46e57b82693def0aab2e58eb4b78068238f3d62b84d89050b92fc2a6e5", "genesis_output_index": 0, "genesis_type": 0, "amount": 300, @@ -245,22 +255,22 @@ "prev_witnesses": [ { "prev_id": { - "out_point": "d60518b65c02c3c6f5d9740c23198f22326ffe3af99bbf4a598714638c82b535:0", - "asset_id": "ea7d47abcbf3935868eb78ecfa55bcee3b1baa50554582770b85cf94184de99c", - "script_key": "0238d9be0d7b1927e9668fc1780c57fc393f98d82e0f4b342be0787d3c2ee706f9" + "out_point": "cd95b60d105a94b428c0672782fb444346a9fa542cb71bf718ca1baf6225dd84:0", + "asset_id": "e304927a992c3a1d81f50586301c1f055f59923c236b93704097d02fdcd9eb78", + "script_key": "02c06945dc5098fb3e2de9cd4b9aa02dfaf1858cf41199304059c91cafdeadffa9" }, "tx_witness": [ - "972817a9848b677b44232f2d67b62b609eb36024389bdb11365a484cbf00a2d79eb13409aeb12883e35c739f7e934fe88d05020c75f148fdbbf618fce69a2f62" + "5ecbbad87c0d10eb4add9fad29855cac988b00aec245e280279e41f00dc1d7058366a1640ae62ae13ea999dec1eaf0bd3ec6294d0856880a21dd6cb74c2da702" ], "split_commitment": null } ], "split_commitment_root": { - "hash": "e37e4f2dd531f4cce52f9f1e19dda65e6db1b3fcff797eb4aafd4bdc26d36abc", + "hash": "780d3433f32490d520b08c284474dd7a466884bd30b699f91ed26d0954eebfba", "sum": "1500" }, "script_version": 0, - "script_key": "025afa47611c1083b459846b54c6f17da8e188a323e0c0e2a15be0c188aae8ad14", + "script_key": "02a249cc2b97c7e9177be1618f0bb0e198df9255742fc43535b62a74a28665dd22", "group_key": null } } @@ -268,18 +278,18 @@ ], "split_commitment_root": null, "script_version": 0, - "script_key": "025dc1551a12879e464751c5d58adc47170366eec5ea474d4f08069faf0ec4a846", + "script_key": "02aee2739664013a7de5c6c324f520af0dda900e53fdde79d97caae61f53b8634b", "group_key": null }, "inclusion_proof": { "output_index": 1, - "internal_key": "02aa01ca611dcc3ac2054da4d48ed1e304409e3fa28f109b9b267efe57791dc9c3", + "internal_key": "02841246205825ef81c3ff94c0a06e54729478969021b56d3f12bc5c03cb05a2d8", "commitment_proof": { "proof": { "asset_proof": { "proof": "0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "version": 0, - "asset_id": "ea7d47abcbf3935868eb78ecfa55bcee3b1baa50554582770b85cf94184de99c" + "asset_id": "e304927a992c3a1d81f50586301c1f055f59923c236b93704097d02fdcd9eb78" }, "taproot_asset_proof": { "proof": "0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", @@ -293,16 +303,16 @@ "exclusion_proofs": [ { "output_index": 0, - "internal_key": "03d40f66bd36bb9fd86c93e01e37667f9dd464f7de4eaa7bcdd8ff9d8e844e6e4f", + "internal_key": "02877e26cda63f3132fdc8c8014a7c7e3af61fc0a65fd53a7aa3e29e9bc61f1f0e", "commitment_proof": { "proof": { "asset_proof": { - "proof": "000123687967d493575aa2b80a0444e4d7d29e01cd9253a36273340ef90f31c65843000000000000012cffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f", + "proof": "00016d94f8a19c6342c684b4ef2aadf0501ef73e2241b22cc9450732e1a8b768424a000000000000012cffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdf", "version": 0, - "asset_id": "ea7d47abcbf3935868eb78ecfa55bcee3b1baa50554582770b85cf94184de99c" + "asset_id": "e304927a992c3a1d81f50586301c1f055f59923c236b93704097d02fdcd9eb78" }, "taproot_asset_proof": { - "proof": "0001667067559e7e7080a9a275e7daa660c6656980a683e36d2c8dce71dbcd0bc74100000000000007d0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f", + "proof": "00016b23e7898ae748e0535d806f4db0d0e76489849c2b149ba4498a7f054f72aad800000000000007d0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbf", "version": 0 } }, @@ -312,7 +322,7 @@ }, { "output_index": 2, - "internal_key": "02cd39142f8263fbdcb58ff1b26a1ef6334d0c7da96da4e6ebffa268e059817023", + "internal_key": "02c151dec9d86d14ee166c98859e54324bbf7e1f07921ab0a6feaad10c3f2780af", "commitment_proof": null, "tapscript_proof": { "tap_preimage_1": "", @@ -323,16 +333,16 @@ ], "split_root_proof": { "output_index": 0, - "internal_key": "03d40f66bd36bb9fd86c93e01e37667f9dd464f7de4eaa7bcdd8ff9d8e844e6e4f", + "internal_key": "02877e26cda63f3132fdc8c8014a7c7e3af61fc0a65fd53a7aa3e29e9bc61f1f0e", "commitment_proof": { "proof": { "asset_proof": { "proof": "0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "version": 0, - "asset_id": "ea7d47abcbf3935868eb78ecfa55bcee3b1baa50554582770b85cf94184de99c" + "asset_id": "e304927a992c3a1d81f50586301c1f055f59923c236b93704097d02fdcd9eb78" }, "taproot_asset_proof": { - "proof": "0001667067559e7e7080a9a275e7daa660c6656980a683e36d2c8dce71dbcd0bc74100000000000007d0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f", + "proof": "00016b23e7898ae748e0535d806f4db0d0e76489849c2b149ba4498a7f054f72aad800000000000007d0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbf", "version": 0 } }, @@ -342,27 +352,29 @@ }, "meta_reveal": null, "additional_inputs": null, - "challenge_witness": null + "challenge_witness": null, + "genesis_reveal": null, + "group_key_reveal": null }, - "expected": "54415050000400000000012435b5828c631487594abf9bf93afe6f32228f19230c74d9f5c6c3025cb61805d6000000000250000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000096e88000000000000000003fd018d020000000001020680d31d053e99fd4d7a05629714af8965179a10817119235b9d65b15d543e2c0000000000ffffffff35b5828c631487594abf9bf93afe6f32228f19230c74d9f5c6c3025cb61805d600000000000000000003e8030000000000002251203026afffa7c1ae44bfc8be0dd4330e1b39dc3c24643687df9a6ac39f6784fbe6e8030000000000002251208233c433a3ed62870bbd76ddb75cef159e7e7620d84c53426178dea384d38c5725d0f5050000000022512064bc6a13119fba156f9151b314ee27d2475504c5b55dfbb67ab15bbe1a17090602483045022100894ed4d986076ee45d0aabd189d47b69791e55c860ccd78f86c8fecf270ca0d8022015cc3da88b7b76581358b642a9c6cb512315b4b7a5f6273b1e1d2fef7d5d01b1012102ce4b86727aa44c70ec1bb03808d0d18346adb4bca9f0e84ee16de53c7bf498c70140fdd3e845797fd13bceef5d226555e9a593e601224dadb9fde1a70cef8154f049f59c0cb930a7313778258bfbcc40dd4675bc86b06c7b9ae14cd6a4551b284b120000000004010005fd02b40001000159026aeb6852b9e126728173b095a689ef6d6b94bd3d9d61fec3b1047269bda94a000000000f66697273742d697465737462757878dedfcaf730cec72f6dbea97c64d4a4f3489edc3c2ff8413ad169e9717a3b058d00000000000201000303fd04b006fd022301fd021f0065000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002fd01b44a0001be0fe4b9e225cbb4f4ddfe05048a23e7469f52599f46f23bf53ac2ad795811c6000000000000012cffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7ffd01660001000159026aeb6852b9e126728173b095a689ef6d6b94bd3d9d61fec3b1047269bda94a000000000f66697273742d697465737462757878dedfcaf730cec72f6dbea97c64d4a4f3489edc3c2ff8413ad169e9717a3b058d00000000000201000303fd012c06ad01ab006535b5828c631487594abf9bf93afe6f32228f19230c74d9f5c6c3025cb61805d600000000ea7d47abcbf3935868eb78ecfa55bcee3b1baa50554582770b85cf94184de99c0238d9be0d7b1927e9668fc1780c57fc393f98d82e0f4b342be0787d3c2ee706f901420140972817a9848b677b44232f2d67b62b609eb36024389bdb11365a484cbf00a2d79eb13409aeb12883e35c739f7e934fe88d05020c75f148fdbbf618fce69a2f620728e37e4f2dd531f4cce52f9f1e19dda65e6db1b3fcff797eb4aafd4bdc26d36abc00000000000005dc080200000921025afa47611c1083b459846b54c6f17da8e188a323e0c0e2a15be0c188aae8ad14080200000921025dc1551a12879e464751c5d58adc47170366eec5ea474d4f08069faf0ec4a846069f000400000001012102aa01ca611dcc3ac2054da4d48ed1e304409e3fa28f109b9b267efe57791dc9c3027400490001000120ea7d47abcbf3935868eb78ecfa55bcee3b1baa50554582770b85cf94184de99c02220000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff012700010001220000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff07fd012002ef000400000000012103d40f66bd36bb9fd86c93e01e37667f9dd464f7de4eaa7bcdd8ff9d8e844e6e4f02c400710001000120ea7d47abcbf3935868eb78ecfa55bcee3b1baa50554582770b85cf94184de99c024a000123687967d493575aa2b80a0444e4d7d29e01cd9253a36273340ef90f31c65843000000000000012cffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f014f000100014a0001667067559e7e7080a9a275e7daa660c6656980a683e36d2c8dce71dbcd0bc74100000000000007d0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f2e000400000002012102cd39142f8263fbdcb58ff1b26a1ef6334d0c7da96da4e6ebffa268e059817023030302010108c7000400000000012103d40f66bd36bb9fd86c93e01e37667f9dd464f7de4eaa7bcdd8ff9d8e844e6e4f029c00490001000120ea7d47abcbf3935868eb78ecfa55bcee3b1baa50554582770b85cf94184de99c02220000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff014f000100014a0001667067559e7e7080a9a275e7daa660c6656980a683e36d2c8dce71dbcd0bc74100000000000007d0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f0c0400000000", + "expected": "54415050000400000000012484dd2562af1bca18f71bb72c54faa9464344fb822767c028b4945a100db695cd000000000250000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000096e88000000000000000003fd018c020000000001028a46df72ee521269648983dac8216d0d6925590b83b157263e45244aeb8302040000000000ffffffff84dd2562af1bca18f71bb72c54faa9464344fb822767c028b4945a100db695cd00000000000000000003e8030000000000002251209c107483f86a56f53e9f6bfb02be5b8c1b01fb8a579a80128a89c5f0534ffd6ce803000000000000225120e016af66bb25dec6174eb55094ed7e901c82dd82d9c4dc4a65f7a268a53a408925d0f5050000000022512047b4284f3d5b066a61acf172d27814392a41729b6cec0b721ff450f26e77454f0247304402202fa5096b8561d841ccb48308495072180cf29ce1eb3072838e5fe860bdf0cbf102200da38e6bc0b13feb6bcab2917af1ed32d006a29e04de5806446888cb9bcfccfe012102597566522e2ea567e32bad2329119c6d34597ced654179ea28f99328d86addb30140b602be182cbae6779c7260c9c2f418751b2c36e9eb7ef9061b1705713c6813b524bda304c436d45af383fc59d366a12137929e7ec32c3e73b9dd5d6fdfea2f810000000004010005fd02b40001000159000edf94014e8e647be631dc8f23a1a2ac762babf95e2110a04cc6d11c9039ff000000000f66697273742d69746573746275787872055b46e57b82693def0aab2e58eb4b78068238f3d62b84d89050b92fc2a6e500000000000201000303fd04b006fd022301fd021f0065000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002fd01b44a0001283e580e7adec8cd31c6de2731d02a66805e9fdee68dc431ddd91abefe88ae46000000000000012cffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7ffd01660001000159000edf94014e8e647be631dc8f23a1a2ac762babf95e2110a04cc6d11c9039ff000000000f66697273742d69746573746275787872055b46e57b82693def0aab2e58eb4b78068238f3d62b84d89050b92fc2a6e500000000000201000303fd012c06ad01ab006584dd2562af1bca18f71bb72c54faa9464344fb822767c028b4945a100db695cd00000000e304927a992c3a1d81f50586301c1f055f59923c236b93704097d02fdcd9eb7802c06945dc5098fb3e2de9cd4b9aa02dfaf1858cf41199304059c91cafdeadffa9014201405ecbbad87c0d10eb4add9fad29855cac988b00aec245e280279e41f00dc1d7058366a1640ae62ae13ea999dec1eaf0bd3ec6294d0856880a21dd6cb74c2da7020728780d3433f32490d520b08c284474dd7a466884bd30b699f91ed26d0954eebfba00000000000005dc08020000092102a249cc2b97c7e9177be1618f0bb0e198df9255742fc43535b62a74a28665dd2208020000092102aee2739664013a7de5c6c324f520af0dda900e53fdde79d97caae61f53b8634b069f000400000001012102841246205825ef81c3ff94c0a06e54729478969021b56d3f12bc5c03cb05a2d8027400490001000120e304927a992c3a1d81f50586301c1f055f59923c236b93704097d02fdcd9eb7802220000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff012700010001220000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff07fd012002ef000400000000012102877e26cda63f3132fdc8c8014a7c7e3af61fc0a65fd53a7aa3e29e9bc61f1f0e02c400710001000120e304927a992c3a1d81f50586301c1f055f59923c236b93704097d02fdcd9eb78024a00016d94f8a19c6342c684b4ef2aadf0501ef73e2241b22cc9450732e1a8b768424a000000000000012cffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdf014f000100014a00016b23e7898ae748e0535d806f4db0d0e76489849c2b149ba4498a7f054f72aad800000000000007d0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbf2e000400000002012102c151dec9d86d14ee166c98859e54324bbf7e1f07921ab0a6feaad10c3f2780af030302010108c7000400000000012102877e26cda63f3132fdc8c8014a7c7e3af61fc0a65fd53a7aa3e29e9bc61f1f0e029c00490001000120e304927a992c3a1d81f50586301c1f055f59923c236b93704097d02fdcd9eb7802220000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff014f000100014a00016b23e7898ae748e0535d806f4db0d0e76489849c2b149ba4498a7f054f72aad800000000000007d0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbf0c0400000000", "comment": "valid regtest split proof" }, { "proof": { - "prev_out": "085f3d0999a0fad576c4a42136f771a2f33dc10da864463dbfabd4d91a1c3807:1", + "prev_out": "5be7e3c66c4090094e7dc10e2b4b38604539d8b2ae5c3a49f6d5bfcf0a8fee61:1", "block_header": { "version": 541065216, - "prev_block": "25e3fc469329f0a99254faf1a6813406dc2ecbca48297443a1496d74107f9c5c", - "merkle_root": "3a581730224dde9347896476ad1f2d6935129151833e73860583db4b6aa09f62", - "timestamp": 1695050241, + "prev_block": "7db85b3fadf578b79582702d071079f16af3432ceb7d62481502854b6d25a992", + "merkle_root": "676a14c4868be64125fc0c20402bd8716c50d3e89edef715434e66466ca03ed8", + "timestamp": 1696275650, "bits": 545259519, - "nonce": 0 + "nonce": 6 }, "block_height": 444, - "anchor_tx": "0200000000010203f8ac0fa47f7eaf42dbf8ec9b135849dcd49b69ffe980b6ecf88293a0b143ba0000000000ffffffff07381c1ad9d4abbf3d4664a80dc13df3a271f73621a4c476d5faa099093d5f0801000000000000000003e803000000000000225120a914766a8a19bb8cc1fe8c17f411aae5fc6841fea6b807ce73d66ebdabf08d52e80300000000000022512087a21c8d7a5d3d0bea676166a83bfcf12ae3c92b7f14bc1fff7d54820eda441a25d0f50500000000225120fe19c6b74a18eccd85988ed33b3d3204e4ccc8f43c2a10b3958d0a9cf6d95f1a02473044022023174c06060685d720e6c711922a07245083222df195fb75524c89b14a30606d02203eea3947bb6bdc65dae743823ee358817a688b9d39271f149c770777933793b401210357ef09bf2d5c536341f759d7d2825e64a9f5954a750250e7cd1fe4d2cf92b3d501403b17cc53283398a529d534a70835d6fe22f45e30d48d9c87e2d3d83b9173670a5280636b53724dd7822692826274c7058a58016038e1a690c7e6366d69d9a6d900000000", + "anchor_tx": "0200000000010204478bc55a872d647f4b68a48f6d8d2240d18d03b9370a7f38743f4827cd99430000000000ffffffff61ee8f0acfbfd5f6493a5caeb2d8394560384b2b0ec17d4e0990406cc6e3e75b01000000000000000003e80300000000000022512028fb02ae7f93d46f673d798597985b2e26f3caeba668be40eb215e7e3b4583c7e80300000000000022512032b6eeb107b144586f1134b285d9f0dcb432233188851829e131aa4478264ef325d0f50500000000225120dec8af6483c79fa7ea39bea834b92024acfe5c1b6ccdd66889048c2ca0a206600247304402207820ce964c23db5429446ea89d666b45d1b3c4fae30aec6894d34214ad0ed089022044d895c3ba0b30babbe5f927795ab186e5384bb25596e2623caeb94029ee64af0121032cbea8ed49a89ee5c69276349fb9fa4a98613ced896cacc4019c02c97314e77001403aff7a5dc8b6501541c36ad1500c5dd84f59f0c3d732e0417fe7bc28371704a5981b0a8bdfd57c592efaad8e0913b29b43ff97a0822d7ee6b65d3d4fdb1d3f9f00000000", "tx_merkle_proof": { "nodes": [ - "bdaabfdb4342c13201b0bfcf9527516e90cef1a95e6b24ec898bfe75b2282361" + "89f114b9364e77c9257bfb697d6cc244bbc9778b61632f96347fccf23c32a05a" ], "bits": [ false @@ -370,9 +382,9 @@ }, "asset": { "version": 0, - "genesis_first_prev_out": "4aa9bd697204b1c3fe619d3dbd946b6def89a695b073817226e1b95268eb6a02:0", + "genesis_first_prev_out": "ff39901cd1c64ca010215ef9ab2b76aca2a1238fdc31e67b648e4e0194df0e00:0", "genesis_tag": "first-itestbuxx", - "genesis_meta_hash": "dedfcaf730cec72f6dbea97c64d4a4f3489edc3c2ff8413ad169e9717a3b058d", + "genesis_meta_hash": "72055b46e57b82693def0aab2e58eb4b78068238f3d62b84d89050b92fc2a6e5", "genesis_output_index": 0, "genesis_type": 0, "amount": 600, @@ -387,12 +399,12 @@ }, "tx_witness": null, "split_commitment": { - "proof": "000176db3c90a94d1d88883b15f2ea49cea0db1a6b99df666bdb2f4717cc259d3c310000000000000258ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f", + "proof": "0001e829447f0dd17d26880ba56a672caa4de2859a5d732799f39077d1ee48595d7b0000000000000258ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdf", "root_asset": { "version": 0, - "genesis_first_prev_out": "4aa9bd697204b1c3fe619d3dbd946b6def89a695b073817226e1b95268eb6a02:0", + "genesis_first_prev_out": "ff39901cd1c64ca010215ef9ab2b76aca2a1238fdc31e67b648e4e0194df0e00:0", "genesis_tag": "first-itestbuxx", - "genesis_meta_hash": "dedfcaf730cec72f6dbea97c64d4a4f3489edc3c2ff8413ad169e9717a3b058d", + "genesis_meta_hash": "72055b46e57b82693def0aab2e58eb4b78068238f3d62b84d89050b92fc2a6e5", "genesis_output_index": 0, "genesis_type": 0, "amount": 600, @@ -401,22 +413,22 @@ "prev_witnesses": [ { "prev_id": { - "out_point": "085f3d0999a0fad576c4a42136f771a2f33dc10da864463dbfabd4d91a1c3807:1", - "asset_id": "ea7d47abcbf3935868eb78ecfa55bcee3b1baa50554582770b85cf94184de99c", - "script_key": "025dc1551a12879e464751c5d58adc47170366eec5ea474d4f08069faf0ec4a846" + "out_point": "5be7e3c66c4090094e7dc10e2b4b38604539d8b2ae5c3a49f6d5bfcf0a8fee61:1", + "asset_id": "e304927a992c3a1d81f50586301c1f055f59923c236b93704097d02fdcd9eb78", + "script_key": "02aee2739664013a7de5c6c324f520af0dda900e53fdde79d97caae61f53b8634b" }, "tx_witness": [ - "30a59f8083dbf0f9a2cecb670fdaeede2c8f7162cdf016d9125fd5826ac5f13e64b587ba9c9224c71af999d495388ef16a9c8f00c28c8487ed84d30c676ca992" + "cc16977679b45a50b64c03b363b95ca3389590495ca742018735f531d5ce3fe6b88dfda0637e06e6eba86e1cdd9f2df4e4cb96ff7c36effd1b50a73334674bd6" ], "split_commitment": null } ], "split_commitment_root": { - "hash": "fcf3a9d2bf6a83827c22662bfa10d095aa5dbc8d0ec54f3bd6e2ee3ab23d211d", + "hash": "1c6319db0fc74f357d435e6efd4406c54d6473fa35face18d29b47ecdf63a8c2", "sum": "1200" }, "script_version": 0, - "script_key": "02ada2da3880c78b716154464311235543576a4a25519c6d7408f16562706a4d6c", + "script_key": "0294aab4886e65569873d588d86dbbb9a8785576b251261170a378a30b2af2d3d2", "group_key": null } } @@ -424,18 +436,18 @@ ], "split_commitment_root": null, "script_version": 0, - "script_key": "02b16a1dabf41be280943e505ee522d4c349250ef1b7c4a0cb197516659eb72709", + "script_key": "02995eefdf358055573f2f70106f09c208f86277e7ab7038edfe52a7e2003c06d9", "group_key": null }, "inclusion_proof": { "output_index": 1, - "internal_key": "0205bd63c9712513e6b573490780fcaecbc9c3fe29807cf6eb9b65067415c77f3d", + "internal_key": "03cdff2a9995874b27e2dc83ae878b7753c925d996339455982250d6c237adecba", "commitment_proof": { "proof": { "asset_proof": { "proof": "0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "version": 0, - "asset_id": "ea7d47abcbf3935868eb78ecfa55bcee3b1baa50554582770b85cf94184de99c" + "asset_id": "e304927a992c3a1d81f50586301c1f055f59923c236b93704097d02fdcd9eb78" }, "taproot_asset_proof": { "proof": "0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", @@ -449,13 +461,13 @@ "exclusion_proofs": [ { "output_index": 0, - "internal_key": "030e0b3b55c02f39e7c4c9ab09ffc94a3329c64fff6ebae8848936dce9526e30fc", + "internal_key": "0260037c3b9987798745c48397b4651f2ee73d433f27aa3bb33f96744a6607b9f5", "commitment_proof": { "proof": { "asset_proof": { - "proof": "000126d95df7e2348c05a2e1b0d7a48473f4dba9128a1b948ec8c885ed667f1e95eb0000000000000258ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbf", + "proof": "000111bf752ef14c9095b14932062e5be15755cecbcd8cd5f26473dbb0a6db1373630000000000000258ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f", "version": 0, - "asset_id": "ea7d47abcbf3935868eb78ecfa55bcee3b1baa50554582770b85cf94184de99c" + "asset_id": "e304927a992c3a1d81f50586301c1f055f59923c236b93704097d02fdcd9eb78" }, "taproot_asset_proof": { "proof": "0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", @@ -468,7 +480,7 @@ }, { "output_index": 2, - "internal_key": "02649b305eb6b54187ff5acccc35bce9e47feea1bf3adbfcdc1be38d4c55cf249a", + "internal_key": "02ff7b62b0ada51df1a354f19f71dd957868b062515f7c1ae5f6e63a4643f4170b", "commitment_proof": null, "tapscript_proof": { "tap_preimage_1": "", @@ -479,13 +491,13 @@ ], "split_root_proof": { "output_index": 0, - "internal_key": "030e0b3b55c02f39e7c4c9ab09ffc94a3329c64fff6ebae8848936dce9526e30fc", + "internal_key": "0260037c3b9987798745c48397b4651f2ee73d433f27aa3bb33f96744a6607b9f5", "commitment_proof": { "proof": { "asset_proof": { "proof": "0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "version": 0, - "asset_id": "ea7d47abcbf3935868eb78ecfa55bcee3b1baa50554582770b85cf94184de99c" + "asset_id": "e304927a992c3a1d81f50586301c1f055f59923c236b93704097d02fdcd9eb78" }, "taproot_asset_proof": { "proof": "0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", @@ -499,28 +511,30 @@ "meta_reveal": null, "additional_inputs": null, "challenge_witness": [ - "65c422d0fee12eeccef954a2a9cad87b75eaedce45bd09af98a0a16d073b748740effa361e055bb28344a0a1523665dc10442ef9847208d7ab33b26eeff616c5" - ] + "0e5788a6d685c0aae69e29cc1178411d42e86d846505eec1b945c4ad24b88707b1fff685d69243efb70054852398881a4775c3fcd6178cda5347a60e84d3bd76" + ], + "genesis_reveal": null, + "group_key_reveal": null }, - "expected": "54415050000400000000012407381c1ad9d4abbf3d4664a80dc13df3a271f73621a4c476d5faa099093d5f08000000010250000040205c9c7f10746d49a143742948cacb2edc063481a6f1fa5492a9f0299346fce325629fa06a4bdb830586733e8351911235692d1fad7664894793de4d223017583a016a0865ffff7f200000000003fd018c0200000000010203f8ac0fa47f7eaf42dbf8ec9b135849dcd49b69ffe980b6ecf88293a0b143ba0000000000ffffffff07381c1ad9d4abbf3d4664a80dc13df3a271f73621a4c476d5faa099093d5f0801000000000000000003e803000000000000225120a914766a8a19bb8cc1fe8c17f411aae5fc6841fea6b807ce73d66ebdabf08d52e80300000000000022512087a21c8d7a5d3d0bea676166a83bfcf12ae3c92b7f14bc1fff7d54820eda441a25d0f50500000000225120fe19c6b74a18eccd85988ed33b3d3204e4ccc8f43c2a10b3958d0a9cf6d95f1a02473044022023174c06060685d720e6c711922a07245083222df195fb75524c89b14a30606d02203eea3947bb6bdc65dae743823ee358817a688b9d39271f149c770777933793b401210357ef09bf2d5c536341f759d7d2825e64a9f5954a750250e7cd1fe4d2cf92b3d501403b17cc53283398a529d534a70835d6fe22f45e30d48d9c87e2d3d83b9173670a5280636b53724dd7822692826274c7058a58016038e1a690c7e6366d69d9a6d900000000042201612328b275fe8b89ec246b5ea9f1ce906e512795cfbfb00132c14243dbbfaabd0005fd02b40001000159026aeb6852b9e126728173b095a689ef6d6b94bd3d9d61fec3b1047269bda94a000000000f66697273742d697465737462757878dedfcaf730cec72f6dbea97c64d4a4f3489edc3c2ff8413ad169e9717a3b058d00000000000201000303fd025806fd022301fd021f0065000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002fd01b44a000176db3c90a94d1d88883b15f2ea49cea0db1a6b99df666bdb2f4717cc259d3c310000000000000258ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7ffd01660001000159026aeb6852b9e126728173b095a689ef6d6b94bd3d9d61fec3b1047269bda94a000000000f66697273742d697465737462757878dedfcaf730cec72f6dbea97c64d4a4f3489edc3c2ff8413ad169e9717a3b058d00000000000201000303fd025806ad01ab006507381c1ad9d4abbf3d4664a80dc13df3a271f73621a4c476d5faa099093d5f0800000001ea7d47abcbf3935868eb78ecfa55bcee3b1baa50554582770b85cf94184de99c025dc1551a12879e464751c5d58adc47170366eec5ea474d4f08069faf0ec4a8460142014030a59f8083dbf0f9a2cecb670fdaeede2c8f7162cdf016d9125fd5826ac5f13e64b587ba9c9224c71af999d495388ef16a9c8f00c28c8487ed84d30c676ca9920728fcf3a9d2bf6a83827c22662bfa10d095aa5dbc8d0ec54f3bd6e2ee3ab23d211d00000000000004b008020000092102ada2da3880c78b716154464311235543576a4a25519c6d7408f16562706a4d6c08020000092102b16a1dabf41be280943e505ee522d4c349250ef1b7c4a0cb197516659eb72709069f00040000000101210205bd63c9712513e6b573490780fcaecbc9c3fe29807cf6eb9b65067415c77f3d027400490001000120ea7d47abcbf3935868eb78ecfa55bcee3b1baa50554582770b85cf94184de99c02220000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff012700010001220000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff07f802c70004000000000121030e0b3b55c02f39e7c4c9ab09ffc94a3329c64fff6ebae8848936dce9526e30fc029c00710001000120ea7d47abcbf3935868eb78ecfa55bcee3b1baa50554582770b85cf94184de99c024a000126d95df7e2348c05a2e1b0d7a48473f4dba9128a1b948ec8c885ed667f1e95eb0000000000000258ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbf012700010001220000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff2e000400000002012102649b305eb6b54187ff5acccc35bce9e47feea1bf3adbfcdc1be38d4c55cf249a0303020101089f0004000000000121030e0b3b55c02f39e7c4c9ab09ffc94a3329c64fff6ebae8848936dce9526e30fc027400490001000120ea7d47abcbf3935868eb78ecfa55bcee3b1baa50554582770b85cf94184de99c02220000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff012700010001220000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0b42014065c422d0fee12eeccef954a2a9cad87b75eaedce45bd09af98a0a16d073b748740effa361e055bb28344a0a1523665dc10442ef9847208d7ab33b26eeff616c50c04000001bc", + "expected": "54415050000400000000012461ee8f0acfbfd5f6493a5caeb2d8394560384b2b0ec17d4e0990406cc6e3e75b0000000102500000402092a9256d4b85021548627deb2c43f36af17910072d708295b778f5ad3f5bb87dd83ea06c46664e4315f7de9ee8d3506c71d82b40200cfc2541e68b86c4146a67c21c1b65ffff7f200600000003fd018c0200000000010204478bc55a872d647f4b68a48f6d8d2240d18d03b9370a7f38743f4827cd99430000000000ffffffff61ee8f0acfbfd5f6493a5caeb2d8394560384b2b0ec17d4e0990406cc6e3e75b01000000000000000003e80300000000000022512028fb02ae7f93d46f673d798597985b2e26f3caeba668be40eb215e7e3b4583c7e80300000000000022512032b6eeb107b144586f1134b285d9f0dcb432233188851829e131aa4478264ef325d0f50500000000225120dec8af6483c79fa7ea39bea834b92024acfe5c1b6ccdd66889048c2ca0a206600247304402207820ce964c23db5429446ea89d666b45d1b3c4fae30aec6894d34214ad0ed089022044d895c3ba0b30babbe5f927795ab186e5384bb25596e2623caeb94029ee64af0121032cbea8ed49a89ee5c69276349fb9fa4a98613ced896cacc4019c02c97314e77001403aff7a5dc8b6501541c36ad1500c5dd84f59f0c3d732e0417fe7bc28371704a5981b0a8bdfd57c592efaad8e0913b29b43ff97a0822d7ee6b65d3d4fdb1d3f9f000000000422015aa0323cf2cc7f34962f63618b77c9bb44c26c7d69fb7b25c9774e36b914f1890005fd02b40001000159000edf94014e8e647be631dc8f23a1a2ac762babf95e2110a04cc6d11c9039ff000000000f66697273742d69746573746275787872055b46e57b82693def0aab2e58eb4b78068238f3d62b84d89050b92fc2a6e500000000000201000303fd025806fd022301fd021f0065000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002fd01b44a0001e829447f0dd17d26880ba56a672caa4de2859a5d732799f39077d1ee48595d7b0000000000000258ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdffd01660001000159000edf94014e8e647be631dc8f23a1a2ac762babf95e2110a04cc6d11c9039ff000000000f66697273742d69746573746275787872055b46e57b82693def0aab2e58eb4b78068238f3d62b84d89050b92fc2a6e500000000000201000303fd025806ad01ab006561ee8f0acfbfd5f6493a5caeb2d8394560384b2b0ec17d4e0990406cc6e3e75b00000001e304927a992c3a1d81f50586301c1f055f59923c236b93704097d02fdcd9eb7802aee2739664013a7de5c6c324f520af0dda900e53fdde79d97caae61f53b8634b01420140cc16977679b45a50b64c03b363b95ca3389590495ca742018735f531d5ce3fe6b88dfda0637e06e6eba86e1cdd9f2df4e4cb96ff7c36effd1b50a73334674bd607281c6319db0fc74f357d435e6efd4406c54d6473fa35face18d29b47ecdf63a8c200000000000004b00802000009210294aab4886e65569873d588d86dbbb9a8785576b251261170a378a30b2af2d3d208020000092102995eefdf358055573f2f70106f09c208f86277e7ab7038edfe52a7e2003c06d9069f000400000001012103cdff2a9995874b27e2dc83ae878b7753c925d996339455982250d6c237adecba027400490001000120e304927a992c3a1d81f50586301c1f055f59923c236b93704097d02fdcd9eb7802220000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff012700010001220000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff07f802c700040000000001210260037c3b9987798745c48397b4651f2ee73d433f27aa3bb33f96744a6607b9f5029c00710001000120e304927a992c3a1d81f50586301c1f055f59923c236b93704097d02fdcd9eb78024a000111bf752ef14c9095b14932062e5be15755cecbcd8cd5f26473dbb0a6db1373630000000000000258ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f012700010001220000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff2e000400000002012102ff7b62b0ada51df1a354f19f71dd957868b062515f7c1ae5f6e63a4643f4170b0303020101089f00040000000001210260037c3b9987798745c48397b4651f2ee73d433f27aa3bb33f96744a6607b9f5027400490001000120e304927a992c3a1d81f50586301c1f055f59923c236b93704097d02fdcd9eb7802220000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff012700010001220000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0b4201400e5788a6d685c0aae69e29cc1178411d42e86d846505eec1b945c4ad24b88707b1fff685d69243efb70054852398881a4775c3fcd6178cda5347a60e84d3bd760c04000001bc", "comment": "valid regtest ownership proof" }, { "proof": { - "prev_out": "4aa9bd697204b1c3fe619d3dbd946b6def89a695b073817226e1b95268eb6a02:0", + "prev_out": "ff39901cd1c64ca010215ef9ab2b76aca2a1238fdc31e67b648e4e0194df0e00:0", "block_header": { "version": 541065216, - "prev_block": "57f6b11cd0db2c1d637decafd90b3bd3309363c2d4d45fb156b8b27f55e6b059", - "merkle_root": "5a1be559ace05eba4ec2342e6557cd8fabe1b71bbf3556689fec05bb3de2d6f1", - "timestamp": 1695050241, + "prev_block": "576de0d5e5257b5785617348d64ea69b0e65ec648edfa27f002242c487e7906d", + "merkle_root": "00b4d1031160fa1116fc5e312b157e5e65e054ef2b9f21b380a5137cb2a95167", + "timestamp": 1696275650, "bits": 545259519, "nonce": 0 }, "block_height": 441, - "anchor_tx": "02000000000101026aeb6852b9e126728173b095a689ef6d6b94bd3d9d61fec3b1047269bda94a0000000000ffffffff02e803000000000000225120236c5808b93f883f906ca0376aff708bf134201050b312296a4288f42ddb23fd5cd5f505000000002251200b2278f01c9a023299df781e97d1b1b0b3439074520b3d04af5037276e53b3b40247304402207afd360d401e9f3b9b65a625a6acc811fb3aa2e156bada2b9351a86cd0388240022023d60132ee2337a56a4d0857f8f58a027b34ffadd15375c50c0f2dae728422e6012102609f61c627ecef1d03917f9c3a5bd1538aa41ead964495acd0809b79f265b1be00000000", + "anchor_tx": "02000000000101000edf94014e8e647be631dc8f23a1a2ac762babf95e2110a04cc6d11c9039ff0000000000ffffffff02e8030000000000002251209f19d16ebf0c9db6bcd66c20bdec8ce77686cf2e60ce98166921bd83fe03ad055cd5f50500000000225120acc12eab663fb6f8f90dcf3d91c483037a67fdd75d3216490d5611e7f200aebb0247304402203c15338ec7b6d08f7b2e420bfcab4949daa20e14b447c55c438b5275b774ab66022057d834bc625fe1e99cfe9bc2cf9dbe4b54c81d1afe299574cc45a9a8560901e101210393c4b6c16602cd15501cd7d4621bb1d76d7ff6cf17b936ba9a0d18502ac176c800000000", "tx_merkle_proof": { "nodes": [ - "e4167376e0d6891698db786b87ecc3c72ca8c7a3cfd012b537db493b727a3bfc" + "e2ea6a03a878abf451ab668b46f565eaeb0bcc3027e7a22e22ea6cadeb588412" ], "bits": [ false @@ -528,9 +542,9 @@ }, "asset": { "version": 0, - "genesis_first_prev_out": "4aa9bd697204b1c3fe619d3dbd946b6def89a695b073817226e1b95268eb6a02:0", + "genesis_first_prev_out": "ff39901cd1c64ca010215ef9ab2b76aca2a1238fdc31e67b648e4e0194df0e00:0", "genesis_tag": "first-itestbuxx", - "genesis_meta_hash": "dedfcaf730cec72f6dbea97c64d4a4f3489edc3c2ff8413ad169e9717a3b058d", + "genesis_meta_hash": "72055b46e57b82693def0aab2e58eb4b78068238f3d62b84d89050b92fc2a6e5", "genesis_output_index": 0, "genesis_type": 0, "amount": 1500, @@ -549,21 +563,21 @@ ], "split_commitment_root": null, "script_version": 0, - "script_key": "0238d9be0d7b1927e9668fc1780c57fc393f98d82e0f4b342be0787d3c2ee706f9", + "script_key": "02c06945dc5098fb3e2de9cd4b9aa02dfaf1858cf41199304059c91cafdeadffa9", "group_key": null }, "inclusion_proof": { "output_index": 0, - "internal_key": "0211d51ac1ce0db381304040cd098adbfb0c0ff4f5bb858dd0f601d9ba403a194c", + "internal_key": "03362012747699f7831e77c94521bf9fe0c2ac5c0531fa1564325e635291014699", "commitment_proof": { "proof": { "asset_proof": { "proof": "0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "version": 0, - "asset_id": "ea7d47abcbf3935868eb78ecfa55bcee3b1baa50554582770b85cf94184de99c" + "asset_id": "e304927a992c3a1d81f50586301c1f055f59923c236b93704097d02fdcd9eb78" }, "taproot_asset_proof": { - "proof": "00010af283fc2adee4aa40c4b2ed45b042d43d10a72c5e5f75d6c2a9ffb9fec5372400000000000007d0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f", + "proof": "00010dd71200ea8127c566c152d000934e4092b4dc21127637980ac2294a19fe7d2200000000000007d0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbf", "version": 0 } }, @@ -574,7 +588,7 @@ "exclusion_proofs": [ { "output_index": 1, - "internal_key": "02f79b0250bf95d352830296036208cb71afd87b17194ed8d10dc53452b0341624", + "internal_key": "027c2a94ef87bc6410a98e7334db8898a4dee8687cf2306ace7fd6a2720947ac96", "commitment_proof": null, "tapscript_proof": { "tap_preimage_1": "", @@ -585,31 +599,39 @@ ], "split_root_proof": null, "meta_reveal": { - "type": 0, + "type": 1, "data": "69746573742d6d65746164617461" }, "additional_inputs": null, - "challenge_witness": null + "challenge_witness": null, + "genesis_reveal": { + "first_prev_out": "ff39901cd1c64ca010215ef9ab2b76aca2a1238fdc31e67b648e4e0194df0e00:0", + "tag": "first-itestbuxx", + "meta_hash": "72055b46e57b82693def0aab2e58eb4b78068238f3d62b84d89050b92fc2a6e5", + "output_index": 0, + "type": 0 + }, + "group_key_reveal": null }, - "expected": "544150500004000000000124026aeb6852b9e126728173b095a689ef6d6b94bd3d9d61fec3b1047269bda94a0000000002500000402059b0e6557fb2b856b15fd4d4c2639330d33b0bd9afec7d631d2cdbd01cb1f657f1d6e23dbb05ec9f685635bf1bb7e1ab8fcd57652e34c24eba5ee0ac59e51b5a016a0865ffff7f200000000003f602000000000101026aeb6852b9e126728173b095a689ef6d6b94bd3d9d61fec3b1047269bda94a0000000000ffffffff02e803000000000000225120236c5808b93f883f906ca0376aff708bf134201050b312296a4288f42ddb23fd5cd5f505000000002251200b2278f01c9a023299df781e97d1b1b0b3439074520b3d04af5037276e53b3b40247304402207afd360d401e9f3b9b65a625a6acc811fb3aa2e156bada2b9351a86cd0388240022023d60132ee2337a56a4d0857f8f58a027b34ffadd15375c50c0f2dae728422e6012102609f61c627ecef1d03917f9c3a5bd1538aa41ead964495acd0809b79f265b1be00000000042201fc3b7a723b49db37b512d0cfa3c7a82cc7c3ec876b78db981689d6e0767316e40005f80001000159026aeb6852b9e126728173b095a689ef6d6b94bd3d9d61fec3b1047269bda94a000000000f66697273742d697465737462757878dedfcaf730cec72f6dbea97c64d4a4f3489edc3c2ff8413ad169e9717a3b058d00000000000201000303fd05dc06690167006500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000802000009210238d9be0d7b1927e9668fc1780c57fc393f98d82e0f4b342be0787d3c2ee706f906c700040000000001210211d51ac1ce0db381304040cd098adbfb0c0ff4f5bb858dd0f601d9ba403a194c029c00490001000120ea7d47abcbf3935868eb78ecfa55bcee3b1baa50554582770b85cf94184de99c02220000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff014f000100014a00010af283fc2adee4aa40c4b2ed45b042d43d10a72c5e5f75d6c2a9ffb9fec5372400000000000007d0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f0730012e000400000001012102f79b0250bf95d352830296036208cb71afd87b17194ed8d10dc53452b034162403030201010913000100010e69746573742d6d657461646174610c04000001b9", + "expected": "544150500004000000000124000edf94014e8e647be631dc8f23a1a2ac762babf95e2110a04cc6d11c9039ff000000000250000040206d90e787c44222007fa2df8e64ec650e9ba64ed648736185577b25e5d5e06d576751a9b27c13a580b3219f2bef54e0655e7e152b315efc1611fa601103d1b400c21c1b65ffff7f200000000003f602000000000101000edf94014e8e647be631dc8f23a1a2ac762babf95e2110a04cc6d11c9039ff0000000000ffffffff02e8030000000000002251209f19d16ebf0c9db6bcd66c20bdec8ce77686cf2e60ce98166921bd83fe03ad055cd5f50500000000225120acc12eab663fb6f8f90dcf3d91c483037a67fdd75d3216490d5611e7f200aebb0247304402203c15338ec7b6d08f7b2e420bfcab4949daa20e14b447c55c438b5275b774ab66022057d834bc625fe1e99cfe9bc2cf9dbe4b54c81d1afe299574cc45a9a8560901e101210393c4b6c16602cd15501cd7d4621bb1d76d7ff6cf17b936ba9a0d18502ac176c800000000042201128458ebad6cea222ea2e72730cc0bebea65f5468b66ab51f4ab78a8036aeae20005f80001000159000edf94014e8e647be631dc8f23a1a2ac762babf95e2110a04cc6d11c9039ff000000000f66697273742d69746573746275787872055b46e57b82693def0aab2e58eb4b78068238f3d62b84d89050b92fc2a6e500000000000201000303fd05dc066901670065000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008020000092102c06945dc5098fb3e2de9cd4b9aa02dfaf1858cf41199304059c91cafdeadffa906c7000400000000012103362012747699f7831e77c94521bf9fe0c2ac5c0531fa1564325e635291014699029c00490001000120e304927a992c3a1d81f50586301c1f055f59923c236b93704097d02fdcd9eb7802220000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff014f000100014a00010dd71200ea8127c566c152d000934e4092b4dc21127637980ac2294a19fe7d2200000000000007d0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbf0730012e0004000000010121027c2a94ef87bc6410a98e7334db8898a4dee8687cf2306ace7fd6a2720947ac9603030201010913000101010e69746573742d6d657461646174610c04000001b90d59000edf94014e8e647be631dc8f23a1a2ac762babf95e2110a04cc6d11c9039ff000000000f66697273742d69746573746275787872055b46e57b82693def0aab2e58eb4b78068238f3d62b84d89050b92fc2a6e50000000000", "comment": "valid regtest proof file index 0" }, { "proof": { - "prev_out": "d60518b65c02c3c6f5d9740c23198f22326ffe3af99bbf4a598714638c82b535:0", + "prev_out": "cd95b60d105a94b428c0672782fb444346a9fa542cb71bf718ca1baf6225dd84:0", "block_header": { "version": 541065216, - "prev_block": "2b3d4e9a3b880c5fd24a3397615ac28fa0d872862f547c19f848fef3addb037f", - "merkle_root": "754cf28a72093cc203a37567ac10ca164cae1f4c98e76cf783b4ae4333774cc1", - "timestamp": 1695050241, + "prev_block": "44c08b1a2bcd152fa037e3ea80435be0f5950b2fcbdfc780e8f43f0faa27c56a", + "merkle_root": "1f1aecf56e2fbb411ce34e0183fa0c1bd8e2f8e617fc24847c434cc5fb76fd6f", + "timestamp": 1696275650, "bits": 545259519, - "nonce": 2 + "nonce": 1 }, "block_height": 442, - "anchor_tx": "020000000001020680d31d053e99fd4d7a05629714af8965179a10817119235b9d65b15d543e2c0000000000ffffffff35b5828c631487594abf9bf93afe6f32228f19230c74d9f5c6c3025cb61805d600000000000000000003e8030000000000002251203026afffa7c1ae44bfc8be0dd4330e1b39dc3c24643687df9a6ac39f6784fbe6e8030000000000002251208233c433a3ed62870bbd76ddb75cef159e7e7620d84c53426178dea384d38c5725d0f5050000000022512064bc6a13119fba156f9151b314ee27d2475504c5b55dfbb67ab15bbe1a17090602483045022100894ed4d986076ee45d0aabd189d47b69791e55c860ccd78f86c8fecf270ca0d8022015cc3da88b7b76581358b642a9c6cb512315b4b7a5f6273b1e1d2fef7d5d01b1012102ce4b86727aa44c70ec1bb03808d0d18346adb4bca9f0e84ee16de53c7bf498c70140fdd3e845797fd13bceef5d226555e9a593e601224dadb9fde1a70cef8154f049f59c0cb930a7313778258bfbcc40dd4675bc86b06c7b9ae14cd6a4551b284b1200000000", + "anchor_tx": "020000000001028a46df72ee521269648983dac8216d0d6925590b83b157263e45244aeb8302040000000000ffffffff84dd2562af1bca18f71bb72c54faa9464344fb822767c028b4945a100db695cd00000000000000000003e8030000000000002251209c107483f86a56f53e9f6bfb02be5b8c1b01fb8a579a80128a89c5f0534ffd6ce803000000000000225120e016af66bb25dec6174eb55094ed7e901c82dd82d9c4dc4a65f7a268a53a408925d0f5050000000022512047b4284f3d5b066a61acf172d27814392a41729b6cec0b721ff450f26e77454f0247304402202fa5096b8561d841ccb48308495072180cf29ce1eb3072838e5fe860bdf0cbf102200da38e6bc0b13feb6bcab2917af1ed32d006a29e04de5806446888cb9bcfccfe012102597566522e2ea567e32bad2329119c6d34597ced654179ea28f99328d86addb30140b602be182cbae6779c7260c9c2f418751b2c36e9eb7ef9061b1705713c6813b524bda304c436d45af383fc59d366a12137929e7ec32c3e73b9dd5d6fdfea2f8100000000", "tx_merkle_proof": { "nodes": [ - "42e923f9c26217601812b7111f92a52e04166f282b9333caed44530c4657cf92" + "3c1ac5b7126321b364ea0fa39df6631326a9aca2753e92f4a785a048e2a17cec" ], "bits": [ false @@ -617,9 +639,9 @@ }, "asset": { "version": 0, - "genesis_first_prev_out": "4aa9bd697204b1c3fe619d3dbd946b6def89a695b073817226e1b95268eb6a02:0", + "genesis_first_prev_out": "ff39901cd1c64ca010215ef9ab2b76aca2a1238fdc31e67b648e4e0194df0e00:0", "genesis_tag": "first-itestbuxx", - "genesis_meta_hash": "dedfcaf730cec72f6dbea97c64d4a4f3489edc3c2ff8413ad169e9717a3b058d", + "genesis_meta_hash": "72055b46e57b82693def0aab2e58eb4b78068238f3d62b84d89050b92fc2a6e5", "genesis_output_index": 0, "genesis_type": 0, "amount": 1200, @@ -634,12 +656,12 @@ }, "tx_witness": null, "split_commitment": { - "proof": "0001be0fe4b9e225cbb4f4ddfe05048a23e7469f52599f46f23bf53ac2ad795811c6000000000000012cffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f", + "proof": "0001283e580e7adec8cd31c6de2731d02a66805e9fdee68dc431ddd91abefe88ae46000000000000012cffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f", "root_asset": { "version": 0, - "genesis_first_prev_out": "4aa9bd697204b1c3fe619d3dbd946b6def89a695b073817226e1b95268eb6a02:0", + "genesis_first_prev_out": "ff39901cd1c64ca010215ef9ab2b76aca2a1238fdc31e67b648e4e0194df0e00:0", "genesis_tag": "first-itestbuxx", - "genesis_meta_hash": "dedfcaf730cec72f6dbea97c64d4a4f3489edc3c2ff8413ad169e9717a3b058d", + "genesis_meta_hash": "72055b46e57b82693def0aab2e58eb4b78068238f3d62b84d89050b92fc2a6e5", "genesis_output_index": 0, "genesis_type": 0, "amount": 300, @@ -648,22 +670,22 @@ "prev_witnesses": [ { "prev_id": { - "out_point": "d60518b65c02c3c6f5d9740c23198f22326ffe3af99bbf4a598714638c82b535:0", - "asset_id": "ea7d47abcbf3935868eb78ecfa55bcee3b1baa50554582770b85cf94184de99c", - "script_key": "0238d9be0d7b1927e9668fc1780c57fc393f98d82e0f4b342be0787d3c2ee706f9" + "out_point": "cd95b60d105a94b428c0672782fb444346a9fa542cb71bf718ca1baf6225dd84:0", + "asset_id": "e304927a992c3a1d81f50586301c1f055f59923c236b93704097d02fdcd9eb78", + "script_key": "02c06945dc5098fb3e2de9cd4b9aa02dfaf1858cf41199304059c91cafdeadffa9" }, "tx_witness": [ - "972817a9848b677b44232f2d67b62b609eb36024389bdb11365a484cbf00a2d79eb13409aeb12883e35c739f7e934fe88d05020c75f148fdbbf618fce69a2f62" + "5ecbbad87c0d10eb4add9fad29855cac988b00aec245e280279e41f00dc1d7058366a1640ae62ae13ea999dec1eaf0bd3ec6294d0856880a21dd6cb74c2da702" ], "split_commitment": null } ], "split_commitment_root": { - "hash": "e37e4f2dd531f4cce52f9f1e19dda65e6db1b3fcff797eb4aafd4bdc26d36abc", + "hash": "780d3433f32490d520b08c284474dd7a466884bd30b699f91ed26d0954eebfba", "sum": "1500" }, "script_version": 0, - "script_key": "025afa47611c1083b459846b54c6f17da8e188a323e0c0e2a15be0c188aae8ad14", + "script_key": "02a249cc2b97c7e9177be1618f0bb0e198df9255742fc43535b62a74a28665dd22", "group_key": null } } @@ -671,18 +693,18 @@ ], "split_commitment_root": null, "script_version": 0, - "script_key": "025dc1551a12879e464751c5d58adc47170366eec5ea474d4f08069faf0ec4a846", + "script_key": "02aee2739664013a7de5c6c324f520af0dda900e53fdde79d97caae61f53b8634b", "group_key": null }, "inclusion_proof": { "output_index": 1, - "internal_key": "02aa01ca611dcc3ac2054da4d48ed1e304409e3fa28f109b9b267efe57791dc9c3", + "internal_key": "02841246205825ef81c3ff94c0a06e54729478969021b56d3f12bc5c03cb05a2d8", "commitment_proof": { "proof": { "asset_proof": { "proof": "0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "version": 0, - "asset_id": "ea7d47abcbf3935868eb78ecfa55bcee3b1baa50554582770b85cf94184de99c" + "asset_id": "e304927a992c3a1d81f50586301c1f055f59923c236b93704097d02fdcd9eb78" }, "taproot_asset_proof": { "proof": "0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", @@ -696,16 +718,16 @@ "exclusion_proofs": [ { "output_index": 0, - "internal_key": "03d40f66bd36bb9fd86c93e01e37667f9dd464f7de4eaa7bcdd8ff9d8e844e6e4f", + "internal_key": "02877e26cda63f3132fdc8c8014a7c7e3af61fc0a65fd53a7aa3e29e9bc61f1f0e", "commitment_proof": { "proof": { "asset_proof": { - "proof": "000123687967d493575aa2b80a0444e4d7d29e01cd9253a36273340ef90f31c65843000000000000012cffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f", + "proof": "00016d94f8a19c6342c684b4ef2aadf0501ef73e2241b22cc9450732e1a8b768424a000000000000012cffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdf", "version": 0, - "asset_id": "ea7d47abcbf3935868eb78ecfa55bcee3b1baa50554582770b85cf94184de99c" + "asset_id": "e304927a992c3a1d81f50586301c1f055f59923c236b93704097d02fdcd9eb78" }, "taproot_asset_proof": { - "proof": "0001667067559e7e7080a9a275e7daa660c6656980a683e36d2c8dce71dbcd0bc74100000000000007d0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f", + "proof": "00016b23e7898ae748e0535d806f4db0d0e76489849c2b149ba4498a7f054f72aad800000000000007d0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbf", "version": 0 } }, @@ -715,7 +737,7 @@ }, { "output_index": 2, - "internal_key": "02cd39142f8263fbdcb58ff1b26a1ef6334d0c7da96da4e6ebffa268e059817023", + "internal_key": "02c151dec9d86d14ee166c98859e54324bbf7e1f07921ab0a6feaad10c3f2780af", "commitment_proof": null, "tapscript_proof": { "tap_preimage_1": "", @@ -726,16 +748,16 @@ ], "split_root_proof": { "output_index": 0, - "internal_key": "03d40f66bd36bb9fd86c93e01e37667f9dd464f7de4eaa7bcdd8ff9d8e844e6e4f", + "internal_key": "02877e26cda63f3132fdc8c8014a7c7e3af61fc0a65fd53a7aa3e29e9bc61f1f0e", "commitment_proof": { "proof": { "asset_proof": { "proof": "0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "version": 0, - "asset_id": "ea7d47abcbf3935868eb78ecfa55bcee3b1baa50554582770b85cf94184de99c" + "asset_id": "e304927a992c3a1d81f50586301c1f055f59923c236b93704097d02fdcd9eb78" }, "taproot_asset_proof": { - "proof": "0001667067559e7e7080a9a275e7daa660c6656980a683e36d2c8dce71dbcd0bc74100000000000007d0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f", + "proof": "00016b23e7898ae748e0535d806f4db0d0e76489849c2b149ba4498a7f054f72aad800000000000007d0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbf", "version": 0 } }, @@ -745,27 +767,29 @@ }, "meta_reveal": null, "additional_inputs": null, - "challenge_witness": null + "challenge_witness": null, + "genesis_reveal": null, + "group_key_reveal": null }, - "expected": "54415050000400000000012435b5828c631487594abf9bf93afe6f32228f19230c74d9f5c6c3025cb61805d6000000000250000040207f03dbadf3fe48f8197c542f8672d8a08fc25a6197334ad25f0c883b9a4e3d2bc14c773343aeb483f76ce7984c1fae4c16ca10ac6775a303c23c09728af24c75016a0865ffff7f200200000003fd018d020000000001020680d31d053e99fd4d7a05629714af8965179a10817119235b9d65b15d543e2c0000000000ffffffff35b5828c631487594abf9bf93afe6f32228f19230c74d9f5c6c3025cb61805d600000000000000000003e8030000000000002251203026afffa7c1ae44bfc8be0dd4330e1b39dc3c24643687df9a6ac39f6784fbe6e8030000000000002251208233c433a3ed62870bbd76ddb75cef159e7e7620d84c53426178dea384d38c5725d0f5050000000022512064bc6a13119fba156f9151b314ee27d2475504c5b55dfbb67ab15bbe1a17090602483045022100894ed4d986076ee45d0aabd189d47b69791e55c860ccd78f86c8fecf270ca0d8022015cc3da88b7b76581358b642a9c6cb512315b4b7a5f6273b1e1d2fef7d5d01b1012102ce4b86727aa44c70ec1bb03808d0d18346adb4bca9f0e84ee16de53c7bf498c70140fdd3e845797fd13bceef5d226555e9a593e601224dadb9fde1a70cef8154f049f59c0cb930a7313778258bfbcc40dd4675bc86b06c7b9ae14cd6a4551b284b120000000004220192cf57460c5344edca33932b286f16042ea5921f11b71218601762c2f923e9420005fd02b40001000159026aeb6852b9e126728173b095a689ef6d6b94bd3d9d61fec3b1047269bda94a000000000f66697273742d697465737462757878dedfcaf730cec72f6dbea97c64d4a4f3489edc3c2ff8413ad169e9717a3b058d00000000000201000303fd04b006fd022301fd021f0065000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002fd01b44a0001be0fe4b9e225cbb4f4ddfe05048a23e7469f52599f46f23bf53ac2ad795811c6000000000000012cffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7ffd01660001000159026aeb6852b9e126728173b095a689ef6d6b94bd3d9d61fec3b1047269bda94a000000000f66697273742d697465737462757878dedfcaf730cec72f6dbea97c64d4a4f3489edc3c2ff8413ad169e9717a3b058d00000000000201000303fd012c06ad01ab006535b5828c631487594abf9bf93afe6f32228f19230c74d9f5c6c3025cb61805d600000000ea7d47abcbf3935868eb78ecfa55bcee3b1baa50554582770b85cf94184de99c0238d9be0d7b1927e9668fc1780c57fc393f98d82e0f4b342be0787d3c2ee706f901420140972817a9848b677b44232f2d67b62b609eb36024389bdb11365a484cbf00a2d79eb13409aeb12883e35c739f7e934fe88d05020c75f148fdbbf618fce69a2f620728e37e4f2dd531f4cce52f9f1e19dda65e6db1b3fcff797eb4aafd4bdc26d36abc00000000000005dc080200000921025afa47611c1083b459846b54c6f17da8e188a323e0c0e2a15be0c188aae8ad14080200000921025dc1551a12879e464751c5d58adc47170366eec5ea474d4f08069faf0ec4a846069f000400000001012102aa01ca611dcc3ac2054da4d48ed1e304409e3fa28f109b9b267efe57791dc9c3027400490001000120ea7d47abcbf3935868eb78ecfa55bcee3b1baa50554582770b85cf94184de99c02220000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff012700010001220000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff07fd012002ef000400000000012103d40f66bd36bb9fd86c93e01e37667f9dd464f7de4eaa7bcdd8ff9d8e844e6e4f02c400710001000120ea7d47abcbf3935868eb78ecfa55bcee3b1baa50554582770b85cf94184de99c024a000123687967d493575aa2b80a0444e4d7d29e01cd9253a36273340ef90f31c65843000000000000012cffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f014f000100014a0001667067559e7e7080a9a275e7daa660c6656980a683e36d2c8dce71dbcd0bc74100000000000007d0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f2e000400000002012102cd39142f8263fbdcb58ff1b26a1ef6334d0c7da96da4e6ebffa268e059817023030302010108c7000400000000012103d40f66bd36bb9fd86c93e01e37667f9dd464f7de4eaa7bcdd8ff9d8e844e6e4f029c00490001000120ea7d47abcbf3935868eb78ecfa55bcee3b1baa50554582770b85cf94184de99c02220000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff014f000100014a0001667067559e7e7080a9a275e7daa660c6656980a683e36d2c8dce71dbcd0bc74100000000000007d0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f0c04000001ba", + "expected": "54415050000400000000012484dd2562af1bca18f71bb72c54faa9464344fb822767c028b4945a100db695cd000000000250000040206ac527aa0f3ff4e880c7dfcb2f0b95f5e05b4380eae337a02f15cd2b1a8bc0446ffd76fbc54c437c8424fc17e6f8e2d81b0cfa83014ee31c41bb2f6ef5ec1a1fc21c1b65ffff7f200100000003fd018c020000000001028a46df72ee521269648983dac8216d0d6925590b83b157263e45244aeb8302040000000000ffffffff84dd2562af1bca18f71bb72c54faa9464344fb822767c028b4945a100db695cd00000000000000000003e8030000000000002251209c107483f86a56f53e9f6bfb02be5b8c1b01fb8a579a80128a89c5f0534ffd6ce803000000000000225120e016af66bb25dec6174eb55094ed7e901c82dd82d9c4dc4a65f7a268a53a408925d0f5050000000022512047b4284f3d5b066a61acf172d27814392a41729b6cec0b721ff450f26e77454f0247304402202fa5096b8561d841ccb48308495072180cf29ce1eb3072838e5fe860bdf0cbf102200da38e6bc0b13feb6bcab2917af1ed32d006a29e04de5806446888cb9bcfccfe012102597566522e2ea567e32bad2329119c6d34597ced654179ea28f99328d86addb30140b602be182cbae6779c7260c9c2f418751b2c36e9eb7ef9061b1705713c6813b524bda304c436d45af383fc59d366a12137929e7ec32c3e73b9dd5d6fdfea2f8100000000042201ec7ca1e248a085a7f4923e75a2aca9261363f69da30fea64b3216312b7c51a3c0005fd02b40001000159000edf94014e8e647be631dc8f23a1a2ac762babf95e2110a04cc6d11c9039ff000000000f66697273742d69746573746275787872055b46e57b82693def0aab2e58eb4b78068238f3d62b84d89050b92fc2a6e500000000000201000303fd04b006fd022301fd021f0065000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002fd01b44a0001283e580e7adec8cd31c6de2731d02a66805e9fdee68dc431ddd91abefe88ae46000000000000012cffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7ffd01660001000159000edf94014e8e647be631dc8f23a1a2ac762babf95e2110a04cc6d11c9039ff000000000f66697273742d69746573746275787872055b46e57b82693def0aab2e58eb4b78068238f3d62b84d89050b92fc2a6e500000000000201000303fd012c06ad01ab006584dd2562af1bca18f71bb72c54faa9464344fb822767c028b4945a100db695cd00000000e304927a992c3a1d81f50586301c1f055f59923c236b93704097d02fdcd9eb7802c06945dc5098fb3e2de9cd4b9aa02dfaf1858cf41199304059c91cafdeadffa9014201405ecbbad87c0d10eb4add9fad29855cac988b00aec245e280279e41f00dc1d7058366a1640ae62ae13ea999dec1eaf0bd3ec6294d0856880a21dd6cb74c2da7020728780d3433f32490d520b08c284474dd7a466884bd30b699f91ed26d0954eebfba00000000000005dc08020000092102a249cc2b97c7e9177be1618f0bb0e198df9255742fc43535b62a74a28665dd2208020000092102aee2739664013a7de5c6c324f520af0dda900e53fdde79d97caae61f53b8634b069f000400000001012102841246205825ef81c3ff94c0a06e54729478969021b56d3f12bc5c03cb05a2d8027400490001000120e304927a992c3a1d81f50586301c1f055f59923c236b93704097d02fdcd9eb7802220000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff012700010001220000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff07fd012002ef000400000000012102877e26cda63f3132fdc8c8014a7c7e3af61fc0a65fd53a7aa3e29e9bc61f1f0e02c400710001000120e304927a992c3a1d81f50586301c1f055f59923c236b93704097d02fdcd9eb78024a00016d94f8a19c6342c684b4ef2aadf0501ef73e2241b22cc9450732e1a8b768424a000000000000012cffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdf014f000100014a00016b23e7898ae748e0535d806f4db0d0e76489849c2b149ba4498a7f054f72aad800000000000007d0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbf2e000400000002012102c151dec9d86d14ee166c98859e54324bbf7e1f07921ab0a6feaad10c3f2780af030302010108c7000400000000012102877e26cda63f3132fdc8c8014a7c7e3af61fc0a65fd53a7aa3e29e9bc61f1f0e029c00490001000120e304927a992c3a1d81f50586301c1f055f59923c236b93704097d02fdcd9eb7802220000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff014f000100014a00016b23e7898ae748e0535d806f4db0d0e76489849c2b149ba4498a7f054f72aad800000000000007d0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbf0c04000001ba", "comment": "valid regtest proof file index 1" }, { "proof": { - "prev_out": "085f3d0999a0fad576c4a42136f771a2f33dc10da864463dbfabd4d91a1c3807:1", + "prev_out": "5be7e3c66c4090094e7dc10e2b4b38604539d8b2ae5c3a49f6d5bfcf0a8fee61:1", "block_header": { "version": 541065216, - "prev_block": "25e3fc469329f0a99254faf1a6813406dc2ecbca48297443a1496d74107f9c5c", - "merkle_root": "3a581730224dde9347896476ad1f2d6935129151833e73860583db4b6aa09f62", - "timestamp": 1695050241, + "prev_block": "7db85b3fadf578b79582702d071079f16af3432ceb7d62481502854b6d25a992", + "merkle_root": "676a14c4868be64125fc0c20402bd8716c50d3e89edef715434e66466ca03ed8", + "timestamp": 1696275650, "bits": 545259519, - "nonce": 0 + "nonce": 6 }, "block_height": 444, - "anchor_tx": "0200000000010203f8ac0fa47f7eaf42dbf8ec9b135849dcd49b69ffe980b6ecf88293a0b143ba0000000000ffffffff07381c1ad9d4abbf3d4664a80dc13df3a271f73621a4c476d5faa099093d5f0801000000000000000003e803000000000000225120a914766a8a19bb8cc1fe8c17f411aae5fc6841fea6b807ce73d66ebdabf08d52e80300000000000022512087a21c8d7a5d3d0bea676166a83bfcf12ae3c92b7f14bc1fff7d54820eda441a25d0f50500000000225120fe19c6b74a18eccd85988ed33b3d3204e4ccc8f43c2a10b3958d0a9cf6d95f1a02473044022023174c06060685d720e6c711922a07245083222df195fb75524c89b14a30606d02203eea3947bb6bdc65dae743823ee358817a688b9d39271f149c770777933793b401210357ef09bf2d5c536341f759d7d2825e64a9f5954a750250e7cd1fe4d2cf92b3d501403b17cc53283398a529d534a70835d6fe22f45e30d48d9c87e2d3d83b9173670a5280636b53724dd7822692826274c7058a58016038e1a690c7e6366d69d9a6d900000000", + "anchor_tx": "0200000000010204478bc55a872d647f4b68a48f6d8d2240d18d03b9370a7f38743f4827cd99430000000000ffffffff61ee8f0acfbfd5f6493a5caeb2d8394560384b2b0ec17d4e0990406cc6e3e75b01000000000000000003e80300000000000022512028fb02ae7f93d46f673d798597985b2e26f3caeba668be40eb215e7e3b4583c7e80300000000000022512032b6eeb107b144586f1134b285d9f0dcb432233188851829e131aa4478264ef325d0f50500000000225120dec8af6483c79fa7ea39bea834b92024acfe5c1b6ccdd66889048c2ca0a206600247304402207820ce964c23db5429446ea89d666b45d1b3c4fae30aec6894d34214ad0ed089022044d895c3ba0b30babbe5f927795ab186e5384bb25596e2623caeb94029ee64af0121032cbea8ed49a89ee5c69276349fb9fa4a98613ced896cacc4019c02c97314e77001403aff7a5dc8b6501541c36ad1500c5dd84f59f0c3d732e0417fe7bc28371704a5981b0a8bdfd57c592efaad8e0913b29b43ff97a0822d7ee6b65d3d4fdb1d3f9f00000000", "tx_merkle_proof": { "nodes": [ - "bdaabfdb4342c13201b0bfcf9527516e90cef1a95e6b24ec898bfe75b2282361" + "89f114b9364e77c9257bfb697d6cc244bbc9778b61632f96347fccf23c32a05a" ], "bits": [ false @@ -773,9 +797,9 @@ }, "asset": { "version": 0, - "genesis_first_prev_out": "4aa9bd697204b1c3fe619d3dbd946b6def89a695b073817226e1b95268eb6a02:0", + "genesis_first_prev_out": "ff39901cd1c64ca010215ef9ab2b76aca2a1238fdc31e67b648e4e0194df0e00:0", "genesis_tag": "first-itestbuxx", - "genesis_meta_hash": "dedfcaf730cec72f6dbea97c64d4a4f3489edc3c2ff8413ad169e9717a3b058d", + "genesis_meta_hash": "72055b46e57b82693def0aab2e58eb4b78068238f3d62b84d89050b92fc2a6e5", "genesis_output_index": 0, "genesis_type": 0, "amount": 600, @@ -790,12 +814,12 @@ }, "tx_witness": null, "split_commitment": { - "proof": "000176db3c90a94d1d88883b15f2ea49cea0db1a6b99df666bdb2f4717cc259d3c310000000000000258ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f", + "proof": "0001e829447f0dd17d26880ba56a672caa4de2859a5d732799f39077d1ee48595d7b0000000000000258ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdf", "root_asset": { "version": 0, - "genesis_first_prev_out": "4aa9bd697204b1c3fe619d3dbd946b6def89a695b073817226e1b95268eb6a02:0", + "genesis_first_prev_out": "ff39901cd1c64ca010215ef9ab2b76aca2a1238fdc31e67b648e4e0194df0e00:0", "genesis_tag": "first-itestbuxx", - "genesis_meta_hash": "dedfcaf730cec72f6dbea97c64d4a4f3489edc3c2ff8413ad169e9717a3b058d", + "genesis_meta_hash": "72055b46e57b82693def0aab2e58eb4b78068238f3d62b84d89050b92fc2a6e5", "genesis_output_index": 0, "genesis_type": 0, "amount": 600, @@ -804,22 +828,22 @@ "prev_witnesses": [ { "prev_id": { - "out_point": "085f3d0999a0fad576c4a42136f771a2f33dc10da864463dbfabd4d91a1c3807:1", - "asset_id": "ea7d47abcbf3935868eb78ecfa55bcee3b1baa50554582770b85cf94184de99c", - "script_key": "025dc1551a12879e464751c5d58adc47170366eec5ea474d4f08069faf0ec4a846" + "out_point": "5be7e3c66c4090094e7dc10e2b4b38604539d8b2ae5c3a49f6d5bfcf0a8fee61:1", + "asset_id": "e304927a992c3a1d81f50586301c1f055f59923c236b93704097d02fdcd9eb78", + "script_key": "02aee2739664013a7de5c6c324f520af0dda900e53fdde79d97caae61f53b8634b" }, "tx_witness": [ - "30a59f8083dbf0f9a2cecb670fdaeede2c8f7162cdf016d9125fd5826ac5f13e64b587ba9c9224c71af999d495388ef16a9c8f00c28c8487ed84d30c676ca992" + "cc16977679b45a50b64c03b363b95ca3389590495ca742018735f531d5ce3fe6b88dfda0637e06e6eba86e1cdd9f2df4e4cb96ff7c36effd1b50a73334674bd6" ], "split_commitment": null } ], "split_commitment_root": { - "hash": "fcf3a9d2bf6a83827c22662bfa10d095aa5dbc8d0ec54f3bd6e2ee3ab23d211d", + "hash": "1c6319db0fc74f357d435e6efd4406c54d6473fa35face18d29b47ecdf63a8c2", "sum": "1200" }, "script_version": 0, - "script_key": "02ada2da3880c78b716154464311235543576a4a25519c6d7408f16562706a4d6c", + "script_key": "0294aab4886e65569873d588d86dbbb9a8785576b251261170a378a30b2af2d3d2", "group_key": null } } @@ -827,18 +851,18 @@ ], "split_commitment_root": null, "script_version": 0, - "script_key": "02b16a1dabf41be280943e505ee522d4c349250ef1b7c4a0cb197516659eb72709", + "script_key": "02995eefdf358055573f2f70106f09c208f86277e7ab7038edfe52a7e2003c06d9", "group_key": null }, "inclusion_proof": { "output_index": 1, - "internal_key": "0205bd63c9712513e6b573490780fcaecbc9c3fe29807cf6eb9b65067415c77f3d", + "internal_key": "03cdff2a9995874b27e2dc83ae878b7753c925d996339455982250d6c237adecba", "commitment_proof": { "proof": { "asset_proof": { "proof": "0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "version": 0, - "asset_id": "ea7d47abcbf3935868eb78ecfa55bcee3b1baa50554582770b85cf94184de99c" + "asset_id": "e304927a992c3a1d81f50586301c1f055f59923c236b93704097d02fdcd9eb78" }, "taproot_asset_proof": { "proof": "0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", @@ -852,13 +876,13 @@ "exclusion_proofs": [ { "output_index": 0, - "internal_key": "030e0b3b55c02f39e7c4c9ab09ffc94a3329c64fff6ebae8848936dce9526e30fc", + "internal_key": "0260037c3b9987798745c48397b4651f2ee73d433f27aa3bb33f96744a6607b9f5", "commitment_proof": { "proof": { "asset_proof": { - "proof": "000126d95df7e2348c05a2e1b0d7a48473f4dba9128a1b948ec8c885ed667f1e95eb0000000000000258ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbf", + "proof": "000111bf752ef14c9095b14932062e5be15755cecbcd8cd5f26473dbb0a6db1373630000000000000258ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f", "version": 0, - "asset_id": "ea7d47abcbf3935868eb78ecfa55bcee3b1baa50554582770b85cf94184de99c" + "asset_id": "e304927a992c3a1d81f50586301c1f055f59923c236b93704097d02fdcd9eb78" }, "taproot_asset_proof": { "proof": "0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", @@ -871,7 +895,7 @@ }, { "output_index": 2, - "internal_key": "02649b305eb6b54187ff5acccc35bce9e47feea1bf3adbfcdc1be38d4c55cf249a", + "internal_key": "02ff7b62b0ada51df1a354f19f71dd957868b062515f7c1ae5f6e63a4643f4170b", "commitment_proof": null, "tapscript_proof": { "tap_preimage_1": "", @@ -882,13 +906,13 @@ ], "split_root_proof": { "output_index": 0, - "internal_key": "030e0b3b55c02f39e7c4c9ab09ffc94a3329c64fff6ebae8848936dce9526e30fc", + "internal_key": "0260037c3b9987798745c48397b4651f2ee73d433f27aa3bb33f96744a6607b9f5", "commitment_proof": { "proof": { "asset_proof": { "proof": "0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "version": 0, - "asset_id": "ea7d47abcbf3935868eb78ecfa55bcee3b1baa50554582770b85cf94184de99c" + "asset_id": "e304927a992c3a1d81f50586301c1f055f59923c236b93704097d02fdcd9eb78" }, "taproot_asset_proof": { "proof": "0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", @@ -901,9 +925,11 @@ }, "meta_reveal": null, "additional_inputs": null, - "challenge_witness": null + "challenge_witness": null, + "genesis_reveal": null, + "group_key_reveal": null }, - "expected": "54415050000400000000012407381c1ad9d4abbf3d4664a80dc13df3a271f73621a4c476d5faa099093d5f08000000010250000040205c9c7f10746d49a143742948cacb2edc063481a6f1fa5492a9f0299346fce325629fa06a4bdb830586733e8351911235692d1fad7664894793de4d223017583a016a0865ffff7f200000000003fd018c0200000000010203f8ac0fa47f7eaf42dbf8ec9b135849dcd49b69ffe980b6ecf88293a0b143ba0000000000ffffffff07381c1ad9d4abbf3d4664a80dc13df3a271f73621a4c476d5faa099093d5f0801000000000000000003e803000000000000225120a914766a8a19bb8cc1fe8c17f411aae5fc6841fea6b807ce73d66ebdabf08d52e80300000000000022512087a21c8d7a5d3d0bea676166a83bfcf12ae3c92b7f14bc1fff7d54820eda441a25d0f50500000000225120fe19c6b74a18eccd85988ed33b3d3204e4ccc8f43c2a10b3958d0a9cf6d95f1a02473044022023174c06060685d720e6c711922a07245083222df195fb75524c89b14a30606d02203eea3947bb6bdc65dae743823ee358817a688b9d39271f149c770777933793b401210357ef09bf2d5c536341f759d7d2825e64a9f5954a750250e7cd1fe4d2cf92b3d501403b17cc53283398a529d534a70835d6fe22f45e30d48d9c87e2d3d83b9173670a5280636b53724dd7822692826274c7058a58016038e1a690c7e6366d69d9a6d900000000042201612328b275fe8b89ec246b5ea9f1ce906e512795cfbfb00132c14243dbbfaabd0005fd02b40001000159026aeb6852b9e126728173b095a689ef6d6b94bd3d9d61fec3b1047269bda94a000000000f66697273742d697465737462757878dedfcaf730cec72f6dbea97c64d4a4f3489edc3c2ff8413ad169e9717a3b058d00000000000201000303fd025806fd022301fd021f0065000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002fd01b44a000176db3c90a94d1d88883b15f2ea49cea0db1a6b99df666bdb2f4717cc259d3c310000000000000258ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7ffd01660001000159026aeb6852b9e126728173b095a689ef6d6b94bd3d9d61fec3b1047269bda94a000000000f66697273742d697465737462757878dedfcaf730cec72f6dbea97c64d4a4f3489edc3c2ff8413ad169e9717a3b058d00000000000201000303fd025806ad01ab006507381c1ad9d4abbf3d4664a80dc13df3a271f73621a4c476d5faa099093d5f0800000001ea7d47abcbf3935868eb78ecfa55bcee3b1baa50554582770b85cf94184de99c025dc1551a12879e464751c5d58adc47170366eec5ea474d4f08069faf0ec4a8460142014030a59f8083dbf0f9a2cecb670fdaeede2c8f7162cdf016d9125fd5826ac5f13e64b587ba9c9224c71af999d495388ef16a9c8f00c28c8487ed84d30c676ca9920728fcf3a9d2bf6a83827c22662bfa10d095aa5dbc8d0ec54f3bd6e2ee3ab23d211d00000000000004b008020000092102ada2da3880c78b716154464311235543576a4a25519c6d7408f16562706a4d6c08020000092102b16a1dabf41be280943e505ee522d4c349250ef1b7c4a0cb197516659eb72709069f00040000000101210205bd63c9712513e6b573490780fcaecbc9c3fe29807cf6eb9b65067415c77f3d027400490001000120ea7d47abcbf3935868eb78ecfa55bcee3b1baa50554582770b85cf94184de99c02220000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff012700010001220000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff07f802c70004000000000121030e0b3b55c02f39e7c4c9ab09ffc94a3329c64fff6ebae8848936dce9526e30fc029c00710001000120ea7d47abcbf3935868eb78ecfa55bcee3b1baa50554582770b85cf94184de99c024a000126d95df7e2348c05a2e1b0d7a48473f4dba9128a1b948ec8c885ed667f1e95eb0000000000000258ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbf012700010001220000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff2e000400000002012102649b305eb6b54187ff5acccc35bce9e47feea1bf3adbfcdc1be38d4c55cf249a0303020101089f0004000000000121030e0b3b55c02f39e7c4c9ab09ffc94a3329c64fff6ebae8848936dce9526e30fc027400490001000120ea7d47abcbf3935868eb78ecfa55bcee3b1baa50554582770b85cf94184de99c02220000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff012700010001220000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0c04000001bc", + "expected": "54415050000400000000012461ee8f0acfbfd5f6493a5caeb2d8394560384b2b0ec17d4e0990406cc6e3e75b0000000102500000402092a9256d4b85021548627deb2c43f36af17910072d708295b778f5ad3f5bb87dd83ea06c46664e4315f7de9ee8d3506c71d82b40200cfc2541e68b86c4146a67c21c1b65ffff7f200600000003fd018c0200000000010204478bc55a872d647f4b68a48f6d8d2240d18d03b9370a7f38743f4827cd99430000000000ffffffff61ee8f0acfbfd5f6493a5caeb2d8394560384b2b0ec17d4e0990406cc6e3e75b01000000000000000003e80300000000000022512028fb02ae7f93d46f673d798597985b2e26f3caeba668be40eb215e7e3b4583c7e80300000000000022512032b6eeb107b144586f1134b285d9f0dcb432233188851829e131aa4478264ef325d0f50500000000225120dec8af6483c79fa7ea39bea834b92024acfe5c1b6ccdd66889048c2ca0a206600247304402207820ce964c23db5429446ea89d666b45d1b3c4fae30aec6894d34214ad0ed089022044d895c3ba0b30babbe5f927795ab186e5384bb25596e2623caeb94029ee64af0121032cbea8ed49a89ee5c69276349fb9fa4a98613ced896cacc4019c02c97314e77001403aff7a5dc8b6501541c36ad1500c5dd84f59f0c3d732e0417fe7bc28371704a5981b0a8bdfd57c592efaad8e0913b29b43ff97a0822d7ee6b65d3d4fdb1d3f9f000000000422015aa0323cf2cc7f34962f63618b77c9bb44c26c7d69fb7b25c9774e36b914f1890005fd02b40001000159000edf94014e8e647be631dc8f23a1a2ac762babf95e2110a04cc6d11c9039ff000000000f66697273742d69746573746275787872055b46e57b82693def0aab2e58eb4b78068238f3d62b84d89050b92fc2a6e500000000000201000303fd025806fd022301fd021f0065000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002fd01b44a0001e829447f0dd17d26880ba56a672caa4de2859a5d732799f39077d1ee48595d7b0000000000000258ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdffd01660001000159000edf94014e8e647be631dc8f23a1a2ac762babf95e2110a04cc6d11c9039ff000000000f66697273742d69746573746275787872055b46e57b82693def0aab2e58eb4b78068238f3d62b84d89050b92fc2a6e500000000000201000303fd025806ad01ab006561ee8f0acfbfd5f6493a5caeb2d8394560384b2b0ec17d4e0990406cc6e3e75b00000001e304927a992c3a1d81f50586301c1f055f59923c236b93704097d02fdcd9eb7802aee2739664013a7de5c6c324f520af0dda900e53fdde79d97caae61f53b8634b01420140cc16977679b45a50b64c03b363b95ca3389590495ca742018735f531d5ce3fe6b88dfda0637e06e6eba86e1cdd9f2df4e4cb96ff7c36effd1b50a73334674bd607281c6319db0fc74f357d435e6efd4406c54d6473fa35face18d29b47ecdf63a8c200000000000004b00802000009210294aab4886e65569873d588d86dbbb9a8785576b251261170a378a30b2af2d3d208020000092102995eefdf358055573f2f70106f09c208f86277e7ab7038edfe52a7e2003c06d9069f000400000001012103cdff2a9995874b27e2dc83ae878b7753c925d996339455982250d6c237adecba027400490001000120e304927a992c3a1d81f50586301c1f055f59923c236b93704097d02fdcd9eb7802220000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff012700010001220000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff07f802c700040000000001210260037c3b9987798745c48397b4651f2ee73d433f27aa3bb33f96744a6607b9f5029c00710001000120e304927a992c3a1d81f50586301c1f055f59923c236b93704097d02fdcd9eb78024a000111bf752ef14c9095b14932062e5be15755cecbcd8cd5f26473dbb0a6db1373630000000000000258ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f012700010001220000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff2e000400000002012102ff7b62b0ada51df1a354f19f71dd957868b062515f7c1ae5f6e63a4643f4170b0303020101089f00040000000001210260037c3b9987798745c48397b4651f2ee73d433f27aa3bb33f96744a6607b9f5027400490001000120e304927a992c3a1d81f50586301c1f055f59923c236b93704097d02fdcd9eb7802220000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff012700010001220000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0c04000001bc", "comment": "valid regtest proof file index 2" } ], diff --git a/proof/verifier.go b/proof/verifier.go index 135ee614a..9c7f2cf9a 100644 --- a/proof/verifier.go +++ b/proof/verifier.go @@ -24,7 +24,8 @@ type Verifier interface { // error if the proof file is valid. A valid file should return an // AssetSnapshot of the final state transition of the file. Verify(c context.Context, blobReader io.Reader, - headerVerifier HeaderVerifier) (*AssetSnapshot, error) + headerVerifier HeaderVerifier, + groupVerifier GroupVerifier) (*AssetSnapshot, error) } // BaseVerifier implements a simple verifier that loads the entire proof file @@ -36,7 +37,8 @@ type BaseVerifier struct { // error if the proof file is valid. A valid file should return an // AssetSnapshot of the final state transition of the file. func (b *BaseVerifier) Verify(ctx context.Context, blobReader io.Reader, - headerVerifier HeaderVerifier) (*AssetSnapshot, error) { + headerVerifier HeaderVerifier, + groupVerifier GroupVerifier) (*AssetSnapshot, error) { var proofFile File err := proofFile.Decode(blobReader) @@ -44,7 +46,7 @@ func (b *BaseVerifier) Verify(ctx context.Context, blobReader io.Reader, return nil, fmt.Errorf("unable to parse proof: %w", err) } - return proofFile.Verify(ctx, headerVerifier) + return proofFile.Verify(ctx, headerVerifier, groupVerifier) } // verifyTaprootProof attempts to verify a TaprootProof for inclusion or @@ -163,7 +165,8 @@ func (p *Proof) verifyExclusionProofs() error { // state transition. This method returns the split asset information if this // state transition represents an asset split. func (p *Proof) verifyAssetStateTransition(ctx context.Context, - prev *AssetSnapshot, headerVerifier HeaderVerifier) (bool, error) { + prev *AssetSnapshot, headerVerifier HeaderVerifier, + groupVerifier GroupVerifier) (bool, error) { // Determine whether we have an asset split based on the resulting // asset's witness. If so, extract the root asset from the split asset. @@ -207,7 +210,9 @@ func (p *Proof) verifyAssetStateTransition(ctx context.Context, inputProof := inputProof errGroup.Go(func() error { - result, err := inputProof.Verify(ctx, headerVerifier) + result, err := inputProof.Verify( + ctx, headerVerifier, groupVerifier, + ) if err != nil { return err } @@ -320,6 +325,18 @@ func (p *Proof) verifyGenesisReveal() error { return nil } +// verifyGenesisGroupKey verifies that the group key attached to the asset in +// this proof has already been verified. +func (p *Proof) verfyGenesisGroupKey(groupVerifier GroupVerifier) error { + groupKey := p.Asset.GroupKey.GroupPubKey + err := groupVerifier(&groupKey) + if err != nil { + return ErrGroupKeyUnknown + } + + return nil +} + // verifyGroupKeyReveal verifies that the group key reveal can be used to derive // the same key as the group key specified for the asset. func (p *Proof) verifyGroupKeyReveal() error { @@ -333,21 +350,15 @@ func (p *Proof) verifyGroupKeyReveal() error { return ErrGroupKeyRevealRequired } - // TODO(jhb): Actually use this key and compare it. - _, err := reveal.GroupPubKey(p.Asset.ID()) + revealedKey, err := reveal.GroupPubKey(p.Asset.ID()) if err != nil { return err } - // TODO(jhb): Enforce this check once we update SignGenesis() to - // implement the same key tweaking as in GroupPubKey(), by passing - // the assetID as a single tweak to SignOutputRaw(). // Make sure the derived key matches what we expect. - /* - if !groupKey.GroupPubKey.IsEqual(revealedKey) { - return ErrGroupKeyRevealMismatch - } - */ + if !groupKey.GroupPubKey.IsEqual(revealedKey) { + return ErrGroupKeyRevealMismatch + } return nil } @@ -356,6 +367,17 @@ func (p *Proof) verifyGroupKeyReveal() error { // block header is invalid (usually: not present on chain). type HeaderVerifier func(blockHeader wire.BlockHeader, blockHeight uint32) error +// GroupVerifier is a callback function which returns an error if the given +// group key has not been imported by the tapd daemon. This can occur if the +// issuance proof for the group anchor has not been imported or synced. +type GroupVerifier func(groupKey *btcec.PublicKey) error + +// GroupAnchorVerifier is a callback function which returns an error if the +// given genesis is not the asset genesis of the group anchor. This callback +// should return an error for any reissuance into an existing group. +type GroupAnchorVerifier func(gen *asset.Genesis, + groupKey *asset.GroupKey) error + // Verify verifies the proof by ensuring that: // // 0. A proof has a valid version. @@ -368,7 +390,8 @@ type HeaderVerifier func(blockHeader wire.BlockHeader, blockHeight uint32) error // 5. A set of asset inputs with valid witnesses are included that satisfy the // resulting state transition. func (p *Proof) Verify(ctx context.Context, prev *AssetSnapshot, - headerVerifier HeaderVerifier) (*AssetSnapshot, error) { + headerVerifier HeaderVerifier, + groupVerifier GroupVerifier) (*AssetSnapshot, error) { // 0. Check only for the proof version. if p.IsUnknownVersion() { @@ -431,7 +454,8 @@ func (p *Proof) Verify(ctx context.Context, prev *AssetSnapshot, // 5. If this is a genesis asset, start by verifying the // genesis reveal, which should be present for genesis assets. // Non-genesis assets must not have a genesis or meta reveal. - isGenesisAsset := p.Asset.HasGenesisWitness() + isGenesisAsset := p.Asset.HasGenesisWitness() || + p.Asset.HasGenesisWitnessForGroup() hasGenesisReveal := p.GenesisReveal != nil hasMetaReveal := p.MetaReveal != nil @@ -448,28 +472,41 @@ func (p *Proof) Verify(ctx context.Context, prev *AssetSnapshot, } } - // 6. Verify group key reveal for genesis assets. Not all assets have a - // group key, and should therefore not have a group key reveal. If a - // group key is present, the group key reveal must also be present. + // 6. Verify group key and group key reveal for genesis assets. Not all + // assets have a group key, and should therefore not have a group key + // reveal. The group key reveal must be present for group anchors, and + // the group key must be present for any reissuance into an asset group. hasGroupKeyReveal := p.GroupKeyReveal != nil hasGroupKey := p.Asset.GroupKey != nil switch { case !isGenesisAsset && hasGroupKeyReveal: return nil, ErrNonGenesisAssetWithGroupKeyReveal - case isGenesisAsset && hasGroupKey && !hasGroupKeyReveal: - return nil, ErrGroupKeyRevealRequired - case isGenesisAsset && !hasGroupKey && hasGroupKeyReveal: return nil, ErrGroupKeyRequired + case isGenesisAsset && hasGroupKey && !hasGroupKeyReveal: + // A reissuance must be for an asset group that has already + // been imported and verified. + if err := p.verfyGenesisGroupKey(groupVerifier); err != nil { + return nil, err + } + case isGenesisAsset && hasGroupKey && hasGroupKeyReveal: if err := p.verifyGroupKeyReveal(); err != nil { return nil, err } } - // 7. Either a set of asset inputs with valid witnesses is included that + // 7. Verify group key for asset transfers. Any asset with a group key + // must carry a group key that has already been imported and verified. + if !isGenesisAsset && hasGroupKey { + if err := p.verfyGenesisGroupKey(groupVerifier); err != nil { + return nil, err + } + } + + // 8. Either a set of asset inputs with valid witnesses is included that // satisfy the resulting state transition or a challenge witness is // provided as part of an ownership proof. var splitAsset bool @@ -479,7 +516,7 @@ func (p *Proof) Verify(ctx context.Context, prev *AssetSnapshot, default: splitAsset, err = p.verifyAssetStateTransition( - ctx, prev, headerVerifier, + ctx, prev, headerVerifier, groupVerifier, ) } if err != nil { @@ -518,7 +555,9 @@ func (p *Proof) Verify(ctx context.Context, prev *AssetSnapshot, // verification loop. // // TODO(roasbeef): pass in the expected genesis point here? -func (f *File) Verify(ctx context.Context, headerVerifier HeaderVerifier) ( +func (f *File) Verify(ctx context.Context, headerVerifier HeaderVerifier, + groupVerifier GroupVerifier) ( + *AssetSnapshot, error) { select { @@ -546,7 +585,9 @@ func (f *File) Verify(ctx context.Context, headerVerifier HeaderVerifier) ( return nil, err } - result, err := decodedProof.Verify(ctx, prev, headerVerifier) + result, err := decodedProof.Verify( + ctx, prev, headerVerifier, groupVerifier, + ) if err != nil { return nil, err } diff --git a/rpcserver.go b/rpcserver.go index f18483635..0edbe6f3e 100644 --- a/rpcserver.go +++ b/rpcserver.go @@ -1084,7 +1084,8 @@ func (r *rpcServer) VerifyProof(ctx context.Context, } headerVerifier := tapgarden.GenHeaderVerifier(ctx, r.cfg.ChainBridge) - _, err = proofFile.Verify(ctx, headerVerifier) + groupVerifier := tapgarden.GenGroupVerifier(ctx, r.cfg.MintingStore) + _, err = proofFile.Verify(ctx, headerVerifier, groupVerifier) if err != nil { // We don't want to fail the RPC request because of a proof // verification error, but we do want to log it for easier @@ -1188,8 +1189,8 @@ func (r *rpcServer) marshalProof(ctx context.Context, p *proof.Proof, var ( rpcMeta *taprpc.AssetMeta - rpcGenesis = decodedProof.GenesisReveal - rpcGroupKey = decodedProof.GroupKeyReveal + rpcGenesis = p.GenesisReveal + rpcGroupKey = p.GroupKeyReveal anchorOutpoint = wire.OutPoint{ Hash: p.AnchorTx.TxHash(), Index: p.InclusionProof.OutputIndex, @@ -1288,24 +1289,26 @@ func (r *rpcServer) marshalProof(ctx context.Context, p *proof.Proof, } } - decodedAssetID := decodedProof.Asset.ID() - genesisReveal := &taprpc.GenesisReveal{ - GenesisBaseReveal: &taprpc.GenesisInfo{ - GenesisPoint: rpcGenesis.FirstPrevOut.String(), - Name: rpcGenesis.Tag, - MetaHash: rpcGenesis.MetaHash[:], - AssetId: decodedAssetID[:], - OutputIndex: rpcGenesis.OutputIndex, - }, - AssetType: taprpc.AssetType(decodedProof.Asset.Type), + decodedAssetID := p.Asset.ID() + var genesisReveal *taprpc.GenesisReveal + if rpcGenesis != nil { + genesisReveal = &taprpc.GenesisReveal{ + GenesisBaseReveal: &taprpc.GenesisInfo{ + GenesisPoint: rpcGenesis.FirstPrevOut.String(), + Name: rpcGenesis.Tag, + MetaHash: rpcGenesis.MetaHash[:], + AssetId: decodedAssetID[:], + OutputIndex: rpcGenesis.OutputIndex, + }, + AssetType: taprpc.AssetType(p.Asset.Type), + } } var GroupKeyReveal taprpc.GroupKeyReveal if rpcGroupKey != nil { - GroupKeyReveal.RawGroupKey = rpcGroupKey.RawKey[:] - if rpcGroupKey.TapscriptRoot != nil { - tapscriptRoot := rpcGroupKey.TapscriptRoot[:] - GroupKeyReveal.TapscriptRoot = tapscriptRoot + GroupKeyReveal = taprpc.GroupKeyReveal{ + RawGroupKey: rpcGroupKey.RawKey[:], + TapscriptRoot: rpcGroupKey.TapscriptRoot, } } @@ -1371,11 +1374,12 @@ func (r *rpcServer) ImportProof(ctx context.Context, } headerVerifier := tapgarden.GenHeaderVerifier(ctx, r.cfg.ChainBridge) + groupVerifier := tapgarden.GenGroupVerifier(ctx, r.cfg.MintingStore) // Now that we know the proof file is at least present, we'll attempt // to import it into the main archive. err := r.cfg.ProofArchive.ImportProofs( - ctx, headerVerifier, false, + ctx, headerVerifier, groupVerifier, false, &proof.AnnotatedProof{Blob: req.ProofFile}, ) if err != nil { @@ -1419,10 +1423,6 @@ func (r *rpcServer) AddrReceives(ctx context.Context, addr.AttachGenesis(*assetGroup.Genesis) - if assetGroup.GroupKey != nil { - addr.AttachGroupWitness(assetGroup.GroupKey.Witness) - } - taprootOutputKey, err := addr.TaprootOutputKey() if err != nil { return nil, fmt.Errorf("error deriving Taproot key: %w", @@ -1724,10 +1724,6 @@ func marshalAddr(addr *address.Tap, if err == nil { addr.AttachGenesis(*assetGroup.Genesis) - if assetGroup.GroupKey != nil { - addr.AttachGroupWitness(assetGroup.GroupKey.Witness) - } - outputKey, err := addr.TaprootOutputKey() if err != nil { return nil, fmt.Errorf("error deriving Taproot "+ @@ -3271,7 +3267,10 @@ func (r *rpcServer) ProveAssetOwnership(ctx context.Context, } headerVerifier := tapgarden.GenHeaderVerifier(ctx, r.cfg.ChainBridge) - lastSnapshot, err := proofFile.Verify(ctx, headerVerifier) + groupVerifier := tapgarden.GenGroupVerifier(ctx, r.cfg.MintingStore) + lastSnapshot, err := proofFile.Verify( + ctx, headerVerifier, groupVerifier, + ) if err != nil { return nil, fmt.Errorf("cannot verify proof: %w", err) } @@ -3326,7 +3325,8 @@ func (r *rpcServer) VerifyAssetOwnership(ctx context.Context, } headerVerifier := tapgarden.GenHeaderVerifier(ctx, r.cfg.ChainBridge) - _, err = p.Verify(ctx, nil, headerVerifier) + groupVerifier := tapgarden.GenGroupVerifier(ctx, r.cfg.MintingStore) + _, err = p.Verify(ctx, nil, headerVerifier, groupVerifier) if err != nil { return nil, fmt.Errorf("error verifying proof: %w", err) } diff --git a/tapcfg/server.go b/tapcfg/server.go index d85c72b90..df644bf43 100644 --- a/tapcfg/server.go +++ b/tapcfg/server.go @@ -17,6 +17,7 @@ import ( "github.com/lightninglabs/taproot-assets/tapdb/sqlc" "github.com/lightninglabs/taproot-assets/tapfreighter" "github.com/lightninglabs/taproot-assets/tapgarden" + "github.com/lightninglabs/taproot-assets/tapscript" "github.com/lightninglabs/taproot-assets/universe" "github.com/lightningnetwork/lnd" "github.com/lightningnetwork/lnd/clock" @@ -127,6 +128,9 @@ func genServerConfig(cfg *Config, cfgLogger btclog.Logger, headerVerifier := tapgarden.GenHeaderVerifier( context.Background(), chainBridge, ) + groupVerifier := tapgarden.GenGroupVerifier( + context.Background(), assetMintingStore, + ) uniCfg := universe.MintingArchiveConfig{ NewBaseTree: func(id universe.Identifier) universe.BaseBackend { return tapdb.NewBaseUniverseTree( @@ -134,6 +138,7 @@ func genServerConfig(cfg *Config, cfgLogger btclog.Logger, ) }, HeaderVerifier: headerVerifier, + GroupVerifier: groupVerifier, Multiverse: multiverse, UniverseStats: universeStats, } @@ -193,7 +198,10 @@ func genServerConfig(cfg *Config, cfgLogger btclog.Logger, } reOrgWatcher := tapgarden.NewReOrgWatcher(&tapgarden.ReOrgWatcherConfig{ - ChainBridge: chainBridge, + ChainBridge: chainBridge, + GroupVerifier: tapgarden.GenGroupVerifier( + context.Background(), assetMintingStore, + ), ProofArchive: proofArchive, NonBuriedAssetFetcher: func(ctx context.Context, minHeight int32) ([]*asset.Asset, error) { @@ -277,13 +285,13 @@ func genServerConfig(cfg *Config, cfgLogger btclog.Logger, ReOrgWatcher: reOrgWatcher, AssetMinter: tapgarden.NewChainPlanter(tapgarden.PlanterConfig{ GardenKit: tapgarden.GardenKit{ - Wallet: walletAnchor, - ChainBridge: chainBridge, - Log: assetMintingStore, - KeyRing: keyRing, - GenSigner: tap.NewLndRpcGenSigner( - lndServices, - ), + Wallet: walletAnchor, + ChainBridge: chainBridge, + Log: assetMintingStore, + KeyRing: keyRing, + GenSigner: virtualTxSigner, + GenTxBuilder: &tapscript.GroupTxBuilder{}, + TxValidator: &tap.ValidatorV0{}, ProofFiles: proofFileStore, Universe: universeFederation, ProofWatcher: reOrgWatcher, @@ -295,9 +303,12 @@ func genServerConfig(cfg *Config, cfgLogger btclog.Logger, }), AssetCustodian: tapgarden.NewCustodian( &tapgarden.CustodianConfig{ - ChainParams: &tapChainParams, - WalletAnchor: walletAnchor, - ChainBridge: chainBridge, + ChainParams: &tapChainParams, + WalletAnchor: walletAnchor, + ChainBridge: chainBridge, + GroupVerifier: tapgarden.GenGroupVerifier( + context.Background(), assetMintingStore, + ), AddrBook: addrBook, ProofArchive: proofArchive, ProofNotifier: assetStore, @@ -314,10 +325,13 @@ func genServerConfig(cfg *Config, cfgLogger btclog.Logger, CoinSelect: coinSelect, ChainPorter: tapfreighter.NewChainPorter( &tapfreighter.ChainPorterConfig{ - Signer: virtualTxSigner, - TxValidator: &tap.ValidatorV0{}, - ExportLog: assetStore, - ChainBridge: chainBridge, + Signer: virtualTxSigner, + TxValidator: &tap.ValidatorV0{}, + ExportLog: assetStore, + ChainBridge: chainBridge, + GroupVerifier: tapgarden.GenGroupVerifier( + context.Background(), assetMintingStore, + ), Wallet: walletAnchor, KeyRing: keyRing, AssetWallet: assetWallet, diff --git a/tapdb/addrs.go b/tapdb/addrs.go index 3288c0455..da4cfdce8 100644 --- a/tapdb/addrs.go +++ b/tapdb/addrs.go @@ -211,10 +211,11 @@ func (t *TapAddressBook) InsertAddrs(ctx context.Context, // For each of the addresses listed, we'll insert the two new // internal keys, then use those returned primary key IDs to // returned to insert the address itself. - for _, addr := range addrs { + for idx := range addrs { // The asset genesis should already be known at this // point, so we'll just fetch it so we can obtain the // genAssetID. + addr := addrs[idx] assetGen, err := db.FetchGenesisByAssetID( ctx, addr.AssetID[:], ) @@ -953,8 +954,8 @@ func (t *TapAddressBook) QueryAssetGroup(ctx context.Context, assetGroup.GroupKey, err = parseGroupKeyInfo( groupInfo.TweakedGroupKey, groupInfo.RawKey, - groupInfo.WitnessStack, groupInfo.KeyFamily, - groupInfo.KeyIndex, + groupInfo.WitnessStack, groupInfo.TapscriptRoot, + groupInfo.KeyFamily, groupInfo.KeyIndex, ) return err diff --git a/tapdb/asset_minting.go b/tapdb/asset_minting.go index 191fd05db..6c28c7a40 100644 --- a/tapdb/asset_minting.go +++ b/tapdb/asset_minting.go @@ -939,6 +939,22 @@ func (a *AssetMintingStore) AddSproutsToBatch(ctx context.Context, // assets committed to within the root commitment specified. assets := assetRoot.CommittedAssets() + // Before we store any assets from the batch, we need to sort the assets + // so that we insert group anchors before reissunces. This is required + // to store the asset genesis as the group anchor. All future group + // anchor verification depends on inserting group anchors before + // reissuances here. We use the raw group anchor verifier since there + // is not yet any stored asset group to reference in the verifier. + anchorVerifier := tapgarden.GenRawGroupAnchorVerifier(ctx) + anchorAssets, nonAnchorAssets, err := tapgarden.SortAssets( + assets, anchorVerifier, + ) + if err != nil { + return fmt.Errorf("unable to sort assets: %w", err) + } + + sortedAssets := append(anchorAssets, nonAnchorAssets...) + genesisOutpoint := genesisPacket.Pkt.UnsignedTx.TxIn[0].PreviousOutPoint rawBatchKey := batchKey.SerializeCompressed() @@ -946,7 +962,7 @@ func (a *AssetMintingStore) AddSproutsToBatch(ctx context.Context, var writeTxOpts AssetStoreTxOptions return a.db.ExecTx(ctx, &writeTxOpts, func(q PendingAssetStore) error { genesisPointID, _, err := upsertAssetsWithGenesis( - ctx, q, genesisOutpoint, assets, nil, + ctx, q, genesisOutpoint, sortedAssets, nil, ) if err != nil { return fmt.Errorf("error inserting assets with "+ diff --git a/tapdb/asset_minting_test.go b/tapdb/asset_minting_test.go index dad74dd8e..7c771bade 100644 --- a/tapdb/asset_minting_test.go +++ b/tapdb/asset_minting_test.go @@ -20,6 +20,7 @@ import ( "github.com/lightninglabs/taproot-assets/proof" "github.com/lightninglabs/taproot-assets/tapdb/sqlc" "github.com/lightninglabs/taproot-assets/tapgarden" + "github.com/lightninglabs/taproot-assets/tapscript" "github.com/lightningnetwork/lnd/build" "github.com/lightningnetwork/lnd/clock" "github.com/lightningnetwork/lnd/keychain" @@ -97,17 +98,21 @@ func storeGroupGenesis(t *testing.T, ctx context.Context, initGen asset.Genesis, *asset.AssetGroup) { // Generate the signature for our group genesis asset. - genSigner := asset.NewRawKeyGenesisSigner(groupPriv) - groupKey, err := asset.DeriveGroupKey( - genSigner, privDesc, initGen, currentGen, - ) - require.NoError(t, err) + genSigner := asset.NewMockGenesisSigner(groupPriv) + genTxBuilder := asset.MockGroupTxBuilder{} // Select the correct genesis for the new asset. assetGen := initGen if currentGen != nil { assetGen = *currentGen } + genProtoAsset := asset.RandAssetWithValues( + t, assetGen, nil, asset.RandScriptKey(t), + ) + groupKey, err := asset.DeriveGroupKey( + genSigner, &genTxBuilder, privDesc, initGen, genProtoAsset, + ) + require.NoError(t, err) initialAsset := asset.RandAssetWithValues( t, assetGen, groupKey, asset.RandScriptKey(t), @@ -346,15 +351,26 @@ func seedlingsToAssetRoot(t *testing.T, genesisPoint wire.OutPoint, } scriptKey, _ := randKeyDesc(t) + tweakedScriptKey := asset.NewScriptKeyBip86(scriptKey) var ( - groupPriv *btcec.PrivateKey - groupKey *asset.GroupKey - groupInfo *asset.AssetGroup - ok bool - err error + genTxBuilder = tapscript.GroupTxBuilder{} + groupPriv *btcec.PrivateKey + groupKey *asset.GroupKey + groupInfo *asset.AssetGroup + protoAsset *asset.Asset + amount uint64 + ok bool + err error ) + switch seedling.AssetType { + case asset.Normal: + amount = seedling.Amount + case asset.Collectible: + amount = 1 + } + if seedling.HasGroupKey() { groupPriv, ok = groupKeys[seedling.AssetName] require.True(t, ok) @@ -368,19 +384,27 @@ func seedlingsToAssetRoot(t *testing.T, genesisPoint wire.OutPoint, require.True(t, ok) } + if groupInfo != nil || seedling.EnableEmission { + protoAsset, err = asset.New( + assetGen, amount, 0, 0, tweakedScriptKey, nil, + ) + require.NoError(t, err) + } + if groupInfo != nil { groupKey, err = asset.DeriveGroupKey( - asset.NewRawKeyGenesisSigner(groupPriv), - groupInfo.GroupKey.RawKey, - *groupInfo.Genesis, &assetGen, + asset.NewMockGenesisSigner(groupPriv), + &genTxBuilder, groupInfo.GroupKey.RawKey, + *groupInfo.Genesis, protoAsset, ) } if seedling.EnableEmission { groupKeyRaw, newGroupPriv := randKeyDesc(t) + genSigner := asset.NewMockGenesisSigner(newGroupPriv) groupKey, err = asset.DeriveGroupKey( - asset.NewRawKeyGenesisSigner(newGroupPriv), - groupKeyRaw, assetGen, nil, + genSigner, &genTxBuilder, groupKeyRaw, assetGen, + protoAsset, ) newGroupPrivs[seedling.AssetName] = newGroupPriv newGroupInfo[seedling.AssetName] = &asset.AssetGroup{ @@ -391,17 +415,8 @@ func seedlingsToAssetRoot(t *testing.T, genesisPoint wire.OutPoint, require.NoError(t, err) - var amount uint64 - switch seedling.AssetType { - case asset.Normal: - amount = seedling.Amount - case asset.Collectible: - amount = 1 - } - newAsset, err := asset.New( - assetGen, amount, 0, 0, - asset.NewScriptKeyBip86(scriptKey), groupKey, + assetGen, amount, 0, 0, tweakedScriptKey, groupKey, ) require.NoError(t, err) @@ -697,10 +712,22 @@ func TestCommitBatchChainActions(t *testing.T) { require.NoError(t, err) require.Equal(t, numSeedlings, len(assets)) + // Count the number of assets with a group key. Each grouped asset + // should have a grouped genesis witness. + groupCount := fn.Count(assets, func(a *ChainAsset) bool { + return a.GroupKey != nil + }) + groupWitnessCount := fn.Count(assets, func(a *ChainAsset) bool { + return a.HasGenesisWitnessForGroup() + }) + require.Equal(t, groupCount, groupWitnessCount) + // All the assets returned should have the genesis prev ID set up. - for _, dbAsset := range assets { - require.True(t, dbAsset.HasGenesisWitness()) - } + ungroupedCount := len(assets) - groupCount + genesisWitnessCount := fn.Count(assets, func(a *ChainAsset) bool { + return a.HasGenesisWitness() + }) + require.Equal(t, ungroupedCount, genesisWitnessCount) // Now that the batch has been committed on disk, we should be able to // obtain all the proofs we just committed. diff --git a/tapdb/assets_common.go b/tapdb/assets_common.go index a7434d91c..37b3a7809 100644 --- a/tapdb/assets_common.go +++ b/tapdb/assets_common.go @@ -3,6 +3,7 @@ package tapdb import ( "bytes" "context" + "crypto/sha256" "database/sql" "errors" "fmt" @@ -260,9 +261,16 @@ func upsertGroupKey(ctx context.Context, groupKey *asset.GroupKey, err) } + // The only valid size for a non-empty Tapscript root is 32 bytes. + if len(groupKey.TapscriptRoot) != 0 && + len(groupKey.TapscriptRoot) != sha256.Size { + + return nullID, fmt.Errorf("tapscript root invalid: wrong size") + } + groupID, err := q.UpsertAssetGroupKey(ctx, AssetGroupKey{ TweakedGroupKey: tweakedKeyBytes, - TapscriptRoot: groupKey.TapscriptRoot[:], + TapscriptRoot: groupKey.TapscriptRoot, InternalKeyID: keyID, GenesisPointID: genesisPointID, }) @@ -436,7 +444,8 @@ func fetchGroupByGenesis(ctx context.Context, q GroupStore, groupKey, err := parseGroupKeyInfo( groupInfo.TweakedGroupKey, groupInfo.RawKey, - groupInfo.WitnessStack, groupInfo.KeyFamily, groupInfo.KeyIndex, + groupInfo.WitnessStack, groupInfo.TapscriptRoot, + groupInfo.KeyFamily, groupInfo.KeyIndex, ) if err != nil { return nil, err @@ -470,7 +479,7 @@ func fetchGroupByGroupKey(ctx context.Context, q GroupStore, groupKey, err := parseGroupKeyInfo( groupKeyQuery, groupInfo.RawKey, groupInfo.WitnessStack, - groupInfo.KeyFamily, groupInfo.KeyIndex, + groupInfo.TapscriptRoot, groupInfo.KeyFamily, groupInfo.KeyIndex, ) if err != nil { return nil, err @@ -483,7 +492,7 @@ func fetchGroupByGroupKey(ctx context.Context, q GroupStore, } // parseGroupKeyInfo maps information on a group key into a GroupKey. -func parseGroupKeyInfo(tweakedKey, rawKey, witness []byte, +func parseGroupKeyInfo(tweakedKey, rawKey, witness, tapscriptRoot []byte, keyFamily, keyIndex int32) (*asset.GroupKey, error) { tweakedGroupKey, err := btcec.ParsePubKey(tweakedKey) @@ -513,9 +522,10 @@ func parseGroupKeyInfo(tweakedKey, rawKey, witness []byte, } return &asset.GroupKey{ - RawKey: groupRawKey, - GroupPubKey: *tweakedGroupKey, - Witness: groupWitness, + RawKey: groupRawKey, + GroupPubKey: *tweakedGroupKey, + TapscriptRoot: tapscriptRoot, + Witness: groupWitness, }, nil } diff --git a/tapdb/assets_store.go b/tapdb/assets_store.go index 511d4e4ff..669000d45 100644 --- a/tapdb/assets_store.go +++ b/tapdb/assets_store.go @@ -1295,7 +1295,8 @@ func (a *AssetStore) insertAssetWitnesses(ctx context.Context, db ActiveAssetsStore, assetID int32, inputs []asset.Witness) error { var buf [8]byte - for _, input := range inputs { + for idx := range inputs { + input := inputs[idx] prevID := input.PrevID prevOutpoint, err := encodeOutpoint(prevID.OutPoint) @@ -1504,8 +1505,8 @@ func (a *AssetStore) upsertAssetProof(ctx context.Context, // // NOTE: This implements the proof.ArchiveBackend interface. func (a *AssetStore) ImportProofs(ctx context.Context, - headerVerifier proof.HeaderVerifier, replace bool, - proofs ...*proof.AnnotatedProof) error { + headerVerifier proof.HeaderVerifier, groupVerifier proof.GroupVerifier, + replace bool, proofs ...*proof.AnnotatedProof) error { var writeTxOpts AssetStoreTxOptions err := a.db.ExecTx(ctx, &writeTxOpts, func(q ActiveAssetsStore) error { @@ -2285,9 +2286,10 @@ func logPendingPassiveAssets(ctx context.Context, q ActiveAssetsStore, transferID, newUtxoID int32, passiveAssets []*tapfreighter.PassiveAssetReAnchor) error { - for _, passiveAsset := range passiveAssets { + for idx := range passiveAssets { // Encode new witness data. var ( + passiveAsset = passiveAssets[idx] newWitnessBuf bytes.Buffer buf [8]byte ) diff --git a/tapdb/assets_store_test.go b/tapdb/assets_store_test.go index ad03d3a8b..18fad42eb 100644 --- a/tapdb/assets_store_test.go +++ b/tapdb/assets_store_test.go @@ -20,6 +20,8 @@ import ( "github.com/lightninglabs/taproot-assets/mssmt" "github.com/lightninglabs/taproot-assets/proof" "github.com/lightninglabs/taproot-assets/tapfreighter" + "github.com/lightninglabs/taproot-assets/tapscript" + "github.com/lightningnetwork/lnd/input" "github.com/lightningnetwork/lnd/keychain" "github.com/stretchr/testify/require" ) @@ -116,25 +118,32 @@ func randAsset(t *testing.T, genOpts ...assetGenOpt) *asset.Asset { groupPriv := *opts.groupKeyPriv - genSigner := asset.NewRawKeyGenesisSigner(&groupPriv) + genSigner := asset.NewMockGenesisSigner(&groupPriv) + genTxBuilder := tapscript.GroupTxBuilder{} var ( groupKeyDesc = keychain.KeyDescriptor{ PubKey: groupPriv.PubKey(), } - assetGroupKey *asset.GroupKey - err error - initialGen = genesis - currentGen *asset.Genesis + assetGroupKey *asset.GroupKey + err error + initialGen = genesis + protoAsset *asset.Asset + lockTime = uint64(test.RandInt[int32]()) + relativeLockTime = uint64(test.RandInt[int32]()) + ) + + protoAsset = asset.NewAssetNoErr( + t, genesis, opts.amt, lockTime, relativeLockTime, + opts.scriptKey, nil, ) if opts.groupAnchorGen != nil { initialGen = *opts.groupAnchorGen - currentGen = &genesis } assetGroupKey, err = asset.DeriveGroupKey( - genSigner, groupKeyDesc, initialGen, currentGen, + genSigner, &genTxBuilder, groupKeyDesc, initialGen, protoAsset, ) require.NoError(t, err) @@ -142,8 +151,8 @@ func randAsset(t *testing.T, genOpts ...assetGenOpt) *asset.Asset { newAsset := &asset.Asset{ Genesis: genesis, Amount: opts.amt, - LockTime: uint64(test.RandInt[int32]()), - RelativeLockTime: uint64(test.RandInt[int32]()), + LockTime: lockTime, + RelativeLockTime: relativeLockTime, ScriptKey: opts.scriptKey, } @@ -322,7 +331,8 @@ func TestImportAssetProof(t *testing.T) { // With all our test data constructed, we'll now attempt to import the // asset into the database. require.NoError(t, assetStore.ImportProofs( - ctxb, proof.MockHeaderVerifier, false, testProof, + ctxb, proof.MockHeaderVerifier, proof.MockGroupVerifier, false, + testProof, )) // We should now be able to retrieve the set of all assets inserted on @@ -375,7 +385,8 @@ func TestImportAssetProof(t *testing.T) { testProof.AnchorTxIndex = 5678 testProof.Blob = updatedBlob require.NoError(t, assetStore.ImportProofs( - ctxb, proof.MockHeaderVerifier, true, testProof, + ctxb, proof.MockHeaderVerifier, proof.MockGroupVerifier, true, + testProof, )) currentBlob, err = assetStore.FetchProof(ctxb, proof.Locator{ @@ -614,12 +625,12 @@ func (a *assetGenerator) bindAssetID(i int, op wire.OutPoint) *asset.ID { func (a *assetGenerator) bindKeyGroup(i int, op wire.OutPoint) *btcec.PublicKey { gen := a.assetGens[i] gen.FirstPrevOut = op + genTweak := gen.ID() groupPriv := *a.groupKeys[i] - tweakedPriv := txscript.TweakTaprootPrivKey( - groupPriv, gen.GroupKeyTweak(), - ) + internalPriv := input.TweakPrivKey(&groupPriv, genTweak[:]) + tweakedPriv := txscript.TweakTaprootPrivKey(*internalPriv, nil) return tweakedPriv.PubKey() } diff --git a/tapdb/universe.go b/tapdb/universe.go index 6b94ded56..d3d1ed96e 100644 --- a/tapdb/universe.go +++ b/tapdb/universe.go @@ -15,6 +15,7 @@ import ( "github.com/lightninglabs/taproot-assets/proof" "github.com/lightninglabs/taproot-assets/tapdb/sqlc" "github.com/lightninglabs/taproot-assets/universe" + "github.com/lightningnetwork/lnd/keychain" ) type ( @@ -233,8 +234,31 @@ func upsertAssetGen(ctx context.Context, db UpsertAssetStore, // Finally, if there's a group key associated with the asset, then // we'll insert that now as well. if groupKey != nil { - _, err := upsertGroupKey( - ctx, groupKey, db, genPointID, genAssetID, + // Every group-related issuance must be accompanied by a group + // witness. + groupWitness := genesisProof.Asset.PrevWitnesses[0].TxWitness + fullGroupKey := &asset.GroupKey{ + GroupPubKey: groupKey.GroupPubKey, + Witness: groupWitness, + } + + // If a group key reveal is present, then this asset is a group + // anchor and we must insert extra information about the group + // key. + if genesisProof.GroupKeyReveal != nil { + reveal := genesisProof.GroupKeyReveal + rawKey, err := reveal.RawKey.ToPubKey() + if err != nil { + return 0, err + } + + fullGroupKey.RawKey = keychain.KeyDescriptor{ + PubKey: rawKey, + } + fullGroupKey.TapscriptRoot = reveal.TapscriptRoot + } + _, err = upsertGroupKey( + ctx, fullGroupKey, db, genPointID, genAssetID, ) if err != nil { return 0, err diff --git a/tapdb/universe_test.go b/tapdb/universe_test.go index cbe92ad91..c01b46839 100644 --- a/tapdb/universe_test.go +++ b/tapdb/universe_test.go @@ -116,10 +116,22 @@ func randMintingLeaf(t *testing.T, assetGen asset.Genesis, Proof: randProof(t), Amt: uint64(rand.Int31()), } + + // The asset within the genesis proof is random; reset the asset genesis + // and group key to match the universe minting leaf. + leaf.Proof.Asset.Genesis = assetGen + leaf.Proof.GenesisReveal = &assetGen + if groupKey != nil { - leaf.GroupKey = &asset.GroupKey{ + assetGroupKey := &asset.GroupKey{ GroupPubKey: *groupKey, - Witness: wire.TxWitness{test.RandBytes(64)}, + Witness: leaf.Proof.Asset.GroupKey.Witness, + } + + leaf.GroupKey = assetGroupKey + leaf.Proof.Asset.GroupKey = assetGroupKey + leaf.Proof.GroupKeyReveal = &asset.GroupKeyReveal{ + RawKey: asset.ToSerialized(groupKey), } } @@ -449,6 +461,7 @@ func TestUniverseLeafQuery(t *testing.T) { baseUniverse, _ := newTestUniverse(t, id) const numLeafs = 3 + var sharedWitness wire.TxWitness // We'll create three new leaves, all of them will share the exact same // minting outpoint, but will have distinct script keys. @@ -460,6 +473,20 @@ func TestUniverseLeafQuery(t *testing.T) { targetKey.OutPoint = rootMintingPoint leaf := randMintingLeaf(t, assetGen, id.GroupKey) + if id.GroupKey != nil { + // All assets are sharing the same genesis and group + // key, so they must also share the same group witness. + switch { + case sharedWitness == nil: + sharedWitness = + leaf.GroupKey.Witness + default: + leaf.GroupKey.Witness = + sharedWitness + leaf.Proof.Asset.GroupKey.Witness = + sharedWitness + } + } scriptKey := asset.ToSerialized(targetKey.ScriptKey.PubKey) diff --git a/tapfreighter/chain_porter.go b/tapfreighter/chain_porter.go index 5d47e9c7d..8583bff30 100644 --- a/tapfreighter/chain_porter.go +++ b/tapfreighter/chain_porter.go @@ -38,6 +38,10 @@ type ChainPorterConfig struct { // ChainBridge is our bridge to the chain we operate on. ChainBridge ChainBridge + // GroupVerifier is used to verify the validity of the group key for a + // genesis proof. + GroupVerifier proof.GroupVerifier + // Wallet is used to fund+sign PSBTs for the transfer transaction. Wallet WalletAnchor @@ -345,7 +349,8 @@ func (p *ChainPorter) storeProofs(sendPkg *sendPackage) error { log.Infof("Importing %d passive asset proofs into local Proof "+ "Archive", len(passiveAssetProofFiles)) err := p.cfg.AssetProofs.ImportProofs( - ctx, headerVerifier, false, passiveAssetProofFiles..., + ctx, headerVerifier, p.cfg.GroupVerifier, false, + passiveAssetProofFiles..., ) if err != nil { return fmt.Errorf("error importing passive proof: %w", err) @@ -464,7 +469,8 @@ func (p *ChainPorter) storeProofs(sendPkg *sendPackage) error { log.Infof("Importing proof for output %d into local Proof "+ "Archive", idx) err = p.cfg.AssetProofs.ImportProofs( - ctx, headerVerifier, false, outputProof, + ctx, headerVerifier, p.cfg.GroupVerifier, false, + outputProof, ) if err != nil { return fmt.Errorf("error importing proof: %w", err) @@ -684,7 +690,8 @@ func (p *ChainPorter) transferReceiverProof(pkg *sendPackage) error { // Load passive asset proof files from archive. passiveAssetProofFiles := map[[32]byte]proof.Blob{} - for _, passiveAsset := range pkg.OutboundPkg.PassiveAssets { + for idx := range pkg.OutboundPkg.PassiveAssets { + passiveAsset := pkg.OutboundPkg.PassiveAssets[idx] proofLocator := proof.Locator{ AssetID: &passiveAsset.GenesisID, ScriptKey: *passiveAsset.ScriptKey.PubKey, @@ -770,7 +777,7 @@ func (p *ChainPorter) importLocalAddresses(ctx context.Context, case strings.Contains(err.Error(), "already exists"): break - case err != nil: + default: return err } } diff --git a/tapfreighter/wallet.go b/tapfreighter/wallet.go index 3bf63695b..fdcebf215 100644 --- a/tapfreighter/wallet.go +++ b/tapfreighter/wallet.go @@ -739,7 +739,7 @@ func (f *AssetWallet) fundPacketWithInputs(ctx context.Context, // it in the database. continue - case err != nil: + default: return nil, fmt.Errorf("cannot fetch script key: %w", err) } @@ -867,7 +867,7 @@ func (f *AssetWallet) setVPacketInputs(ctx context.Context, vPkt.Inputs = make([]*tappsbt.VInput, len(eligibleCommitments)) inputCommitments := make(tappsbt.InputCommitments) - for idx, assetInput := range eligibleCommitments { + for idx := range eligibleCommitments { // If the key found for the input UTXO cannot be identified as // belonging to the lnd wallet, we won't be able to sign for it. // This would happen if a user manually imported an asset that @@ -875,6 +875,7 @@ func (f *AssetWallet) setVPacketInputs(ctx context.Context, // not create asset entries for such imported assets in the // first place, as we won't be able to spend it anyway. But for // now we just put this check in place. + assetInput := eligibleCommitments[idx] internalKey := assetInput.InternalKey if !f.cfg.KeyRing.IsLocalKey(ctx, internalKey) { return nil, fmt.Errorf("invalid internal key family "+ diff --git a/tapgarden/caretaker.go b/tapgarden/caretaker.go index d20358227..51e162963 100644 --- a/tapgarden/caretaker.go +++ b/tapgarden/caretaker.go @@ -2,11 +2,13 @@ package tapgarden import ( "context" + "errors" "fmt" "strings" "sync" "time" + "github.com/btcsuite/btcd/btcec/v2" "github.com/btcsuite/btcd/btcutil" "github.com/btcsuite/btcd/btcutil/psbt" "github.com/btcsuite/btcd/chaincfg/chainhash" @@ -34,6 +36,15 @@ var ( PkScript: GenesisDummyScript[:], Value: int64(GenesisAmtSats), } + + // ErrGroupKeyUnknown is an error returned if an asset has a group key + // attached that has not been previously verified. + ErrGroupKeyUnknown = errors.New("group key not known") + + // ErrGenesisNotGroupAnchor is an error returned if an asset has a group + // key attached, and the asset is not the anchor asset for the group. + // This is true for any asset created via reissuance. + ErrGenesisNotGroupAnchor = errors.New("genesis not group anchor") ) const ( @@ -441,12 +452,23 @@ func (b *BatchCaretaker) seedlingsToAssetSprouts(ctx context.Context, return nil, fmt.Errorf("unable to obtain script "+ "key: %w", err) } + tweakedScriptKey := asset.NewScriptKeyBip86(scriptKey) var ( + amount uint64 groupInfo *asset.AssetGroup + protoAsset *asset.Asset sproutGroupKey *asset.GroupKey ) + // Determine the amount for the actual asset. + switch seedling.AssetType { + case asset.Normal: + amount = seedling.Amount + case asset.Collectible: + amount = 1 + } + // If the seedling has a group key specified, // that group key was validated earlier. We need to // sign the new genesis with that group key. @@ -462,14 +484,27 @@ func (b *BatchCaretaker) seedlingsToAssetSprouts(ctx context.Context, groupInfo = newGroups[*seedling.GroupAnchor] } + // If a group witness needs to be produced, then we will need a + // partially filled asset as part of the signing process. + if groupInfo != nil || seedling.EnableEmission { + protoAsset, err = asset.New( + assetGen, amount, 0, 0, tweakedScriptKey, nil, + ) + if err != nil { + return nil, fmt.Errorf("unable to create "+ + "asset for group key signing: %w", err) + } + } + if groupInfo != nil { sproutGroupKey, err = asset.DeriveGroupKey( - b.cfg.GenSigner, groupInfo.GroupKey.RawKey, - *groupInfo.Genesis, &assetGen, + b.cfg.GenSigner, b.cfg.GenTxBuilder, + groupInfo.GroupKey.RawKey, + *groupInfo.Genesis, protoAsset, ) if err != nil { - return nil, fmt.Errorf("unable to"+ - "tweak group key: %w", err) + return nil, fmt.Errorf("unable to tweak group "+ + "key: %w", err) } } @@ -482,16 +517,17 @@ func (b *BatchCaretaker) seedlingsToAssetSprouts(ctx context.Context, ctx, asset.TaprootAssetsKeyFamily, ) if err != nil { - return nil, fmt.Errorf("unable to"+ - "derive group key: %w", err) + return nil, fmt.Errorf("unable to derive "+ + "group key: %w", err) } + sproutGroupKey, err = asset.DeriveGroupKey( - b.cfg.GenSigner, rawGroupKey, - assetGen, nil, + b.cfg.GenSigner, b.cfg.GenTxBuilder, + rawGroupKey, assetGen, protoAsset, ) if err != nil { - return nil, fmt.Errorf("unable to"+ - "tweak group key: %w", err) + return nil, fmt.Errorf("unable to tweak group "+ + "key: %w", err) } newGroups[seedlingName] = &asset.AssetGroup{ @@ -502,23 +538,24 @@ func (b *BatchCaretaker) seedlingsToAssetSprouts(ctx context.Context, // With the necessary keys components assembled, we'll create // the actual asset now. - var amount uint64 - switch seedling.AssetType { - case asset.Normal: - amount = seedling.Amount - case asset.Collectible: - amount = 1 - } - newAsset, err := asset.New( - assetGen, amount, 0, 0, - asset.NewScriptKeyBip86(scriptKey), sproutGroupKey, + assetGen, amount, 0, 0, tweakedScriptKey, + sproutGroupKey, ) if err != nil { return nil, fmt.Errorf("unable to create new asset: %w", err) } + // Verify the group witness if present. + if sproutGroupKey != nil { + err := b.cfg.TxValidator.Execute(newAsset, nil, nil) + if err != nil { + return nil, fmt.Errorf("unable to verify "+ + "asset group witness: %w", err) + } + } + newAssets = append(newAssets, newAsset) } @@ -834,6 +871,8 @@ func (b *BatchCaretaker) stateStep(currentState BatchState) (BatchState, error) defer cancel() headerVerifier := GenHeaderVerifier(ctx, b.cfg.ChainBridge) + groupVerifier := GenGroupVerifier(ctx, b.cfg.Log) + groupAnchorVerifier := GenGroupAnchorVerifier(ctx, b.cfg.Log) // Now that the minting transaction has been confirmed, we'll // need to create the series of proof file blobs for each of @@ -867,7 +906,8 @@ func (b *BatchCaretaker) stateStep(currentState BatchState) (BatchState, error) } mintingProofs, err := proof.NewMintingBlobs( - baseProof, headerVerifier, + baseProof, headerVerifier, groupVerifier, + groupAnchorVerifier, proof.WithAssetMetaReveals(b.cfg.Batch.AssetMetas), ) if err != nil { @@ -903,38 +943,56 @@ func (b *BatchCaretaker) stateStep(currentState BatchState) (BatchState, error) }) } + // Before we write any assets from the batch, we need to sort + // the assets so that we insert group anchors before + // reissunces. This is required for any possible reissuances + // to be verified correctly when updating our local Universe. + anchorAssets, nonAnchorAssets, err := SortAssets( + committedAssets, groupAnchorVerifier, + ) + if err != nil { + return 0, fmt.Errorf("could not sort assets: %w", err) + } + // Before we confirm the batch, we'll also update the on disk // file system as well. // // TODO(roasbeef): rely on the upsert here instead - err = fn.ParSlice( - ctx, committedAssets, - func(ctx context.Context, newAsset *asset.Asset) error { - scriptPubKey := newAsset.ScriptKey.PubKey - scriptKey := asset.ToSerialized(scriptPubKey) + updateAssetProofs := func(ctx context.Context, + newAsset *asset.Asset) error { - mintingProof := mintingProofs[scriptKey] + scriptPubKey := newAsset.ScriptKey.PubKey + scriptKey := asset.ToSerialized(scriptPubKey) - proofBlob, uniProof, err := b.storeMintingProof( - ctx, newAsset, mintingProof, mintTxHash, - headerVerifier, - ) - if err != nil { - return fmt.Errorf("unable to store "+ - "proof: %w", err) - } + mintingProof := mintingProofs[scriptKey] + + proofBlob, uniProof, err := b.storeMintingProof( + ctx, newAsset, mintingProof, mintTxHash, + headerVerifier, groupVerifier, + ) + if err != nil { + return fmt.Errorf("unable to store "+ + "proof: %w", err) + } - proofMutex.Lock() - mintingProofBlobs[scriptKey] = proofBlob - proofMutex.Unlock() + proofMutex.Lock() + mintingProofBlobs[scriptKey] = proofBlob + proofMutex.Unlock() - if uniProof != nil { - universeItems <- uniProof - } + if uniProof != nil { + universeItems <- uniProof + } - return nil - }, - ) + return nil + } + + err = fn.ParSlice(ctx, anchorAssets, updateAssetProofs) + if err != nil { + return 0, fmt.Errorf("unable to update asset proofs: "+ + "%w", err) + } + + err = fn.ParSlice(ctx, nonAnchorAssets, updateAssetProofs) if err != nil { return 0, fmt.Errorf("unable to update asset proofs: "+ "%w", err) @@ -999,8 +1057,9 @@ func (b *BatchCaretaker) stateStep(currentState BatchState) (BatchState, error) // can be used to register the asset with the universe. func (b *BatchCaretaker) storeMintingProof(ctx context.Context, a *asset.Asset, mintingProof *proof.Proof, mintTxHash chainhash.Hash, - headerVerifier proof.HeaderVerifier) (proof.Blob, - *universe.IssuanceItem, error) { + headerVerifier proof.HeaderVerifier, + groupVerifier proof.GroupVerifier) (proof.Blob, *universe.IssuanceItem, + error) { assetID := a.ID() blob, err := proof.EncodeAsProofFile(mintingProof) @@ -1009,14 +1068,16 @@ func (b *BatchCaretaker) storeMintingProof(ctx context.Context, err) } - err = b.cfg.ProofFiles.ImportProofs( - ctx, headerVerifier, false, &proof.AnnotatedProof{ - Locator: proof.Locator{ - AssetID: &assetID, - ScriptKey: *a.ScriptKey.PubKey, - }, - Blob: blob, + fullProof := &proof.AnnotatedProof{ + Locator: proof.Locator{ + AssetID: &assetID, + ScriptKey: *a.ScriptKey.PubKey, }, + Blob: blob, + } + + err = b.cfg.ProofFiles.ImportProofs( + ctx, headerVerifier, groupVerifier, false, fullProof, ) if err != nil { return nil, nil, fmt.Errorf("unable to insert proofs: %w", err) @@ -1137,6 +1198,45 @@ func SortSeedlings(seedlings []*Seedling) []string { return allSeedlings } +// SortAssets sorts the batch assets such that assets that are group anchors are +// partitioned from all other assets. +func SortAssets(fullAssets []*asset.Asset, + anchorVerifier proof.GroupAnchorVerifier) ([]*asset.Asset, + []*asset.Asset, error) { + + var anchorAssets, nonAnchorAssets []*asset.Asset + for ind := range fullAssets { + fullAsset := fullAssets[ind] + + switch { + case fullAsset.GroupKey != nil: + err := anchorVerifier( + &fullAsset.Genesis, + fullAsset.GroupKey, + ) + + switch { + case err == nil: + anchorAssets = append(anchorAssets, fullAsset) + + case errors.Is(err, ErrGenesisNotGroupAnchor) || + errors.Is(err, ErrGroupKeyUnknown): + + nonAnchorAssets = append( + nonAnchorAssets, fullAsset, + ) + + default: + return nil, nil, err + } + default: + nonAnchorAssets = append(nonAnchorAssets, fullAsset) + } + } + + return anchorAssets, nonAnchorAssets, nil +} + // GetTxFee returns the value of the on-chain fees paid by a finalized PSBT. func GetTxFee(pkt *psbt.Packet) (int64, error) { inputValue, err := psbt.SumUtxoInputValues(pkt) @@ -1162,3 +1262,134 @@ func GenHeaderVerifier(ctx context.Context, return err } } + +// GenGroupVeifier generates a group key verification callback function given +// a DB handle. +func GenGroupVerifier(ctx context.Context, + mintingStore MintingStore) func(*btcec.PublicKey) error { + + // Cache known group keys that were previously fetched. + assetGroups := fn.NewSet[asset.SerializedKey]() + + // verifierLock is a mutex that must be held when using the group + // anchor verifier. + var verifierLock sync.Mutex + + return func(groupKey *btcec.PublicKey) error { + if groupKey == nil { + return fmt.Errorf("cannot verify empty group key") + } + + verifierLock.Lock() + defer verifierLock.Unlock() + + assetGroupKey := asset.ToSerialized(groupKey) + ok := assetGroups.Contains(assetGroupKey) + if ok { + return nil + } + + // This query will err if no stored group has a matching + // tweaked group key. + _, err := mintingStore.FetchGroupByGroupKey( + ctx, groupKey, + ) + if err != nil { + return fmt.Errorf("%x: %w", assetGroupKey, + ErrGroupKeyUnknown) + } + + assetGroups.Add(assetGroupKey) + + return nil + } +} + +// GenGroupAnchorVerifier generates a caching group anchor verification callback +// function given a DB handle. +func GenGroupAnchorVerifier(ctx context.Context, + mintingStore MintingStore) func(*asset.Genesis, + *asset.GroupKey) error { + + // Cache anchors for groups that were previously fetched. + groupAnchors := make(map[asset.SerializedKey]*asset.Genesis) + + // verifierLock is a mutex that must be held when using the group + // anchor verifier. + var verifierLock sync.Mutex + + return func(gen *asset.Genesis, groupKey *asset.GroupKey) error { + verifierLock.Lock() + defer verifierLock.Unlock() + + assetGroupKey := asset.ToSerialized(&groupKey.GroupPubKey) + groupAnchor, ok := groupAnchors[assetGroupKey] + + if !ok { + storedGroup, err := mintingStore.FetchGroupByGroupKey( + ctx, &groupKey.GroupPubKey, + ) + if err != nil { + return ErrGroupKeyUnknown + } + + groupAnchors[assetGroupKey] = storedGroup.Genesis + groupAnchor = storedGroup.Genesis + } + + if gen.ID() != groupAnchor.ID() { + return ErrGenesisNotGroupAnchor + } + + return nil + } +} + +// GenRawGroupAnchorVerifier generates a group anchor verification callback +// function. This anchor verifier recomputes the tweaked group key with the +// passed genesis and compares that key to the given group key. This verifier +// is only used in the caretaker, before any asset groups are stored in the DB. +func GenRawGroupAnchorVerifier(ctx context.Context) func(*asset.Genesis, + *asset.GroupKey) error { + + // Cache group anchors we already verified. + groupAnchors := make(map[asset.SerializedKey]*asset.Genesis) + + // verifierLock is a mutex that must be held when using the group + // anchor verifier. + var verifierLock sync.Mutex + + return func(gen *asset.Genesis, groupKey *asset.GroupKey) error { + verifierLock.Lock() + defer verifierLock.Unlock() + + assetGroupKey := asset.ToSerialized(&groupKey.GroupPubKey) + groupAnchor, ok := groupAnchors[assetGroupKey] + + if !ok { + // TODO(jhb): add tapscript root support + singleTweak := gen.ID() + tweakedGroupKey, err := asset.GroupPubKey( + groupKey.RawKey.PubKey, singleTweak[:], nil, + ) + if err != nil { + return err + } + + computedGroupKey := asset.ToSerialized(tweakedGroupKey) + if computedGroupKey != assetGroupKey { + return ErrGenesisNotGroupAnchor + } + + groupAnchors[assetGroupKey] = gen + + return nil + } + + if gen.ID() != groupAnchor.ID() { + return ErrGenesisNotGroupAnchor + } + + return nil + } +} diff --git a/tapgarden/custodian.go b/tapgarden/custodian.go index e528b6d66..179cd4ed0 100644 --- a/tapgarden/custodian.go +++ b/tapgarden/custodian.go @@ -36,6 +36,10 @@ type CustodianConfig struct { // backend. ChainBridge ChainBridge + // GroupVerifier is used to verify the validity of the group key for an + // asset. + GroupVerifier proof.GroupVerifier + // AddrBook is the storage backend for addresses. AddrBook *address.Book @@ -421,7 +425,8 @@ func (c *Custodian) inspectWalletTx(walletTx *lndclient.Transaction) error { ctx, c.cfg.ChainBridge, ) err = c.cfg.ProofArchive.ImportProofs( - ctx, headerVerifier, false, addrProof, + ctx, headerVerifier, c.cfg.GroupVerifier, false, + addrProof, ) if err != nil { log.Errorf("unable to import proofs: %v", err) diff --git a/tapgarden/custodian_test.go b/tapgarden/custodian_test.go index ff6359123..d03a4245f 100644 --- a/tapgarden/custodian_test.go +++ b/tapgarden/custodian_test.go @@ -333,10 +333,17 @@ func TestAddrMatchesAsset(t *testing.T) { t.Parallel() randKey1, randKey2 := test.RandPubKey(t), test.RandPubKey(t) + randScriptKey1, randScriptKey2 := test.RandPubKey(t), test.RandPubKey(t) randGen1 := asset.RandGenesis(t, asset.Normal) randGen2 := asset.RandGenesis(t, asset.Normal) - randGroup1 := asset.RandGroupKey(t, randGen1) - randGroup2 := asset.RandGroupKey(t, randGen2) + protoAsset1 := asset.RandAssetWithValues( + t, randGen1, nil, asset.NewScriptKey(randScriptKey1), + ) + protoAsset2 := asset.RandAssetWithValues( + t, randGen2, nil, asset.NewScriptKey(randScriptKey2), + ) + randGroup1 := asset.RandGroupKey(t, randGen1, protoAsset1) + randGroup2 := asset.RandGroupKey(t, randGen2, protoAsset2) var blankKey btcec.PublicKey diff --git a/tapgarden/mock.go b/tapgarden/mock.go index 3b457979c..9c77b76c6 100644 --- a/tapgarden/mock.go +++ b/tapgarden/mock.go @@ -362,6 +362,12 @@ func (m *MockChainBridge) EstimateFee(ctx context.Context, return 253, nil } +func GenMockGroupVerifier() func(*btcec.PublicKey) error { + return func(groupKey *btcec.PublicKey) error { + return nil + } +} + type MockKeyRing struct { FamIndex keychain.KeyFamily KeyIndex uint32 @@ -452,15 +458,19 @@ func NewMockGenSigner(keyRing *MockKeyRing) *MockGenSigner { } } -func (m *MockGenSigner) SignGenesis(desc keychain.KeyDescriptor, - initialGen asset.Genesis, currentGen *asset.Genesis) (*btcec.PublicKey, - *schnorr.Signature, error) { +func (m *MockGenSigner) SignVirtualTx(signDesc *lndclient.SignDescriptor, + virtualTx *wire.MsgTx, prevOut *wire.TxOut) (*schnorr.Signature, + error) { - priv := m.KeyRing.Keys[desc.KeyLocator] - signer := asset.NewRawKeyGenesisSigner(priv) - return signer.SignGenesis(desc, initialGen, currentGen) + priv := m.KeyRing.Keys[signDesc.KeyDesc.KeyLocator] + signer := asset.NewMockGenesisSigner(priv) + return signer.SignVirtualTx(signDesc, virtualTx, prevOut) } +// A compile-time assertion to ensure MockGenSigner meets the GenesisSigner +// interface. +var _ asset.GenesisSigner = (*MockGenSigner)(nil) + type MockProofArchive struct { } @@ -477,8 +487,8 @@ func (m *MockProofArchive) FetchProofs(ctx context.Context, } func (m *MockProofArchive) ImportProofs(ctx context.Context, - headerVerifier proof.HeaderVerifier, replace bool, - proofs ...*proof.AnnotatedProof) error { + headerVerifier proof.HeaderVerifier, groupVerifier proof.GroupVerifier, + replace bool, proofs ...*proof.AnnotatedProof) error { return nil } diff --git a/tapgarden/planter.go b/tapgarden/planter.go index 5978925c4..f512e8479 100644 --- a/tapgarden/planter.go +++ b/tapgarden/planter.go @@ -12,6 +12,7 @@ import ( "github.com/lightninglabs/taproot-assets/asset" "github.com/lightninglabs/taproot-assets/fn" "github.com/lightninglabs/taproot-assets/proof" + "github.com/lightninglabs/taproot-assets/tapscript" "github.com/lightninglabs/taproot-assets/universe" "github.com/lightningnetwork/lnd/ticker" "golang.org/x/exp/maps" @@ -41,6 +42,14 @@ type GardenKit struct { // emission. GenSigner asset.GenesisSigner + // GenTxBuilder is used to create virtual transactions for the group + // witness generation process. + GenTxBuilder asset.GenesisTxBuilder + + // TxValidator is used to validate group witnesses when creating assets + // that support reissuance. + TxValidator tapscript.TxValidator + // ProofFiles stores the set of flat proof files. ProofFiles proof.Archiver @@ -853,11 +862,13 @@ func (c *ChainPlanter) updateMintingProofs(proofs []*proof.Proof) error { defer cancel() headerVerifier := GenHeaderVerifier(ctx, c.cfg.ChainBridge) + groupVerifier := GenGroupVerifier(ctx, c.cfg.Log) for idx := range proofs { p := proofs[idx] err := proof.ReplaceProofInBlob( ctx, p, c.cfg.ProofUpdates, headerVerifier, + groupVerifier, ) if err != nil { return fmt.Errorf("unable to update minted proofs: %w", diff --git a/tapgarden/planter_test.go b/tapgarden/planter_test.go index a755e929d..101d0e03c 100644 --- a/tapgarden/planter_test.go +++ b/tapgarden/planter_test.go @@ -18,6 +18,7 @@ import ( "github.com/btcsuite/btcd/txscript" "github.com/btcsuite/btcd/wire" "github.com/davecgh/go-spew/spew" + tap "github.com/lightninglabs/taproot-assets" "github.com/lightninglabs/taproot-assets/asset" "github.com/lightninglabs/taproot-assets/fn" "github.com/lightninglabs/taproot-assets/internal/test" @@ -25,6 +26,7 @@ import ( "github.com/lightninglabs/taproot-assets/tapdb" _ "github.com/lightninglabs/taproot-assets/tapdb" // Register relevant drivers. "github.com/lightninglabs/taproot-assets/tapgarden" + "github.com/lightninglabs/taproot-assets/tapscript" "github.com/lightningnetwork/lnd/build" "github.com/lightningnetwork/lnd/keychain" "github.com/lightningnetwork/lnd/lntest/wait" @@ -66,6 +68,10 @@ type mintingTestHarness struct { genSigner *tapgarden.MockGenSigner + genTxBuilder asset.GenesisTxBuilder + + txValidator tapscript.TxValidator + ticker *ticker.Force planter *tapgarden.ChainPlanter @@ -99,6 +105,8 @@ func newMintingTestHarness(t *testing.T, store tapgarden.MintingStore, proofWatcher: &tapgarden.MockProofWatcher{}, keyRing: keyRing, genSigner: genSigner, + genTxBuilder: &tapscript.GroupTxBuilder{}, + txValidator: &tap.ValidatorV0{}, errChan: make(chan error, 10), } } @@ -118,6 +126,8 @@ func (t *mintingTestHarness) refreshChainPlanter() { Log: t.store, KeyRing: t.keyRing, GenSigner: t.genSigner, + GenTxBuilder: t.genTxBuilder, + TxValidator: t.txValidator, ProofFiles: t.proofFiles, ProofWatcher: t.proofWatcher, }, diff --git a/tapgarden/re-org_watcher.go b/tapgarden/re-org_watcher.go index 44840ac1d..4b650d60c 100644 --- a/tapgarden/re-org_watcher.go +++ b/tapgarden/re-org_watcher.go @@ -62,6 +62,10 @@ type ReOrgWatcherConfig struct { // backend. ChainBridge ChainBridge + // GroupVerifier is used to verify the validity of the group key for an + // asset. + GroupVerifier proof.GroupVerifier + // ProofArchive is the storage backend for proofs to which we store // updated proofs. ProofArchive proof.NotifyArchiver @@ -566,7 +570,7 @@ func (w *ReOrgWatcher) DefaultUpdateCallback() proof.UpdateCallback { for idx := range proofs { err := proof.ReplaceProofInBlob( ctxt, proofs[idx], w.cfg.ProofArchive, - headerVerifier, + headerVerifier, w.cfg.GroupVerifier, ) if err != nil { return fmt.Errorf("unable to update proofs: %w", diff --git a/tapgarden/re-org_watcher_test.go b/tapgarden/re-org_watcher_test.go index f58f8124d..d4329e777 100644 --- a/tapgarden/re-org_watcher_test.go +++ b/tapgarden/re-org_watcher_test.go @@ -50,7 +50,8 @@ func (h *reOrgWatcherHarness) eventually(fn func() bool) { func newReOrgWatcherHarness(t *testing.T) *reOrgWatcherHarness { chainBridge := NewMockChainBridge() cfg := &ReOrgWatcherConfig{ - ChainBridge: chainBridge, + ChainBridge: chainBridge, + GroupVerifier: GenMockGroupVerifier(), NonBuriedAssetFetcher: func(ctx context.Context, minHeight int32) ([]*asset.Asset, error) { diff --git a/tappsbt/testdata/psbt_encoding_generated.json b/tappsbt/testdata/psbt_encoding_generated.json index 3643857d5..e11e44d07 100644 --- a/tappsbt/testdata/psbt_encoding_generated.json +++ b/tappsbt/testdata/psbt_encoding_generated.json @@ -10,7 +10,7 @@ "tr_merkle_root": "", "prev_id": { "out_point": "0000000000000000000000000000000000000000000000000000000000000000:0", - "asset_id": "6abedfb7cc21821085134aec85f1ec2335aae36608efb88578042e2d29a137f2", + "asset_id": "93aa785d48c3e0a0c7f82c83c2f15785351c93d6e5dd91e251eb79790067f46b", "script_key": "000000000000000000000000000000000000000000000000000000000000000000" }, "anchor": { @@ -46,11 +46,11 @@ "tr_merkle_root": "" }, { - "amount": 5263531936693774911, + "amount": 2703501726821866378, "type": 0, "interactive": false, "anchor_output_index": 1, - "anchor_output_internal_key": "034a821d5ec008712983929de448b8afb6c24e5a1b97367b9a65b6220d7f083fe3", + "anchor_output_internal_key": "03126685da09d16135881ca9762295a5a8399b0bd66eaa5863a0d7512eeec162fe", "anchor_output_bip32_derivation": null, "anchor_output_tr_bip32_derivation": null, "anchor_output_tapscript_sibling": "", @@ -73,7 +73,7 @@ "anchor_output_tapscript_sibling": "", "asset": null, "split_asset": null, - "pk_script": "51209bfdf06c3322b3f3fde43d9c13db6b5c5882f69fbba6a958c1312f48e1c71b11", + "pk_script": "5120a6acba87a2486f33967892ca3eb23c9f10a04ba744f5b5f20048aa1111bf601d", "bip32_derivation": null, "tr_bip32_derivation": null, "tr_internal_key": "", @@ -83,7 +83,7 @@ "version": 0, "chain_params_hrp": "tapbc" }, - "expected": "cHNidP8BALQCAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAAAAAAAIlEgfHm5sm5GOJXu9WedhViULIbErSIzre8BvD5tVAs2U/4/ao62aNILSSJRIEWKkswS0BuOiJLaWO1RHTmPLOQrTWKVzwxmNGJJ9NMGAAAAAAAAAAAiUSCb/fBsMyKz8/3kPZwT22tcWIL2n7umqVjBMS9I4ccbEQAAAAABcAEBAXEFdGFwYmMBcgEAAAFwZQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGq+37fMIYIQhRNK7IXx7CM1quNmCO+4hXgELi0poTfyAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAXEIAAAAAAAAAAABcgABcwgAAAAAAAAAAAF1AAF4AAF6AAABcAEBAXEBAAFyCAAAAAAAAAAAAAFwAQABcQEAAXIIAAAAAAAAAAEBcyEDSoIdXsAIcSmDkp3kSLivtsJOWhuXNnuaZbYiDX8IP+MAAXABAAFxAQABcggAAAAAAAAAAAA=", + "expected": "cHNidP8BALQCAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAAAAAAAIlEgfHm5sm5GOJXu9WedhViULIbErSIzre8BvD5tVAs2U/6KW98sf8SEJSJRIEWKkswS0BuOiJLaWO1RHTmPLOQrTWKVzwxmNGJJ9NMGAAAAAAAAAAAiUSCmrLqHokhvM5Z4kso+sjyfEKBLp0T1tfIASKoREb9gHQAAAAABcAEBAXEFdGFwYmMBcgEAAAFwZQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJOqeF1Iw+Cgx/gsg8LxV4U1HJPW5d2R4lHreXkAZ/RrAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAXEIAAAAAAAAAAABcgABcwgAAAAAAAAAAAF1AAF4AAF6AAABcAEBAXEBAAFyCAAAAAAAAAAAAAFwAQABcQEAAXIIAAAAAAAAAAEBcyEDEmaF2gnRYTWIHKl2IpWlqDmbC9ZuqlhjoNdRLu7BYv4AAXABAAFxAQABcggAAAAAAAAAAAA=", "comment": "minimal packet" }, { @@ -121,7 +121,7 @@ "tr_merkle_root": "6d65726b6c6520726f6f74", "prev_id": { "out_point": "42c29291018d7c2d968d3f71f8cb984b92f67403049442fd5ad145f422b02936:4104515131", - "asset_id": "9d17346865fcf92b0c3a17c9028be9914eb7649c6c9347800979d1830356f2a5", + "asset_id": "8953bb6865fcf92b0c3a17c9028be9914eb7649c6c9347800979d1830356f2a5", "script_key": "035f01644ac40614b96363ba9baf1a7381a7bac742d267909edac6eebfc3eba5e7" }, "anchor": { @@ -166,7 +166,7 @@ "genesis_meta_hash": "24e2cafccae3a61fb586b14323a6bc8f9e7df1d929333ff993933bea6f5b3af6", "genesis_output_index": 1864800808, "genesis_type": 0, - "amount": 6735196588112087611, + "amount": 2227583514184312747, "lock_time": 0, "relative_lock_time": 0, "prev_witnesses": [ @@ -176,7 +176,9 @@ "asset_id": "0000000000000000000000000000000000000000000000000000000000000000", "script_key": "000000000000000000000000000000000000000000000000000000000000000000" }, - "tx_witness": null, + "tx_witness": [ + "96f01899d3d7a6539e84c8dfbf943ad9f106c9ed6ac7362859f5752249c9359d84206a87a2425528dd47c7ef23e66fe9276a6e2b315074dc0db3486fe7abfe19" + ], "split_commitment": null } ], @@ -184,7 +186,7 @@ "script_version": 0, "script_key": "022b6089025115cd1c390a01476da56cc20d9dbf4f571bc883623fb027aa2c7a98", "group_key": { - "group_key": "0275c517d5ed149ebee5735da50d8cc59ac6378436e000138561abd6c437d02d13" + "group_key": "03e3385517ed68b91dcd46c3da509146274eae9c9942db4eed1d40573d6e7a2289" } }, "proof": "7468697320697320612070726f6f66" @@ -251,11 +253,11 @@ "asset": { "version": 0, "genesis_first_prev_out": "f665a6a780ea967cd7101f46e83699caf3a08e4b738b68290b0d22050143a661:2783629501", - "genesis_tag": "993ebdf888b04883e56a156a8de563afa467d49dec6a40e9a1d007f033c28230", - "genesis_meta_hash": "993ebdf888b04883e56a156a8de563afa467d49dec6a40e9a1d007f033c28230", + "genesis_tag": "d8be9c3978b04883e56a156a8de563afa467d49dec6a40e9a1d007f033c28230", + "genesis_meta_hash": "d8be9c3978b04883e56a156a8de563afa467d49dec6a40e9a1d007f033c28230", "genesis_output_index": 637353343, "genesis_type": 0, - "amount": 8267293389953062912, + "amount": 5089134323978233019, "lock_time": 0, "relative_lock_time": 0, "prev_witnesses": [ @@ -265,7 +267,9 @@ "asset_id": "0000000000000000000000000000000000000000000000000000000000000000", "script_key": "000000000000000000000000000000000000000000000000000000000000000000" }, - "tx_witness": null, + "tx_witness": [ + "27539684a388647db9cf13776b3ab1d0c42eb16eb6d93dd574c472ee39d3a94f6ffc808a1a0a7ab6187524cbaf9bb7e93d487de1dae33c72fe31c278ff8908ac" + ], "split_commitment": null } ], @@ -273,17 +277,17 @@ "script_version": 0, "script_key": "02b2d0d9435b2a97e09da73665048bfadcebfbe17b6fa572d955bc11e5d665f689", "group_key": { - "group_key": "023a8b6353a798347b45a15b2c2348799aaa3a3290f1bd91896b310b01acf3b572" + "group_key": "02ad67d4a159934dc1ed02a49f9ad05ad69a90dc3f73c83341ba76e0a2472badf9" } }, "split_asset": { "version": 0, "genesis_first_prev_out": "f665a6a780ea967cd7101f46e83699caf3a08e4b738b68290b0d22050143a661:2783629501", - "genesis_tag": "993ebdf888b04883e56a156a8de563afa467d49dec6a40e9a1d007f033c28230", - "genesis_meta_hash": "993ebdf888b04883e56a156a8de563afa467d49dec6a40e9a1d007f033c28230", + "genesis_tag": "d8be9c3978b04883e56a156a8de563afa467d49dec6a40e9a1d007f033c28230", + "genesis_meta_hash": "d8be9c3978b04883e56a156a8de563afa467d49dec6a40e9a1d007f033c28230", "genesis_output_index": 637353343, "genesis_type": 0, - "amount": 8267293389953062912, + "amount": 5089134323978233019, "lock_time": 0, "relative_lock_time": 0, "prev_witnesses": [ @@ -293,7 +297,9 @@ "asset_id": "0000000000000000000000000000000000000000000000000000000000000000", "script_key": "000000000000000000000000000000000000000000000000000000000000000000" }, - "tx_witness": null, + "tx_witness": [ + "27539684a388647db9cf13776b3ab1d0c42eb16eb6d93dd574c472ee39d3a94f6ffc808a1a0a7ab6187524cbaf9bb7e93d487de1dae33c72fe31c278ff8908ac" + ], "split_commitment": null } ], @@ -301,7 +307,7 @@ "script_version": 0, "script_key": "02b2d0d9435b2a97e09da73665048bfadcebfbe17b6fa572d955bc11e5d665f689", "group_key": { - "group_key": "023a8b6353a798347b45a15b2c2348799aaa3a3290f1bd91896b310b01acf3b572" + "group_key": "02ad67d4a159934dc1ed02a49f9ad05ad69a90dc3f73c83341ba76e0a2472badf9" } }, "pk_script": "5120b2d0d9435b2a97e09da73665048bfadcebfbe17b6fa572d955bc11e5d665f689", @@ -347,11 +353,11 @@ "asset": { "version": 0, "genesis_first_prev_out": "f665a6a780ea967cd7101f46e83699caf3a08e4b738b68290b0d22050143a661:2783629501", - "genesis_tag": "993ebdf888b04883e56a156a8de563afa467d49dec6a40e9a1d007f033c28230", - "genesis_meta_hash": "993ebdf888b04883e56a156a8de563afa467d49dec6a40e9a1d007f033c28230", + "genesis_tag": "d8be9c3978b04883e56a156a8de563afa467d49dec6a40e9a1d007f033c28230", + "genesis_meta_hash": "d8be9c3978b04883e56a156a8de563afa467d49dec6a40e9a1d007f033c28230", "genesis_output_index": 637353343, "genesis_type": 0, - "amount": 8267293389953062912, + "amount": 5089134323978233019, "lock_time": 0, "relative_lock_time": 0, "prev_witnesses": [ @@ -361,7 +367,9 @@ "asset_id": "0000000000000000000000000000000000000000000000000000000000000000", "script_key": "000000000000000000000000000000000000000000000000000000000000000000" }, - "tx_witness": null, + "tx_witness": [ + "27539684a388647db9cf13776b3ab1d0c42eb16eb6d93dd574c472ee39d3a94f6ffc808a1a0a7ab6187524cbaf9bb7e93d487de1dae33c72fe31c278ff8908ac" + ], "split_commitment": null } ], @@ -369,7 +377,7 @@ "script_version": 0, "script_key": "02b2d0d9435b2a97e09da73665048bfadcebfbe17b6fa572d955bc11e5d665f689", "group_key": { - "group_key": "023a8b6353a798347b45a15b2c2348799aaa3a3290f1bd91896b310b01acf3b572" + "group_key": "02ad67d4a159934dc1ed02a49f9ad05ad69a90dc3f73c83341ba76e0a2472badf9" } }, "split_asset": null, @@ -383,7 +391,7 @@ "version": 0, "chain_params_hrp": "tapbc" }, - "expected": "cHNidP8BALICAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACewAAAAAAAAAiUSCy0NlDWyqX4J2nNmUEi/rc6/vhe2+lctlVvBHl1mX2iVkBAAAAAAAAIlEgstDZQ1sql+CdpzZlBIv63Ov74XtvpXLZVbwR5dZl9okAAAAAAXABAQFxBXRhcGJjAXIBAAAiBgK/j+L3JfM1c7d+aeg8NvDXbTdc28HjUIVQzFnFtifJDBgAAAAA+QMAgAAAAIB7AACAAAAAAMgBAAAhFr+P4vcl8zVzt35p6Dw28NdtN1zbweNQhVDMWcW2J8kMGQAAAAAA+QMAgAAAAIB7AACAAAAAAMgBAAABFyC/j+L3JfM1c7d+aeg8NvDXbTdc28HjUIVQzFnFtifJDAEYC21lcmtsZSByb290AXBlNimwIvRF0Vr9QpQEA3T2kkuYy/hxP42WLXyNAZGSwkL0pe47nRc0aGX8+SsMOhfJAovpkU63ZJxsk0eACXnRgwNW8qUDXwFkSsQGFLljY7qbrxpzgae6x0LSZ5Ce2sbuv8PrpecBcQgAAAAAAAADCQFyD2FuY2hvciBwa3NjcmlwdAFzCAAAAAAAAAADAXQhAr+P4vcl8zVzt35p6Dw28NdtN1zbweNQhVDMWcW2J8kMAXULbWVya2xlIHJvb3QidgK/j+L3JfM1c7d+aeg8NvDXbTdc28HjUIVQzFnFtifJDBgAAAAA+QMAgAAAAIB7AACAAAAAAMgBAAAhd7+P4vcl8zVzt35p6Dw28NdtN1zbweNQhVDMWcW2J8kMGQAAAAAA+QMAgAAAAIB7AACAAAAAAMgBAAABeAdzaWJsaW5nAXn9UgEAAQABit4DdAZ9ibx/AfH1c5gWWaRP8XpMchWjtTnrHlhJxgd9GUdsNkAyNGUyY2FmY2NhZTNhNjFmYjU4NmIxNDMyM2E2YmM4ZjllN2RmMWQ5MjkzMzNmZjk5MzkzM2JlYTZmNWIzYWY2JOLK/Mrjph+1hrFDI6a8j5598dkpMz/5k5M76m9bOvZvJpooAAIBAAMJ/114OZy+2Ao7BmkBZwBlAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAgAACSECK2CJAlEVzRw5CgFHbaVswg2dv09XG8iDYj+wJ6osepgKIQJ1xRfV7RSevuVzXaUNjMWaxjeENuAAE4Vhq9bEN9AtEwF6D3RoaXMgaXMgYSBwcm9vZgABcGUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFxCAAAAAAAAAAAAXIAAXMIAAAAAAAAAAABdQABeAABegAAAXABAQFxAQEBcggAAAAAAAAAAAFzIQK/j+L3JfM1c7d+aeg8NvDXbTdc28HjUIVQzFnFtifJDCJ0Ar+P4vcl8zVzt35p6Dw28NdtN1zbweNQhVDMWcW2J8kMGAAAAAD5AwCAAAAAgHsAAIAAAAAAyAEAACF1v4/i9yXzNXO3fmnoPDbw1203XNvB41CFUMxZxbYnyQwZAAAAAAD5AwCAAAAAgHsAAIAAAAAAyAEAAAF2/VIBAAEAAYphpkMBBSINCyloi3NLjqDzypk26EYfENd8luqAp6Zl9qXq0L1AOTkzZWJkZjg4OGIwNDg4M2U1NmExNTZhOGRlNTYzYWZhNDY3ZDQ5ZGVjNmE0MGU5YTFkMDA3ZjAzM2MyODIzMJk+vfiIsEiD5WoVao3lY6+kZ9Sd7GpA6aHQB/AzwoIwJf09fwACAQADCf9yu1OJQhZYAAZpAWcAZQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAIAAAkhArLQ2UNbKpfgnac2ZQSL+tzr++F7b6Vy2VW8EeXWZfaJCiECOotjU6eYNHtFoVssI0h5mqo6MpDxvZGJazELAazztXIBd/1SAQABAAGKYaZDAQUiDQspaItzS46g88qZNuhGHxDXfJbqgKemZfal6tC9QDk5M2ViZGY4ODhiMDQ4ODNlNTZhMTU2YThkZTU2M2FmYTQ2N2Q0OWRlYzZhNDBlOWExZDAwN2YwMzNjMjgyMzCZPr34iLBIg+VqFWqN5WOvpGfUnexqQOmh0AfwM8KCMCX9PX8AAgEAAwn/crtTiUIWWAAGaQFnAGUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgCAAAJIQKy0NlDWyqX4J2nNmUEi/rc6/vhe2+lctlVvBHl1mX2iQohAjqLY1OnmDR7RaFbLCNIeZqqOjKQ8b2RiWsxCwGs87VyAXgVAMASbm90IGEgdmFsaWQgc2NyaXB0AAFwAQEBcQEAAXIIAAAAAAAAAAEBcyECv4/i9yXzNXO3fmnoPDbw1203XNvB41CFUMxZxbYnyQwidAK/j+L3JfM1c7d+aeg8NvDXbTdc28HjUIVQzFnFtifJDBgAAAAA+QMAgAAAAIB7AACAAAAAAMgBAAAhdb+P4vcl8zVzt35p6Dw28NdtN1zbweNQhVDMWcW2J8kMGQAAAAAA+QMAgAAAAIB7AACAAAAAAMgBAAABdv1SAQABAAGKYaZDAQUiDQspaItzS46g88qZNuhGHxDXfJbqgKemZfal6tC9QDk5M2ViZGY4ODhiMDQ4ODNlNTZhMTU2YThkZTU2M2FmYTQ2N2Q0OWRlYzZhNDBlOWExZDAwN2YwMzNjMjgyMzCZPr34iLBIg+VqFWqN5WOvpGfUnexqQOmh0AfwM8KCMCX9PX8AAgEAAwn/crtTiUIWWAAGaQFnAGUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgCAAAJIQKy0NlDWyqX4J2nNmUEi/rc6/vhe2+lctlVvBHl1mX2iQohAjqLY1OnmDR7RaFbLCNIeZqqOjKQ8b2RiWsxCwGs87VyAXhBARl84i0SvFqZWHUzr0EWn6Hcn/hmwNTTAhFY1ikzZy0RGXziLRK8WplYdTOvQRafodyf+GbA1NMCEVjWKTNnLREA", + "expected": "cHNidP8BALICAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACewAAAAAAAAAiUSCy0NlDWyqX4J2nNmUEi/rc6/vhe2+lctlVvBHl1mX2iVkBAAAAAAAAIlEgstDZQ1sql+CdpzZlBIv63Ov74XtvpXLZVbwR5dZl9okAAAAAAXABAQFxBXRhcGJjAXIBAAAiBgK/j+L3JfM1c7d+aeg8NvDXbTdc28HjUIVQzFnFtifJDBgAAAAA+QMAgAAAAIB7AACAAAAAAMgBAAAhFr+P4vcl8zVzt35p6Dw28NdtN1zbweNQhVDMWcW2J8kMGQAAAAAA+QMAgAAAAIB7AACAAAAAAMgBAAABFyC/j+L3JfM1c7d+aeg8NvDXbTdc28HjUIVQzFnFtifJDAEYC21lcmtsZSByb290AXBlNimwIvRF0Vr9QpQEA3T2kkuYy/hxP42WLXyNAZGSwkL0pe47iVO7aGX8+SsMOhfJAovpkU63ZJxsk0eACXnRgwNW8qUDXwFkSsQGFLljY7qbrxpzgae6x0LSZ5Ce2sbuv8PrpecBcQgAAAAAAAADCQFyD2FuY2hvciBwa3NjcmlwdAFzCAAAAAAAAAADAXQhAr+P4vcl8zVzt35p6Dw28NdtN1zbweNQhVDMWcW2J8kMAXULbWVya2xlIHJvb3QidgK/j+L3JfM1c7d+aeg8NvDXbTdc28HjUIVQzFnFtifJDBgAAAAA+QMAgAAAAIB7AACAAAAAAMgBAAAhd7+P4vcl8zVzt35p6Dw28NdtN1zbweNQhVDMWcW2J8kMGQAAAAAA+QMAgAAAAIB7AACAAAAAAMgBAAABeAdzaWJsaW5nAXn9lgEAAQABit4DdAZ9ibx/AfH1c5gWWaRP8XpMchWjtTnrHlhJxgd9GUdsNkAyNGUyY2FmY2NhZTNhNjFmYjU4NmIxNDMyM2E2YmM4ZjllN2RmMWQ5MjkzMzNmZjk5MzkzM2JlYTZmNWIzYWY2JOLK/Mrjph+1hrFDI6a8j5598dkpMz/5k5M76m9bOvZvJpooAAIBAAMJ/x7p92dmeOerBq0BqwBlAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQgFAlvAYmdPXplOehMjfv5Q62fEGye1qxzYoWfV1IknJNZ2EIGqHokJVKN1Hx+8j5m/pJ2puKzFQdNwNs0hv56v+GQgCAAAJIQIrYIkCURXNHDkKAUdtpWzCDZ2/T1cbyINiP7Anqix6mAohA+M4VRftaLkdzUbD2lCRRidOrpyZQttO7R1AVz1ueiKJAXoPdGhpcyBpcyBhIHByb29mAAFwZQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAXEIAAAAAAAAAAABcgABcwgAAAAAAAAAAAF1AAF4AAF6AAABcAEBAXEBAQFyCAAAAAAAAAAAAXMhAr+P4vcl8zVzt35p6Dw28NdtN1zbweNQhVDMWcW2J8kMInQCv4/i9yXzNXO3fmnoPDbw1203XNvB41CFUMxZxbYnyQwYAAAAAPkDAIAAAACAewAAgAAAAADIAQAAIXW/j+L3JfM1c7d+aeg8NvDXbTdc28HjUIVQzFnFtifJDBkAAAAAAPkDAIAAAACAewAAgAAAAADIAQAAAXb9lgEAAQABimGmQwEFIg0LKWiLc0uOoPPKmTboRh8Q13yW6oCnpmX2perQvUBkOGJlOWMzOTc4YjA0ODgzZTU2YTE1NmE4ZGU1NjNhZmE0NjdkNDlkZWM2YTQwZTlhMWQwMDdmMDMzYzI4MjMw2L6cOXiwSIPlahVqjeVjr6Rn1J3sakDpodAH8DPCgjAl/T1/AAIBAAMJ/0agPLRK+GS7Bq0BqwBlAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQgFAJ1OWhKOIZH25zxN3azqx0MQusW622T3VdMRy7jnTqU9v/ICKGgp6thh1JMuvm7fpPUh94drjPHL+McJ4/4kIrAgCAAAJIQKy0NlDWyqX4J2nNmUEi/rc6/vhe2+lctlVvBHl1mX2iQohAq1n1KFZk03B7QKkn5rQWtaakNw/c8gzQbp24KJHK635AXf9lgEAAQABimGmQwEFIg0LKWiLc0uOoPPKmTboRh8Q13yW6oCnpmX2perQvUBkOGJlOWMzOTc4YjA0ODgzZTU2YTE1NmE4ZGU1NjNhZmE0NjdkNDlkZWM2YTQwZTlhMWQwMDdmMDMzYzI4MjMw2L6cOXiwSIPlahVqjeVjr6Rn1J3sakDpodAH8DPCgjAl/T1/AAIBAAMJ/0agPLRK+GS7Bq0BqwBlAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQgFAJ1OWhKOIZH25zxN3azqx0MQusW622T3VdMRy7jnTqU9v/ICKGgp6thh1JMuvm7fpPUh94drjPHL+McJ4/4kIrAgCAAAJIQKy0NlDWyqX4J2nNmUEi/rc6/vhe2+lctlVvBHl1mX2iQohAq1n1KFZk03B7QKkn5rQWtaakNw/c8gzQbp24KJHK635AXgVAMASbm90IGEgdmFsaWQgc2NyaXB0AAFwAQEBcQEAAXIIAAAAAAAAAAEBcyECv4/i9yXzNXO3fmnoPDbw1203XNvB41CFUMxZxbYnyQwidAK/j+L3JfM1c7d+aeg8NvDXbTdc28HjUIVQzFnFtifJDBgAAAAA+QMAgAAAAIB7AACAAAAAAMgBAAAhdb+P4vcl8zVzt35p6Dw28NdtN1zbweNQhVDMWcW2J8kMGQAAAAAA+QMAgAAAAIB7AACAAAAAAMgBAAABdv2WAQABAAGKYaZDAQUiDQspaItzS46g88qZNuhGHxDXfJbqgKemZfal6tC9QGQ4YmU5YzM5NzhiMDQ4ODNlNTZhMTU2YThkZTU2M2FmYTQ2N2Q0OWRlYzZhNDBlOWExZDAwN2YwMzNjMjgyMzDYvpw5eLBIg+VqFWqN5WOvpGfUnexqQOmh0AfwM8KCMCX9PX8AAgEAAwn/RqA8tEr4ZLsGrQGrAGUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCAUAnU5aEo4hkfbnPE3drOrHQxC6xbrbZPdV0xHLuOdOpT2/8gIoaCnq2GHUky6+bt+k9SH3h2uM8cv4xwnj/iQisCAIAAAkhArLQ2UNbKpfgnac2ZQSL+tzr++F7b6Vy2VW8EeXWZfaJCiECrWfUoVmTTcHtAqSfmtBa1pqQ3D9zyDNBunbgokcrrfkBeEEBGXziLRK8WplYdTOvQRafodyf+GbA1NMCEVjWKTNnLREZfOItErxamVh1M69BFp+h3J/4ZsDU0wIRWNYpM2ctEQA=", "comment": "random packet" } ], diff --git a/tapscript/mint.go b/tapscript/mint.go new file mode 100644 index 000000000..7eee733e3 --- /dev/null +++ b/tapscript/mint.go @@ -0,0 +1,56 @@ +package tapscript + +import ( + "fmt" + + "github.com/btcsuite/btcd/wire" + "github.com/lightninglabs/taproot-assets/asset" +) + +// GroupTxBuilder is an implementation of the asset.GenesisTxBuilder +// interface that constructs virtual transactions for grouped asset genesis. +type GroupTxBuilder struct{} + +// BuildGenesisTx constructs a virtual transaction and prevOut that represent +// the genesis state transition for a grouped asset. This output is used to +// create a group witness for the grouped asset. +func BuildGenesisTx(newAsset *asset.Asset) (*wire.MsgTx, + *wire.TxOut, error) { + + // First, we check that the passed asset is a genesis grouped asset + // that has no group witness. + if !newAsset.NeedsGenesisWitnessForGroup() { + return nil, nil, fmt.Errorf("asset is not a genesis grouped" + + "asset") + } + + prevOut, err := asset.InputGenesisAssetPrevOut(*newAsset) + if err != nil { + return nil, nil, err + } + + // Now, create the virtual transaction that represents this asset + // minting. + virtualTx, _, err := VirtualTx(newAsset, nil) + if err != nil { + return nil, nil, err + } + populatedVirtualTx := asset.VirtualTxWithInput( + virtualTx, newAsset, 0, nil, + ) + + return populatedVirtualTx, prevOut, nil +} + +// BuildGenesisTx constructs a virtual transaction and prevOut that represent +// the genesis state transition for a grouped asset. This output is used to +// create a group witness for the grouped asset. +func (m *GroupTxBuilder) BuildGenesisTx(newAsset *asset.Asset) (*wire.MsgTx, + *wire.TxOut, error) { + + return BuildGenesisTx(newAsset) +} + +// A compile time assertion to ensure that GroupTxBuilder meets the +// asset.GenesisTxBuilder interface. +var _ asset.GenesisTxBuilder = (*GroupTxBuilder)(nil) diff --git a/tapscript/mock.go b/tapscript/mock.go index 9d206073a..767756135 100644 --- a/tapscript/mock.go +++ b/tapscript/mock.go @@ -1,14 +1,11 @@ package tapscript import ( - "fmt" - "github.com/btcsuite/btcd/btcec/v2" "github.com/btcsuite/btcd/btcec/v2/schnorr" - "github.com/btcsuite/btcd/txscript" "github.com/btcsuite/btcd/wire" "github.com/lightninglabs/lndclient" - "github.com/lightningnetwork/lnd/input" + "github.com/lightninglabs/taproot-assets/asset" ) type MockSigner struct { @@ -21,106 +18,10 @@ func NewMockSigner(privKey *btcec.PrivateKey) *MockSigner { } } -// SignOutputRaw creates a signature for a single input. -// Taken from lnd/lnwallet/btcwallet/signer:L344, SignOutputRaw -func (m *MockSigner) SignOutputRaw(tx *wire.MsgTx, - signDesc *input.SignDescriptor) (*schnorr.Signature, error) { - - witnessScript := signDesc.WitnessScript - - privKey := m.PrivKey - var maybeTweakPrivKey *btcec.PrivateKey - - switch { - case signDesc.SingleTweak != nil: - maybeTweakPrivKey = input.TweakPrivKey( - privKey, signDesc.SingleTweak, - ) - - case signDesc.DoubleTweak != nil: - maybeTweakPrivKey = input.DeriveRevocationPrivKey( - privKey, signDesc.DoubleTweak, - ) - - default: - maybeTweakPrivKey = privKey - } - - privKey = maybeTweakPrivKey - - // In case of a taproot output any signature is always a Schnorr - // signature, based on the new tapscript sighash algorithm. - if !txscript.IsPayToTaproot(signDesc.Output.PkScript) { - return nil, fmt.Errorf("mock signer: output script not taproot") - } - - sigHashes := txscript.NewTxSigHashes( - tx, signDesc.PrevOutputFetcher, - ) - - // Are we spending a script path or the key path? The API is slightly - // different, so we need to account for that to get the raw signature. - var ( - rawSig []byte - err error - ) - switch signDesc.SignMethod { - case input.TaprootKeySpendBIP0086SignMethod, - input.TaprootKeySpendSignMethod: - - // This function tweaks the private key using the tap root key - // supplied as the tweak. - rawSig, err = txscript.RawTxInTaprootSignature( - tx, sigHashes, signDesc.InputIndex, - signDesc.Output.Value, signDesc.Output.PkScript, - signDesc.TapTweak, signDesc.HashType, privKey, - ) - - case input.TaprootScriptSpendSignMethod: - leaf := txscript.TapLeaf{ - LeafVersion: txscript.BaseLeafVersion, - Script: witnessScript, - } - rawSig, err = txscript.RawTxInTapscriptSignature( - tx, sigHashes, signDesc.InputIndex, - signDesc.Output.Value, signDesc.Output.PkScript, - leaf, signDesc.HashType, privKey, - ) - } - if err != nil { - return nil, err - } - - return schnorr.ParseSignature(rawSig) -} - func (m *MockSigner) SignVirtualTx(signDesc *lndclient.SignDescriptor, tx *wire.MsgTx, prevOut *wire.TxOut) (*schnorr.Signature, error) { - prevOutFetcher := txscript.NewCannedPrevOutputFetcher( - prevOut.PkScript, prevOut.Value, - ) - - sigHashes := txscript.NewTxSigHashes(tx, prevOutFetcher) - - fullSignDesc := input.SignDescriptor{ - KeyDesc: signDesc.KeyDesc, - SingleTweak: signDesc.SingleTweak, - DoubleTweak: signDesc.DoubleTweak, - TapTweak: signDesc.TapTweak, - WitnessScript: signDesc.WitnessScript, - SignMethod: signDesc.SignMethod, - Output: signDesc.Output, - HashType: signDesc.HashType, - SigHashes: sigHashes, - PrevOutputFetcher: prevOutFetcher, - InputIndex: signDesc.InputIndex, - } - - sig, err := m.SignOutputRaw(tx, &fullSignDesc) - if err != nil { - return nil, err - } - - return sig, nil + return asset.SignVirtualTx(m.PrivKey, signDesc, tx, prevOut) } + +var _ Signer = (*MockSigner)(nil) diff --git a/tapscript/send.go b/tapscript/send.go index 70cc89fbc..3a43233ad 100644 --- a/tapscript/send.go +++ b/tapscript/send.go @@ -627,7 +627,7 @@ func SignVirtualTransaction(vPkt *tappsbt.VPacket, signer Signer, // Update the input of the virtual TX, generate a witness, and // attach it to the copy of the new Asset. virtualTxCopy := virtualTx.Copy() - inputSpecificVirtualTx := VirtualTxWithInput( + inputSpecificVirtualTx := asset.VirtualTxWithInput( virtualTxCopy, input.Asset(), uint32(idx), nil, ) diff --git a/tapscript/send_test.go b/tapscript/send_test.go index c1f3d337d..7d9b707c9 100644 --- a/tapscript/send_test.go +++ b/tapscript/send_test.go @@ -103,6 +103,9 @@ func initSpendScenario(t *testing.T) spendData { state.genesis1.MetaHash = [32]byte{} state.genesis1collect.MetaHash = [32]byte{} + // Our mock genesis TXs always use an output index of 0. + state.genesis1.OutputIndex = 0 + // Keys for sender, receiver, and group. Default to keypath spend // for the spender ScriptKey. spenderPrivKey, spenderPubKey := btcec.PrivKeyFromBytes(key1Bytes) @@ -119,7 +122,12 @@ func initSpendScenario(t *testing.T) spendData { state.receiverPrivKey = *receiverPrivKey state.receiverPubKey = *receiverPubKey - groupKey := asset.RandGroupKey(t, state.genesis1collect) + genesis1collectProtoAsset := asset.NewAssetNoErr( + t, state.genesis1collect, 1, 0, 0, spenderScriptKey, nil, + ) + groupKey := asset.RandGroupKey( + t, state.genesis1collect, genesis1collectProtoAsset, + ) state.groupKey = *groupKey // Addresses to cover both asset types and all three asset values. @@ -271,7 +279,9 @@ func createGenesisProof(t *testing.T, state *spendData) { require.NoError(t, err) asset2GenesisTx := &wire.MsgTx{ Version: 2, - TxIn: []*wire.TxIn{{}}, + TxIn: []*wire.TxIn{{ + PreviousOutPoint: state.genesis1.FirstPrevOut, + }}, TxOut: []*wire.TxOut{{ PkScript: senderScript, Value: 330, @@ -311,6 +321,7 @@ func createGenesisProof(t *testing.T, state *spendData) { Proof: *asset2CommitmentProof, }, }, + GenesisReveal: &state.asset2.Genesis, } state.asset2GenesisProof = asset2GenesisProof @@ -1725,7 +1736,7 @@ func TestProofVerify(t *testing.T) { // Add a PrevID to represent our fake genesis TX. genesisOutPoint := &wire.OutPoint{ Hash: state.asset2GenesisProof.AnchorTx.TxHash(), - Index: state.asset2GenesisProof.PrevOut.Index, + Index: state.asset2GenesisProof.InclusionProof.OutputIndex, } state.asset2PrevID = asset.PrevID{ OutPoint: *genesisOutPoint, @@ -1750,21 +1761,29 @@ func TestProofVerify(t *testing.T) { // Create a proof for each receiver and verify it. senderBlob, _, err := proof.AppendTransition( genesisProofBlob, &proofParams[0], proof.MockHeaderVerifier, + proof.MockGroupVerifier, ) require.NoError(t, err) senderFile := proof.NewEmptyFile(proof.V0) require.NoError(t, senderFile.Decode(bytes.NewReader(senderBlob))) - _, err = senderFile.Verify(context.TODO(), proof.MockHeaderVerifier) + _, err = senderFile.Verify( + context.TODO(), proof.MockHeaderVerifier, + proof.MockGroupVerifier, + ) require.NoError(t, err) receiverBlob, _, err := proof.AppendTransition( genesisProofBlob, &proofParams[1], proof.MockHeaderVerifier, + proof.MockGroupVerifier, ) require.NoError(t, err) receiverFile, err := proof.NewFile(proof.V0) require.NoError(t, err) require.NoError(t, receiverFile.Decode(bytes.NewReader(receiverBlob))) - _, err = receiverFile.Verify(context.TODO(), proof.MockHeaderVerifier) + _, err = receiverFile.Verify( + context.TODO(), proof.MockHeaderVerifier, + proof.MockGroupVerifier, + ) require.NoError(t, err) } @@ -1788,7 +1807,7 @@ func TestProofVerifyFullValueSplit(t *testing.T) { // Add a PrevID to represent our fake genesis TX. genesisOutPoint := &wire.OutPoint{ Hash: state.asset2GenesisProof.AnchorTx.TxHash(), - Index: state.asset2GenesisProof.PrevOut.Index, + Index: state.asset2GenesisProof.InclusionProof.OutputIndex, } state.asset2PrevID = asset.PrevID{ OutPoint: *genesisOutPoint, @@ -1815,21 +1834,29 @@ func TestProofVerifyFullValueSplit(t *testing.T) { // Create a proof for each receiver and verify it. senderBlob, _, err := proof.AppendTransition( genesisProofBlob, &proofParams[0], proof.MockHeaderVerifier, + proof.MockGroupVerifier, ) require.NoError(t, err) senderFile, err := proof.NewFile(proof.V0) require.NoError(t, err) require.NoError(t, senderFile.Decode(bytes.NewReader(senderBlob))) - _, err = senderFile.Verify(context.TODO(), proof.MockHeaderVerifier) + _, err = senderFile.Verify( + context.TODO(), proof.MockHeaderVerifier, + proof.MockGroupVerifier, + ) require.NoError(t, err) receiverBlob, _, err := proof.AppendTransition( genesisProofBlob, &proofParams[1], proof.MockHeaderVerifier, + proof.MockGroupVerifier, ) require.NoError(t, err) receiverFile := proof.NewEmptyFile(proof.V0) require.NoError(t, receiverFile.Decode(bytes.NewReader(receiverBlob))) - _, err = receiverFile.Verify(context.TODO(), proof.MockHeaderVerifier) + _, err = receiverFile.Verify( + context.TODO(), proof.MockHeaderVerifier, + proof.MockGroupVerifier, + ) require.NoError(t, err) } diff --git a/tapscript/tx.go b/tapscript/tx.go index 4a742434a..a9d12e6e3 100644 --- a/tapscript/tx.go +++ b/tapscript/tx.go @@ -4,12 +4,10 @@ import ( "bytes" "context" "crypto/sha256" - "encoding/binary" "errors" "fmt" "github.com/btcsuite/btcd/btcec/v2/schnorr" - "github.com/btcsuite/btcd/chaincfg/chainhash" "github.com/btcsuite/btcd/txscript" "github.com/btcsuite/btcd/wire" "github.com/lightninglabs/lndclient" @@ -41,95 +39,60 @@ const ( zeroIndex = 0 ) -// computeTaprootScript computes the on-chain SegWit v1 script, known as -// Taproot, based on the given `witnessProgram`. -func computeTaprootScript(witnessProgram []byte) ([]byte, error) { - return txscript.NewScriptBuilder(). - AddOp(txscript.OP_1). - AddData(witnessProgram[:]). - Script() -} - -// virtualTxInPrevOut returns the prevout of the Taproot Asset virtual -// transaction's single input as a hash of the root node's key concatenated by -// its sum. -func virtualTxInPrevOut(root mssmt.Node) *wire.OutPoint { - // Grab the hash digest of the SMT node. This'll be used to generate - // the virtual prev out for this tx in. - // - // TODO(roasbeef): this already contains the sum, so can just use it - // directly? - rootKey := root.NodeHash() - - // Map this to: nodeHash || nodeSum. - h := sha256.New() - _, _ = h.Write(rootKey[:]) - _ = binary.Write(h, binary.BigEndian, root.NodeSum()) - - return wire.NewOutPoint( - (*chainhash.Hash)(h.Sum(nil)), zeroIndex, - ) -} - // virtualTxIn computes the single input of a Taproot Asset virtual transaction. // The input prevout's hash is the root of a MS-SMT committing to all inputs of // a state transition. func virtualTxIn(newAsset *asset.Asset, prevAssets commitment.InputSet) ( *wire.TxIn, mssmt.Tree, error) { - // Genesis assets shouldn't have any inputs committed, so they'll have - // an empty input tree. - isGenesisAsset := newAsset.HasGenesisWitness() inputTree := mssmt.NewCompactedTree(mssmt.NewDefaultStore()) - if !isGenesisAsset { - // For each input we'll locate the asset UTXO beign spent, then - // insert that into a new SMT, with the key being the hash of - // the prevID pointer, and the value being the leaf itself. - inputsConsumed := make( - map[asset.PrevID]struct{}, len(prevAssets), - ) + // For each input we'll locate the asset UTXO being spent, then + // insert that into a new SMT, with the key being the hash of + // the prevID pointer, and the value being the leaf itself. + inputsConsumed := make( + map[asset.PrevID]struct{}, len(prevAssets), + ) + + // TODO(bhandras): thread the context through. + ctx := context.TODO() + + for _, input := range newAsset.PrevWitnesses { + // At this point, each input MUST have a prev ID. + if input.PrevID == nil { + return nil, nil, ErrNoInputs + } - // TODO(bhandras): thread the context through. - ctx := context.TODO() - - for _, input := range newAsset.PrevWitnesses { - // At this point, each input MUST have a prev ID. - if input.PrevID == nil { - return nil, nil, ErrNoInputs - } - - // The set of prev assets are similar to the prev - // output fetcher used in taproot. - prevAsset, ok := prevAssets[*input.PrevID] - if !ok { - return nil, nil, ErrNoInputs - } - - // Now we'll insert this prev asset leaf into the tree. - // The generated leaf includes the amount of the asset, - // so the sum of this tree will be the total amount - // being spent. - key := input.PrevID.Hash() - leaf, err := prevAsset.Leaf() - if err != nil { - return nil, nil, err - } - _, err = inputTree.Insert(ctx, key, leaf) - if err != nil { - return nil, nil, err - } - - inputsConsumed[*input.PrevID] = struct{}{} + // The set of prev assets are similar to the prev + // output fetcher used in taproot. + prevAsset, ok := prevAssets[*input.PrevID] + if !ok { + return nil, nil, ErrNoInputs } - // In this context, the set of referenced inputs should match - // the set of previous assets. This ensures no duplicate inputs - // are being spent. - // - // TODO(roasbeef): make further explicit? - if len(inputsConsumed) != len(prevAssets) { - return nil, nil, ErrInputMismatch + // Now we'll insert this prev asset leaf into the tree. + // The generated leaf includes the amount of the asset, + // so the sum of this tree will be the total amount + // being spent. + key := input.PrevID.Hash() + leaf, err := prevAsset.Leaf() + if err != nil { + return nil, nil, err + } + _, err = inputTree.Insert(ctx, key, leaf) + if err != nil { + return nil, nil, err } + + inputsConsumed[*input.PrevID] = struct{}{} + } + + // In this context, the set of referenced inputs should match + // the set of previous assets. This ensures no duplicate inputs + // are being spent. + // + // TODO(roasbeef): make further explicit? + if len(inputsConsumed) != len(prevAssets) { + return nil, nil, ErrInputMismatch } treeRoot, err := inputTree.Root(context.Background()) @@ -138,26 +101,26 @@ func virtualTxIn(newAsset *asset.Asset, prevAssets commitment.InputSet) ( } // TODO(roasbeef): document empty hash usage here - prevOut := virtualTxInPrevOut(treeRoot) + prevOut := asset.VirtualTxInPrevOut(treeRoot) return wire.NewTxIn(prevOut, nil, nil), inputTree, nil } // virtualTxOut computes the single output of a Taproot Asset virtual // transaction based on whether an asset has a split commitment or not. -func virtualTxOut(asset *asset.Asset) (*wire.TxOut, error) { +func virtualTxOut(txAsset *asset.Asset) (*wire.TxOut, error) { // If we have any asset splits, then we'll indirectly commit to all of // them through the SplitCommitmentRoot. - if asset.SplitCommitmentRoot != nil { + if txAsset.SplitCommitmentRoot != nil { // In this case, we already have an MS-SMT over the set of // outputs created, so we'll map this into a normal taproot // (segwit v1) script. - rootKey := asset.SplitCommitmentRoot.NodeHash() - pkScript, err := computeTaprootScript(rootKey[:]) + rootKey := txAsset.SplitCommitmentRoot.NodeHash() + pkScript, err := asset.ComputeTaprootScript(rootKey[:]) if err != nil { return nil, err } - value := int64(asset.SplitCommitmentRoot.NodeSum()) + value := int64(txAsset.SplitCommitmentRoot.NodeSum()) return wire.NewTxOut(value, pkScript), nil } @@ -165,27 +128,29 @@ func virtualTxOut(asset *asset.Asset) (*wire.TxOut, error) { // this case, the output script is derived from the root of a // MS-SMT containing the new asset. var groupKey []byte - if asset.GroupKey != nil { - groupKey = schnorr.SerializePubKey(&asset.GroupKey.GroupPubKey) + if txAsset.GroupKey != nil { + groupKey = schnorr.SerializePubKey( + &txAsset.GroupKey.GroupPubKey, + ) } else { var emptyKey [32]byte groupKey = emptyKey[:] } - assetID := asset.Genesis.ID() + assetID := txAsset.Genesis.ID() // TODO(roasbeef): double check this key matches the split commitment // above? or can treat as standalone case (no splits) h := sha256.New() _, _ = h.Write(groupKey) _, _ = h.Write(assetID[:]) - _, _ = h.Write(schnorr.SerializePubKey(asset.ScriptKey.PubKey)) + _, _ = h.Write(schnorr.SerializePubKey(txAsset.ScriptKey.PubKey)) // The new asset may have witnesses for its input(s), so make a // copy and strip them out when including the asset in the tree, // as the witness depends on the result of the tree. // // TODO(roasbeef): ensure this is documented in the BIP - copyWithoutWitness := asset.Copy() + copyWithoutWitness := txAsset.Copy() for i := range copyWithoutWitness.PrevWitnesses { copyWithoutWitness.PrevWitnesses[i].TxWitness = nil } @@ -208,11 +173,11 @@ func virtualTxOut(asset *asset.Asset) (*wire.TxOut, error) { } rootKey := treeRoot.NodeHash() - pkScript, err := computeTaprootScript(rootKey[:]) + pkScript, err := asset.ComputeTaprootScript(rootKey[:]) if err != nil { return nil, err } - return wire.NewTxOut(int64(asset.Amount), pkScript), nil + return wire.NewTxOut(int64(txAsset.Amount), pkScript), nil } // VirtualTx constructs the virtual transaction that enables the movement of an @@ -220,8 +185,20 @@ func virtualTxOut(asset *asset.Asset) (*wire.TxOut, error) { func VirtualTx(newAsset *asset.Asset, prevAssets commitment.InputSet) ( *wire.MsgTx, mssmt.Tree, error) { + var ( + txIn *wire.TxIn + inputTree mssmt.Tree + err error + ) + // We'll start by mapping all inputs into a MS-SMT. - txIn, inputTree, err := virtualTxIn(newAsset, prevAssets) + if newAsset.NeedsGenesisWitnessForGroup() || + newAsset.HasGenesisWitnessForGroup() { + + txIn, inputTree, err = asset.VirtualGenesisTxIn(newAsset) + } else { + txIn, inputTree, err = virtualTxIn(newAsset, prevAssets) + } if err != nil { return nil, nil, err } @@ -240,31 +217,12 @@ func VirtualTx(newAsset *asset.Asset, prevAssets commitment.InputSet) ( return virtualTx, inputTree, nil } -// VirtualTxWithInput returns a copy of the `virtualTx` amended to include all -// input-specific details. -// -// This is used to further bind a given witness to the "true" input it spends. -// We'll use the index of the serialized input to bind the prev index, which -// represents the "leaf index" of the virtual input MS-SMT. -func VirtualTxWithInput(virtualTx *wire.MsgTx, input *asset.Asset, - idx uint32, witness wire.TxWitness) *wire.MsgTx { - - txCopy := virtualTx.Copy() - txCopy.LockTime = uint32(input.LockTime) - txCopy.TxIn[zeroIndex].PreviousOutPoint.Index = idx - txCopy.TxIn[zeroIndex].Sequence = uint32(input.RelativeLockTime) - txCopy.TxIn[zeroIndex].Witness = witness - return txCopy -} - // InputAssetPrevOut returns a TxOut that represents the input asset in a // Taproot Asset virtual TX. func InputAssetPrevOut(prevAsset asset.Asset) (*wire.TxOut, error) { - var pkScript []byte switch prevAsset.ScriptVersion { case asset.ScriptV0: - var err error - pkScript, err = PayToTaprootScript(prevAsset.ScriptKey.PubKey) + pkScript, err := PayToTaprootScript(prevAsset.ScriptKey.PubKey) if err != nil { return nil, err } @@ -299,7 +257,7 @@ func InputPrevOutFetcher(prevAsset asset.Asset) (*txscript.CannedPrevOutputFetch func InputKeySpendSigHash(virtualTx *wire.MsgTx, input *asset.Asset, idx uint32, sigHashType txscript.SigHashType) ([]byte, error) { - virtualTxCopy := VirtualTxWithInput(virtualTx, input, idx, nil) + virtualTxCopy := asset.VirtualTxWithInput(virtualTx, input, idx, nil) prevOutFetcher, err := InputPrevOutFetcher(*input) if err != nil { return nil, err @@ -318,7 +276,7 @@ func InputScriptSpendSigHash(virtualTx *wire.MsgTx, input *asset.Asset, idx uint32, sigHashType txscript.SigHashType, tapLeaf *txscript.TapLeaf) ([]byte, error) { - virtualTxCopy := VirtualTxWithInput(virtualTx, input, idx, nil) + virtualTxCopy := asset.VirtualTxWithInput(virtualTx, input, idx, nil) prevOutFetcher, err := InputPrevOutFetcher(*input) if err != nil { return nil, err diff --git a/universe/base.go b/universe/base.go index 745ec3a09..edb36feeb 100644 --- a/universe/base.go +++ b/universe/base.go @@ -28,6 +28,10 @@ type MintingArchiveConfig struct { // genesis proof. HeaderVerifier proof.HeaderVerifier + // GroupVerifier is used to verify the validity of the group key for a + // genesis proof. + GroupVerifier proof.GroupVerifier + // Multiverse is used to interact with the set of known base // universe trees, and also obtain associated metadata and statistics. Multiverse MultiverseArchive @@ -224,6 +228,7 @@ func (a *MintingArchive) verifyIssuanceProof(ctx context.Context, id Identifier, assetSnapshot, err := leaf.Proof.Verify( ctx, prevAssetSnapshot, a.cfg.HeaderVerifier, + a.cfg.GroupVerifier, ) if err != nil { return nil, fmt.Errorf("unable to verify proof: %v", err) @@ -269,26 +274,71 @@ func (a *MintingArchive) RegisterNewIssuanceBatch(ctx context.Context, log.Infof("Verifying %d new proofs for insertion into Universe", len(items)) - err := fn.ParSlice( - ctx, items, func(ctx context.Context, i *IssuanceItem) error { - assetSnapshot, err := a.verifyIssuanceProof( - ctx, i.ID, i.Key, i.Leaf, nil, - ) - if err != nil { - return err - } + // Issuances that also create an asset group, group anchors, must be + // verified and stored before any issuances that may be reissuances into + // the same asset group. This is required for proper verification of + // reissuances, which may be in this batch. + var anchorItems []*IssuanceItem + nonAnchorItems := make([]*IssuanceItem, 0, len(items)) + for ind := range items { + item := items[ind] + // Any group anchor issuance proof must have a group key reveal + // attached, so tht can be used to partition anchor assets and + // non-anchor assets. + switch { + case item.Leaf.Proof.GroupKeyReveal != nil: + anchorItems = append(anchorItems, item) + default: + nonAnchorItems = append(nonAnchorItems, item) + } + } - i.MetaReveal = assetSnapshot.MetaReveal + verifyBatch := func(batchItems []*IssuanceItem) error { + err := fn.ParSlice( + ctx, batchItems, func(ctx context.Context, + i *IssuanceItem) error { - return nil - }, - ) + assetSnapshot, err := a.verifyIssuanceProof( + ctx, i.ID, i.Key, i.Leaf, nil, + ) + if err != nil { + return err + } + + i.MetaReveal = assetSnapshot.MetaReveal + + return nil + }, + ) + if err != nil { + return fmt.Errorf("unable to verify issuance proofs: "+ + "%w", err) + } + + return nil + } + + err := verifyBatch(anchorItems) + if err != nil { + return err + } + + log.Infof("Inserting %d verified group anchor proofs into Universe", + len(anchorItems)) + err = a.cfg.Multiverse.RegisterBatchIssuance(ctx, anchorItems) + if err != nil { + return fmt.Errorf("unable to register new group anchor "+ + "issuance proofs: %w", err) + } + + err = verifyBatch(nonAnchorItems) if err != nil { - return fmt.Errorf("unable to verify issuance proofs: %w", err) + return err } - log.Infof("Inserting %d verified proofs into Universe", len(items)) - err = a.cfg.Multiverse.RegisterBatchIssuance(ctx, items) + log.Infof("Inserting %d verified proofs into Universe", + len(nonAnchorItems)) + err = a.cfg.Multiverse.RegisterBatchIssuance(ctx, nonAnchorItems) if err != nil { return fmt.Errorf("unable to register new issuance proofs: %w", err) @@ -318,7 +368,9 @@ func (a *MintingArchive) getPrevAssetSnapshot(ctx context.Context, // If this is a genesis proof, then there is no previous asset (and // therefore no previous asset snapshot). - if newProof.Asset.HasGenesisWitness() { + if newProof.Asset.HasGenesisWitness() || + newProof.Asset.HasGenesisWitnessForGroup() { + return nil, nil } diff --git a/virtual_tx_signer.go b/virtual_tx_signer.go index b7d08efb8..fa81bcd84 100644 --- a/virtual_tx_signer.go +++ b/virtual_tx_signer.go @@ -6,6 +6,7 @@ import ( "github.com/btcsuite/btcd/btcec/v2/schnorr" "github.com/btcsuite/btcd/wire" "github.com/lightninglabs/lndclient" + "github.com/lightninglabs/taproot-assets/asset" "github.com/lightninglabs/taproot-assets/tapscript" ) @@ -46,6 +47,8 @@ func (l *LndRpcVirtualTxSigner) SignVirtualTx(signDesc *lndclient.SignDescriptor return virtualTxSig, nil } -// A compile time assertion to ensure LndRpcVirtualTxSigner meets the -// tapscript.Signer interface. +// Compile time assertions to ensure LndRpcVirtualTxSigner meets the +// tapscript.Signer and asset.GenesisSigner interfaces. var _ tapscript.Signer = (*LndRpcVirtualTxSigner)(nil) + +var _ asset.GenesisSigner = (*LndRpcVirtualTxSigner)(nil) diff --git a/vm/testdata/vm_validation_generated.json b/vm/testdata/vm_validation_generated.json index 85f611f98..6bb54995c 100644 --- a/vm/testdata/vm_validation_generated.json +++ b/vm/testdata/vm_validation_generated.json @@ -18,15 +18,17 @@ "asset_id": "0000000000000000000000000000000000000000000000000000000000000000", "script_key": "000000000000000000000000000000000000000000000000000000000000000000" }, - "tx_witness": null, + "tx_witness": [ + "9b0c6a56c3f6c0f32e2d7a3fbdedd9d30b2a9a65184a99da00b7d6ae6b2b037c317ab6a1bf0ac8f6396c2a2b8a45b23b5a7f288a6f5119088d27a238f0068de2" + ], "split_commitment": null } ], "split_commitment_root": null, "script_version": 0, - "script_key": "020a63940c839383ca25aee2aa951bdd5e4d21a02f2c5516f271c10c2c5cda5ab3", + "script_key": "025a2ecdb843565f539d8221f8089dce6abd88c5e86dab02f8924c55807ac3227d", "group_key": { - "group_key": "020fc0cfd65b59ce832579edcbc2b8886d5b99c0749c161e54b1c42a02688f7bf7" + "group_key": "03c191af8026bca0c9d4e24b4e2b26542d8aa50464c0a35503fc19cc036fef1999" } }, "split_set": [], @@ -41,7 +43,7 @@ "genesis_meta_hash": "d3d8df93fab7e125ddebafe65a31bd5d41e2d2ce9c2b17892f0fea1931a29022", "genesis_output_index": 25252826, "genesis_type": 0, - "amount": 8424619375577601359, + "amount": 9018276315719068316, "lock_time": 0, "relative_lock_time": 0, "prev_witnesses": [ @@ -51,15 +53,17 @@ "asset_id": "0000000000000000000000000000000000000000000000000000000000000000", "script_key": "000000000000000000000000000000000000000000000000000000000000000000" }, - "tx_witness": null, + "tx_witness": [ + "7dc3f7063deb5f85e62ff3635bd8e2cdbcb4e23b493074809c4ea2a88c4894f1bb4bba18ab51bdf4905c4047ba2fa972190355d210ce94693c84e106db7d0c87" + ], "split_commitment": null } ], "split_commitment_root": null, "script_version": 0, - "script_key": "02e6eb3bc918b9a94614573aebb6ae82068daa0992d16e72e742d1d1ef82b60b71", + "script_key": "02653fa5a1c26bb919e3423948558611e009615806f21e43abe7a70dcdeb834c91", "group_key": { - "group_key": "022632fe34120cf37a482f6d64b6b795768908ade0085165cfee678179f12ed34b" + "group_key": "030aba41a98624e5ffd0e541e8985ef6a721c4ec2a9f6ec22ee95da2a89d58ae04" } }, "split_set": [], @@ -82,19 +86,19 @@ "prev_id": { "out_point": "0000000000000000000000000000000000000000000000000000000000000000:0", "asset_id": "aab1690ccf37c7258f65b9c69669895d1f763fa7e1f3f558893bd946b1f271f2", - "script_key": "0253c673f0469e47b3d263f768e9757bd5fc70b8a04cc004963a0e87f40638ece7" + "script_key": "02e5cbc75c4d10bf4a7092e1807e8cde32ec60c7d84baab8d4c05999459fd4f547" }, "tx_witness": [ - "8c98e757cb83730977edb7bec02e6ba1fbbd10a8a5f75f982aced30221ab83fbd1cc1c939612a2140810ce0683d9e9b4b5c833a17a161af0d8cbaa0ac01dbfcf" + "62882bfd9a3453e8cfc5272b6c16f08dd5ecd151a8a41460af3dc82b82728e856b4b4b9599d0b93e73b31f8e902c178f74152277c737f23b17bb3d3cc3cfc320" ], "split_commitment": null } ], "split_commitment_root": null, "script_version": 0, - "script_key": "02606ff5340b5cbed25bddb4f8b88912b0cbbd9a8352c0477b76954c8973033fd5", + "script_key": "0279fd317c6dd26f87ddf77f51dc5c431a1ffcfea1548e46f03722f3fbabe168fa", "group_key": { - "group_key": "03de2df2370e5be5d011225180c5918931076949fee2e1ee7e40600fafcc6e09c5" + "group_key": "032a0a7a44b40879b843df6484605bbe4fee32ccf12778632095aa8a1c6c20ee00" } }, "split_set": [], @@ -103,7 +107,7 @@ "prev_id": { "out_point": "0000000000000000000000000000000000000000000000000000000000000000:0", "asset_id": "aab1690ccf37c7258f65b9c69669895d1f763fa7e1f3f558893bd946b1f271f2", - "script_key": "0253c673f0469e47b3d263f768e9757bd5fc70b8a04cc004963a0e87f40638ece7" + "script_key": "02e5cbc75c4d10bf4a7092e1807e8cde32ec60c7d84baab8d4c05999459fd4f547" }, "asset": { "version": 0, @@ -128,9 +132,9 @@ ], "split_commitment_root": null, "script_version": 0, - "script_key": "0253c673f0469e47b3d263f768e9757bd5fc70b8a04cc004963a0e87f40638ece7", + "script_key": "02e5cbc75c4d10bf4a7092e1807e8cde32ec60c7d84baab8d4c05999459fd4f547", "group_key": { - "group_key": "03de2df2370e5be5d011225180c5918931076949fee2e1ee7e40600fafcc6e09c5" + "group_key": "032a0a7a44b40879b843df6484605bbe4fee32ccf12778632095aa8a1c6c20ee00" } } } @@ -145,7 +149,7 @@ "genesis_meta_hash": "e4613bb365b2ebb44f0ffb6907136385cdc838f0bdd4c812f042577410aca008", "genesis_output_index": 2531337014, "genesis_type": 0, - "amount": 10114159691898037785, + "amount": 8716283094932373785, "lock_time": 0, "relative_lock_time": 0, "prev_witnesses": [ @@ -156,18 +160,18 @@ "script_key": "022622cb5de340e3b724a50e46aa24eea9dd1041527f130a6a24006707e5e26f15" }, "tx_witness": [ - "1068fbec676f404197ebb4b92816600e5e322a0eb7fa9ddff302d39c16fbb8badf2498fd8fd78db454f26369c2e5cb77376e1462026a8cae98015664b8095714" + "e44eb8c4a6fc1c74ea5cb24a666f06f8b5ff95b9af237410fe7df765fd5c52f2a9de4705c67062dcde16a278d2b22356688c4e2ff62aa24d66ae02f60a843cb9" ], "split_commitment": null }, { "prev_id": { "out_point": "0000000000000000000000000000000000000000000000000000000000000000:0", - "asset_id": "07eb9ccc97b628e77c1ad2edc1b5c09d9d5c69904cdf4c242bc86e06a5352a51", + "asset_id": "2c8a216b276cf82caac3283a63138e3c797c01c6e16d1f2ef43fbb5e86d5577d", "script_key": "020b538161670c27c1aec60995f6b207ffb8fa1cda1f5306783dd0c501ed39622a" }, "tx_witness": [ - "7af559f9fcce2f454aa02ba4e81e4e29b4ac0efad907ebac4ebc9849e425e6e52aa78269bcbc09aabff5d1e74d31c61909af8543d6cb89c070a304c3bb64ff78", + "907cd455532536fc8eac51e906f7a55131f674d8582fb1adf4afd2a506ade63abc34a6b75bf92bc6f873494a048f72a62115609ed76c8cf414b50a6048c3d036", "200716050e6976c3f5f8463da04004e0030827d8c77dd82e188c72c83eb47fb200ad56b2", "c00716050e6976c3f5f8463da04004e0030827d8c77dd82e188c72c83eb47fb200" ], @@ -176,9 +180,9 @@ ], "split_commitment_root": null, "script_version": 0, - "script_key": "02821764c216367a42a490d42158b087682d83d05deb005f6082244b194c73001d", + "script_key": "02a6d09a3efa8b8e06a8978ccd99e73769fdb876cc1ca0407714de3a903ce6b581", "group_key": { - "group_key": "03e0e1e780b217c919674045ee9957ea96eb94a2d8617915f02ec6fa79e88039da" + "group_key": "0243f5b65a13a8bca8f47ace5ee6cafa2e4b76eed7464ec89c7e38ec4ee629049a" } }, "split_set": [], @@ -186,17 +190,17 @@ { "prev_id": { "out_point": "0000000000000000000000000000000000000000000000000000000000000000:0", - "asset_id": "07eb9ccc97b628e77c1ad2edc1b5c09d9d5c69904cdf4c242bc86e06a5352a51", + "asset_id": "2c8a216b276cf82caac3283a63138e3c797c01c6e16d1f2ef43fbb5e86d5577d", "script_key": "020b538161670c27c1aec60995f6b207ffb8fa1cda1f5306783dd0c501ed39622a" }, "asset": { "version": 0, "genesis_first_prev_out": "7acf370641dfb551b042d3d63831661b336077ccd0ac46076870b5f1a9f56921:164677904", - "genesis_tag": "aeb00e40f67aab29332de1448b35507c7c8a09c4db07105dc31003620405da3b", - "genesis_meta_hash": "aeb00e40f67aab29332de1448b35507c7c8a09c4db07105dc31003620405da3b", + "genesis_tag": "6ab00e40f67aab29332de1448b35507c7c8a09c4db07105dc31003620405da3b", + "genesis_meta_hash": "6ab00e40f67aab29332de1448b35507c7c8a09c4db07105dc31003620405da3b", "genesis_output_index": 2349636590, "genesis_type": 0, - "amount": 2662218518393240647, + "amount": 2522543887406335641, "lock_time": 0, "relative_lock_time": 6, "prev_witnesses": [ @@ -214,7 +218,7 @@ "script_version": 0, "script_key": "020b538161670c27c1aec60995f6b207ffb8fa1cda1f5306783dd0c501ed39622a", "group_key": { - "group_key": "027242055ee49eaaaff9968472897f81a90aace0f3a9765995be12a89a9b6f265a" + "group_key": "032d32ce0139ecf52a6b3727228fe9517ec0c5d01f596ef7f24f5cfd8461065d48" } } }, @@ -231,7 +235,7 @@ "genesis_meta_hash": "e4613bb365b2ebb44f0ffb6907136385cdc838f0bdd4c812f042577410aca008", "genesis_output_index": 2531337014, "genesis_type": 0, - "amount": 7451941173504797138, + "amount": 6193739207526038144, "lock_time": 0, "relative_lock_time": 0, "prev_witnesses": [ @@ -249,7 +253,7 @@ "script_version": 0, "script_key": "022622cb5de340e3b724a50e46aa24eea9dd1041527f130a6a24006707e5e26f15", "group_key": { - "group_key": "03e0e1e780b217c919674045ee9957ea96eb94a2d8617915f02ec6fa79e88039da" + "group_key": "0243f5b65a13a8bca8f47ace5ee6cafa2e4b76eed7464ec89c7e38ec4ee629049a" } } } @@ -275,19 +279,19 @@ "script_key": "021285582f1b01b4fc15c14e60f0dc3e431f414585031e3d5719f794861a8e88a8" }, "tx_witness": [ - "791013d77e86011b09b5e2972f6f491b2606331fe23c6d64d876b03c719f42bff774569467623e22da4506886ee751c2aecacf3d70cede73e77f08bf65efdca6" + "793f96f8b94b4edcfec590e5df7cedbb871a0f9d536d571e2e4c576dee0d40168156e7a9ae4f34f0cbf97f2e1aa5dc852eb944a8424e3b5a7884642e20667b9a" ], "split_commitment": null } ], "split_commitment_root": { - "hash": "ba43b19d34de8bbfeceab54b71ea29de7519de2a4d8b6763ec48c8565068de16", + "hash": "0408aeeab9b84db9f894dc206ff8e0091643aef407c097f9259f6af351bd6d1c", "sum": "3" }, "script_version": 0, "script_key": "021285582f1b01b4fc15c14e60f0dc3e431f414585031e3d5719f794861a8e88a8", "group_key": { - "group_key": "02e61a08dbb48e3e72daa796bae5cbd9f65947195dc21e29d273b9cfc5a9d5bd17" + "group_key": "0356423f67480e7c60fa231d4c7846bb50a33c2448d8999c211e0eb13d0285e751" } }, "split_set": [ @@ -318,7 +322,7 @@ }, "tx_witness": null, "split_commitment": { - "proof": "0002c9b1e05942df6951fc6a6edb12c936f3f534084e7488ce9345c268b6dd5424b300000000000000010456ee6e92595303bc7f70fc6cc7adb11fd7581a65ec3d89d221377b33f69a8c0000000000000001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff3f", + "proof": "0002a3674fa7b5d3cf45eab3b4ef026e261cd31df14ef1ebe5cd51490500628efb5900000000000000017579ad6350ba288d09b480e6fb32a31e914f22b08c44cacde64e615d8eaba7660000000000000001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff3f", "root_asset": { "version": 0, "genesis_first_prev_out": "4b45cb188bde77a649ba141d44d256987db903e70ab90059114dd9ae05bf7c9a:628422945", @@ -337,19 +341,19 @@ "script_key": "021285582f1b01b4fc15c14e60f0dc3e431f414585031e3d5719f794861a8e88a8" }, "tx_witness": [ - "791013d77e86011b09b5e2972f6f491b2606331fe23c6d64d876b03c719f42bff774569467623e22da4506886ee751c2aecacf3d70cede73e77f08bf65efdca6" + "793f96f8b94b4edcfec590e5df7cedbb871a0f9d536d571e2e4c576dee0d40168156e7a9ae4f34f0cbf97f2e1aa5dc852eb944a8424e3b5a7884642e20667b9a" ], "split_commitment": null } ], "split_commitment_root": { - "hash": "ba43b19d34de8bbfeceab54b71ea29de7519de2a4d8b6763ec48c8565068de16", + "hash": "0408aeeab9b84db9f894dc206ff8e0091643aef407c097f9259f6af351bd6d1c", "sum": "3" }, "script_version": 0, "script_key": "021285582f1b01b4fc15c14e60f0dc3e431f414585031e3d5719f794861a8e88a8", "group_key": { - "group_key": "02e61a08dbb48e3e72daa796bae5cbd9f65947195dc21e29d273b9cfc5a9d5bd17" + "group_key": "0356423f67480e7c60fa231d4c7846bb50a33c2448d8999c211e0eb13d0285e751" } } } @@ -359,7 +363,7 @@ "script_version": 0, "script_key": "021285582f1b01b4fc15c14e60f0dc3e431f414585031e3d5719f794861a8e88a8", "group_key": { - "group_key": "02e61a08dbb48e3e72daa796bae5cbd9f65947195dc21e29d273b9cfc5a9d5bd17" + "group_key": "0356423f67480e7c60fa231d4c7846bb50a33c2448d8999c211e0eb13d0285e751" } }, "output_index": 0 @@ -369,7 +373,7 @@ "key": { "output_index": 1, "asset_id": "8e1c8248b23efff7dec941debae1163c65796e23e807dc549da31c30ebc62132", - "script_key": "02cf402b0d7efa77997b6d135666d00d71e35121e2b7c3568ff2404db279d26913", + "script_key": "03566f09debfac45e038738be61f4e23fb04829b6cb7be0f8554112ac190f17938", "amount": 1 }, "value": { @@ -392,7 +396,7 @@ }, "tx_witness": null, "split_commitment": { - "proof": "000140d39b3aaf76c4379ec0fc17457bc222aa59cff4c42e7ab46cf46ce8b2c2cb5d0000000000000002ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f", + "proof": "0001b490069a5c30d90d1b4a347985b355e4ee020d8f2de8c988317fa99f329ff90d0000000000000002ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f", "root_asset": { "version": 0, "genesis_first_prev_out": "4b45cb188bde77a649ba141d44d256987db903e70ab90059114dd9ae05bf7c9a:628422945", @@ -411,19 +415,19 @@ "script_key": "021285582f1b01b4fc15c14e60f0dc3e431f414585031e3d5719f794861a8e88a8" }, "tx_witness": [ - "791013d77e86011b09b5e2972f6f491b2606331fe23c6d64d876b03c719f42bff774569467623e22da4506886ee751c2aecacf3d70cede73e77f08bf65efdca6" + "793f96f8b94b4edcfec590e5df7cedbb871a0f9d536d571e2e4c576dee0d40168156e7a9ae4f34f0cbf97f2e1aa5dc852eb944a8424e3b5a7884642e20667b9a" ], "split_commitment": null } ], "split_commitment_root": { - "hash": "ba43b19d34de8bbfeceab54b71ea29de7519de2a4d8b6763ec48c8565068de16", + "hash": "0408aeeab9b84db9f894dc206ff8e0091643aef407c097f9259f6af351bd6d1c", "sum": "3" }, "script_version": 0, "script_key": "021285582f1b01b4fc15c14e60f0dc3e431f414585031e3d5719f794861a8e88a8", "group_key": { - "group_key": "02e61a08dbb48e3e72daa796bae5cbd9f65947195dc21e29d273b9cfc5a9d5bd17" + "group_key": "0356423f67480e7c60fa231d4c7846bb50a33c2448d8999c211e0eb13d0285e751" } } } @@ -431,9 +435,9 @@ ], "split_commitment_root": null, "script_version": 0, - "script_key": "02cf402b0d7efa77997b6d135666d00d71e35121e2b7c3568ff2404db279d26913", + "script_key": "02566f09debfac45e038738be61f4e23fb04829b6cb7be0f8554112ac190f17938", "group_key": { - "group_key": "02e61a08dbb48e3e72daa796bae5cbd9f65947195dc21e29d273b9cfc5a9d5bd17" + "group_key": "0356423f67480e7c60fa231d4c7846bb50a33c2448d8999c211e0eb13d0285e751" } }, "output_index": 1 @@ -466,7 +470,7 @@ }, "tx_witness": null, "split_commitment": { - "proof": "00025d38d673c076277938e36299ca74c8a0982fb9e8ba8a72bc76d3581773e2b0c900000000000000010456ee6e92595303bc7f70fc6cc7adb11fd7581a65ec3d89d221377b33f69a8c0000000000000001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff3f", + "proof": "0002743b9c893739fb623f1df3a843600df9729a94dff8e0446ac189284517bf1d3f00000000000000017579ad6350ba288d09b480e6fb32a31e914f22b08c44cacde64e615d8eaba7660000000000000001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff3f", "root_asset": { "version": 0, "genesis_first_prev_out": "4b45cb188bde77a649ba141d44d256987db903e70ab90059114dd9ae05bf7c9a:628422945", @@ -485,19 +489,19 @@ "script_key": "021285582f1b01b4fc15c14e60f0dc3e431f414585031e3d5719f794861a8e88a8" }, "tx_witness": [ - "791013d77e86011b09b5e2972f6f491b2606331fe23c6d64d876b03c719f42bff774569467623e22da4506886ee751c2aecacf3d70cede73e77f08bf65efdca6" + "793f96f8b94b4edcfec590e5df7cedbb871a0f9d536d571e2e4c576dee0d40168156e7a9ae4f34f0cbf97f2e1aa5dc852eb944a8424e3b5a7884642e20667b9a" ], "split_commitment": null } ], "split_commitment_root": { - "hash": "ba43b19d34de8bbfeceab54b71ea29de7519de2a4d8b6763ec48c8565068de16", + "hash": "0408aeeab9b84db9f894dc206ff8e0091643aef407c097f9259f6af351bd6d1c", "sum": "3" }, "script_version": 0, "script_key": "021285582f1b01b4fc15c14e60f0dc3e431f414585031e3d5719f794861a8e88a8", "group_key": { - "group_key": "02e61a08dbb48e3e72daa796bae5cbd9f65947195dc21e29d273b9cfc5a9d5bd17" + "group_key": "0356423f67480e7c60fa231d4c7846bb50a33c2448d8999c211e0eb13d0285e751" } } } @@ -507,7 +511,7 @@ "script_version": 0, "script_key": "0259c79d57f581060e5f07062f5dd3298834c957b7acafaf2e886aed07360063fd", "group_key": { - "group_key": "02e61a08dbb48e3e72daa796bae5cbd9f65947195dc21e29d273b9cfc5a9d5bd17" + "group_key": "0356423f67480e7c60fa231d4c7846bb50a33c2448d8999c211e0eb13d0285e751" } }, "output_index": 2 @@ -546,7 +550,7 @@ "script_version": 0, "script_key": "021285582f1b01b4fc15c14e60f0dc3e431f414585031e3d5719f794861a8e88a8", "group_key": { - "group_key": "02e61a08dbb48e3e72daa796bae5cbd9f65947195dc21e29d273b9cfc5a9d5bd17" + "group_key": "0356423f67480e7c60fa231d4c7846bb50a33c2448d8999c211e0eb13d0285e751" } } } @@ -572,19 +576,19 @@ "script_key": "0269399b0f788bd21741f6e5badb8f37af257b05503812c5795a1ac52bb6e7d843" }, "tx_witness": [ - "0b463783cc06a8ca684ef81be6f2f87028fb44ed60243f6416ba8001309430b2365e94a7793a8a4371b9e02994dba4b7565f40f919ab2588f99876884e6ce1fb" + "9453d1a5d41cc8734412a0c8f97b151f3331490decc50926fa82d8a2cb0e6749b85c2ea07cbb489e268dfaee992488331ba585a83f98d4b695c4ae50fd5923d3" ], "split_commitment": null } ], "split_commitment_root": { - "hash": "f9a3c8a21d636f9a81de7dce94a28c1da9f79465ceb618fbae6610dc84e2a113", + "hash": "9d3add9bc0fd3712a570cd990f62ef6b86f3f9645090d20222eb1fec3e7fa1ef", "sum": "3" }, "script_version": 0, "script_key": "027c79b9b26e463895eef5679d8558942c86c4ad2233adef01bc3e6d540b3653fe", "group_key": { - "group_key": "0315d5020e23968aebd05fb7fef844f756984f89b7cff52b0a87b14da15944451d" + "group_key": "023dede282e492747aa326aee924076cd1cdc320d779793de394a12caef02bfe8d" } }, "split_set": [ @@ -615,7 +619,7 @@ }, "tx_witness": null, "split_commitment": { - "proof": "0001cbdbec79f8bb69ea4d9b1677acb8fece789af55c49f9f68dffaef940e8f45da00000000000000003ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f", + "proof": "00014d6a221ebc7f519cbbcd8fdb7126922a441d8265cf1dff65a4622a24cd180ce00000000000000003ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f", "root_asset": { "version": 0, "genesis_first_prev_out": "6dcd37451320249dab1e9aa9d428d50f978c8884bc9335b357407fecc269a5aa:3172904479", @@ -634,19 +638,19 @@ "script_key": "0269399b0f788bd21741f6e5badb8f37af257b05503812c5795a1ac52bb6e7d843" }, "tx_witness": [ - "0b463783cc06a8ca684ef81be6f2f87028fb44ed60243f6416ba8001309430b2365e94a7793a8a4371b9e02994dba4b7565f40f919ab2588f99876884e6ce1fb" + "9453d1a5d41cc8734412a0c8f97b151f3331490decc50926fa82d8a2cb0e6749b85c2ea07cbb489e268dfaee992488331ba585a83f98d4b695c4ae50fd5923d3" ], "split_commitment": null } ], "split_commitment_root": { - "hash": "f9a3c8a21d636f9a81de7dce94a28c1da9f79465ceb618fbae6610dc84e2a113", + "hash": "9d3add9bc0fd3712a570cd990f62ef6b86f3f9645090d20222eb1fec3e7fa1ef", "sum": "3" }, "script_version": 0, "script_key": "027c79b9b26e463895eef5679d8558942c86c4ad2233adef01bc3e6d540b3653fe", "group_key": { - "group_key": "0315d5020e23968aebd05fb7fef844f756984f89b7cff52b0a87b14da15944451d" + "group_key": "023dede282e492747aa326aee924076cd1cdc320d779793de394a12caef02bfe8d" } } } @@ -656,7 +660,7 @@ "script_version": 0, "script_key": "027c79b9b26e463895eef5679d8558942c86c4ad2233adef01bc3e6d540b3653fe", "group_key": { - "group_key": "0315d5020e23968aebd05fb7fef844f756984f89b7cff52b0a87b14da15944451d" + "group_key": "023dede282e492747aa326aee924076cd1cdc320d779793de394a12caef02bfe8d" } }, "output_index": 0 @@ -666,7 +670,7 @@ "key": { "output_index": 1, "asset_id": "09c9ab5b33b235f23add6bf646b67062363ed3d3fb281d9a916bb5c0eb55d320", - "script_key": "03e27ddfca263cea98b5d3edca9ecddafba99378d54059fc12d6746921ebf48549", + "script_key": "03563c88b964b5e734f6e46ae6a4b5c2bc1fc8817a37f359c7403e36cc257499db", "amount": 3 }, "value": { @@ -689,7 +693,7 @@ }, "tx_witness": null, "split_commitment": { - "proof": "0001fa0b1587ea8867ae093bb3cf062a108054223a483e94e60cb930e50a836a2c540000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f", + "proof": "0001913db664bbf4c457822eb98dc9a6a689901df9e9f7f44f5e071b63e7498d368b0000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f", "root_asset": { "version": 0, "genesis_first_prev_out": "6dcd37451320249dab1e9aa9d428d50f978c8884bc9335b357407fecc269a5aa:3172904479", @@ -708,19 +712,19 @@ "script_key": "0269399b0f788bd21741f6e5badb8f37af257b05503812c5795a1ac52bb6e7d843" }, "tx_witness": [ - "0b463783cc06a8ca684ef81be6f2f87028fb44ed60243f6416ba8001309430b2365e94a7793a8a4371b9e02994dba4b7565f40f919ab2588f99876884e6ce1fb" + "9453d1a5d41cc8734412a0c8f97b151f3331490decc50926fa82d8a2cb0e6749b85c2ea07cbb489e268dfaee992488331ba585a83f98d4b695c4ae50fd5923d3" ], "split_commitment": null } ], "split_commitment_root": { - "hash": "f9a3c8a21d636f9a81de7dce94a28c1da9f79465ceb618fbae6610dc84e2a113", + "hash": "9d3add9bc0fd3712a570cd990f62ef6b86f3f9645090d20222eb1fec3e7fa1ef", "sum": "3" }, "script_version": 0, "script_key": "027c79b9b26e463895eef5679d8558942c86c4ad2233adef01bc3e6d540b3653fe", "group_key": { - "group_key": "0315d5020e23968aebd05fb7fef844f756984f89b7cff52b0a87b14da15944451d" + "group_key": "023dede282e492747aa326aee924076cd1cdc320d779793de394a12caef02bfe8d" } } } @@ -728,9 +732,9 @@ ], "split_commitment_root": null, "script_version": 0, - "script_key": "02e27ddfca263cea98b5d3edca9ecddafba99378d54059fc12d6746921ebf48549", + "script_key": "02563c88b964b5e734f6e46ae6a4b5c2bc1fc8817a37f359c7403e36cc257499db", "group_key": { - "group_key": "0315d5020e23968aebd05fb7fef844f756984f89b7cff52b0a87b14da15944451d" + "group_key": "023dede282e492747aa326aee924076cd1cdc320d779793de394a12caef02bfe8d" } }, "output_index": 1 @@ -769,7 +773,7 @@ "script_version": 0, "script_key": "0269399b0f788bd21741f6e5badb8f37af257b05503812c5795a1ac52bb6e7d843", "group_key": { - "group_key": "0315d5020e23968aebd05fb7fef844f756984f89b7cff52b0a87b14da15944451d" + "group_key": "023dede282e492747aa326aee924076cd1cdc320d779793de394a12caef02bfe8d" } } } @@ -795,19 +799,19 @@ "script_key": "0225e93954c5acf51b69069f117a08c2e68d69ee7e085f268e33c53625d09f80f5" }, "tx_witness": [ - "ebb2abcdb83b12401f5097add49f130475c6337f8d52fc2e796b429149f1af6e5f011bbad371d42f542c11f5ed9ca6f919c71bfcc76656f1f302ebf93d048255" + "23aa16a912900fdd9513cf4734b7d0bfa37a6902e0dc6163e8685810bfd8267d9515c9389fe9a926111c9e0794d797d938f12b28dd8284ed03f1620466948187" ], "split_commitment": null } ], "split_commitment_root": { - "hash": "d5e75f6f43cfba967510346064f25743814d94bafffe218914656919648af3d9", + "hash": "bf82836b0b830e8f739987682d72ac75bfe8f794a6c6b84d5b790c7f6ae4cef7", "sum": "1" }, "script_version": 0, "script_key": "027c79b9b26e463895eef5679d8558942c86c4ad2233adef01bc3e6d540b3653fe", "group_key": { - "group_key": "0230b5391509f38310934b5fc28d176aa6fbdfd2034ebd0bf1fd47603ad9466b76" + "group_key": "0229a90b13170fa33581af52100ff214e1ea9d4347319f460d642b5450322c405d" } }, "split_set": [ @@ -838,7 +842,7 @@ }, "tx_witness": null, "split_commitment": { - "proof": "0001930bdc3bfda226dcf9ae2ed2ae1f67546592123069ca6d45ef9f720e0a91bf2b0000000000000001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f", + "proof": "00011e3d3c5b1d8ecf617db53584015b9c50e22f794473e052cb622ccea1db4e491a0000000000000001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdf", "root_asset": { "version": 0, "genesis_first_prev_out": "4e9e805321becad4c60f949050cb8638aab4ddb4c6c09fb15b30e866eacd4335:61520613", @@ -857,19 +861,19 @@ "script_key": "0225e93954c5acf51b69069f117a08c2e68d69ee7e085f268e33c53625d09f80f5" }, "tx_witness": [ - "ebb2abcdb83b12401f5097add49f130475c6337f8d52fc2e796b429149f1af6e5f011bbad371d42f542c11f5ed9ca6f919c71bfcc76656f1f302ebf93d048255" + "23aa16a912900fdd9513cf4734b7d0bfa37a6902e0dc6163e8685810bfd8267d9515c9389fe9a926111c9e0794d797d938f12b28dd8284ed03f1620466948187" ], "split_commitment": null } ], "split_commitment_root": { - "hash": "d5e75f6f43cfba967510346064f25743814d94bafffe218914656919648af3d9", + "hash": "bf82836b0b830e8f739987682d72ac75bfe8f794a6c6b84d5b790c7f6ae4cef7", "sum": "1" }, "script_version": 0, "script_key": "027c79b9b26e463895eef5679d8558942c86c4ad2233adef01bc3e6d540b3653fe", "group_key": { - "group_key": "0230b5391509f38310934b5fc28d176aa6fbdfd2034ebd0bf1fd47603ad9466b76" + "group_key": "0229a90b13170fa33581af52100ff214e1ea9d4347319f460d642b5450322c405d" } } } @@ -879,7 +883,7 @@ "script_version": 0, "script_key": "027c79b9b26e463895eef5679d8558942c86c4ad2233adef01bc3e6d540b3653fe", "group_key": { - "group_key": "0230b5391509f38310934b5fc28d176aa6fbdfd2034ebd0bf1fd47603ad9466b76" + "group_key": "0229a90b13170fa33581af52100ff214e1ea9d4347319f460d642b5450322c405d" } }, "output_index": 0 @@ -889,7 +893,7 @@ "key": { "output_index": 1, "asset_id": "4f173cf6c25236c6a677c765cfe069f57e39235037918084b0bb695ef023f03a", - "script_key": "0204458f8b8352d50bf64ed6c92820fbeb22da842b09e78516d75ea62a3568e36e", + "script_key": "03bb7e853950ff36d64079fade9da5150f4db095bc95dd54a4e42ac37722d60cc5", "amount": 1 }, "value": { @@ -912,7 +916,7 @@ }, "tx_witness": null, "split_commitment": { - "proof": "000165b68784e4602d8c89aac2d515dd9f057479efa2f68506153c0b07866218e65b0000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f", + "proof": "000157debb88263c9386c4a1f876fdf8358d3f6f6b6c3d60b776356cb2f08b12cddc0000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdf", "root_asset": { "version": 0, "genesis_first_prev_out": "4e9e805321becad4c60f949050cb8638aab4ddb4c6c09fb15b30e866eacd4335:61520613", @@ -931,19 +935,19 @@ "script_key": "0225e93954c5acf51b69069f117a08c2e68d69ee7e085f268e33c53625d09f80f5" }, "tx_witness": [ - "ebb2abcdb83b12401f5097add49f130475c6337f8d52fc2e796b429149f1af6e5f011bbad371d42f542c11f5ed9ca6f919c71bfcc76656f1f302ebf93d048255" + "23aa16a912900fdd9513cf4734b7d0bfa37a6902e0dc6163e8685810bfd8267d9515c9389fe9a926111c9e0794d797d938f12b28dd8284ed03f1620466948187" ], "split_commitment": null } ], "split_commitment_root": { - "hash": "d5e75f6f43cfba967510346064f25743814d94bafffe218914656919648af3d9", + "hash": "bf82836b0b830e8f739987682d72ac75bfe8f794a6c6b84d5b790c7f6ae4cef7", "sum": "1" }, "script_version": 0, "script_key": "027c79b9b26e463895eef5679d8558942c86c4ad2233adef01bc3e6d540b3653fe", "group_key": { - "group_key": "0230b5391509f38310934b5fc28d176aa6fbdfd2034ebd0bf1fd47603ad9466b76" + "group_key": "0229a90b13170fa33581af52100ff214e1ea9d4347319f460d642b5450322c405d" } } } @@ -951,9 +955,9 @@ ], "split_commitment_root": null, "script_version": 0, - "script_key": "0204458f8b8352d50bf64ed6c92820fbeb22da842b09e78516d75ea62a3568e36e", + "script_key": "02bb7e853950ff36d64079fade9da5150f4db095bc95dd54a4e42ac37722d60cc5", "group_key": { - "group_key": "0230b5391509f38310934b5fc28d176aa6fbdfd2034ebd0bf1fd47603ad9466b76" + "group_key": "0229a90b13170fa33581af52100ff214e1ea9d4347319f460d642b5450322c405d" } }, "output_index": 1 @@ -992,7 +996,7 @@ "script_version": 0, "script_key": "0225e93954c5acf51b69069f117a08c2e68d69ee7e085f268e33c53625d09f80f5", "group_key": { - "group_key": "0230b5391509f38310934b5fc28d176aa6fbdfd2034ebd0bf1fd47603ad9466b76" + "group_key": "0229a90b13170fa33581af52100ff214e1ea9d4347319f460d642b5450322c405d" } } } @@ -1026,13 +1030,13 @@ } ], "split_commitment_root": { - "hash": "975cb06a1db1809777575613d4397a0bca31ebdea9a64cabb04edec37b318967", + "hash": "4383ac3c6938448b013f68ba50aad42803e4f4fd579fb80718c24f2026577325", "sum": "3" }, "script_version": 0, "script_key": "02c974ab0bdb78b718947d967969020de23eb809128a9a90290e7e58386b622f73", "group_key": { - "group_key": "03bd854cd4856c86f71fdad527861f022eb0ff1fb81769d22ab6ce9aaaea50c4e7" + "group_key": "03dfe7b2be064d5f17323748e8bb5d9f5088691dd140b3cc58889bf8cec0afc32a" } }, "split_set": [ @@ -1063,7 +1067,7 @@ }, "tx_witness": null, "split_commitment": { - "proof": "0002700abea8ee8172561b714ae98b5d7fd39041f54ebacd8359c9270b35138dbf620000000000000001903f1d18715e3458ab863e403e4ded7b6440a51911161c7d33d28d1578caf0f00000000000000001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff3f", + "proof": "0002f38320de29357ed4323a06d909530bca1666fb8121e1bbe705fff16a6cd560ae0000000000000001d195f71d9f4425dd60c459e189c98aed36d25609b72ac8d4d0de8f3b736707d00000000000000001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff3f", "root_asset": { "version": 0, "genesis_first_prev_out": "587cb3ad0bb95ff183c471d46cffa2ba517936255aaf95e946278447a4189deb:4085734660", @@ -1090,13 +1094,13 @@ } ], "split_commitment_root": { - "hash": "975cb06a1db1809777575613d4397a0bca31ebdea9a64cabb04edec37b318967", + "hash": "4383ac3c6938448b013f68ba50aad42803e4f4fd579fb80718c24f2026577325", "sum": "3" }, "script_version": 0, "script_key": "02c974ab0bdb78b718947d967969020de23eb809128a9a90290e7e58386b622f73", "group_key": { - "group_key": "03bd854cd4856c86f71fdad527861f022eb0ff1fb81769d22ab6ce9aaaea50c4e7" + "group_key": "03dfe7b2be064d5f17323748e8bb5d9f5088691dd140b3cc58889bf8cec0afc32a" } } } @@ -1106,7 +1110,7 @@ "script_version": 0, "script_key": "02c974ab0bdb78b718947d967969020de23eb809128a9a90290e7e58386b622f73", "group_key": { - "group_key": "03bd854cd4856c86f71fdad527861f022eb0ff1fb81769d22ab6ce9aaaea50c4e7" + "group_key": "03dfe7b2be064d5f17323748e8bb5d9f5088691dd140b3cc58889bf8cec0afc32a" } }, "output_index": 0 @@ -1116,7 +1120,7 @@ "key": { "output_index": 1, "asset_id": "8ab49898ff49a9a3045d752bb2becda7461f135801897b7eb5c5740e8852c43e", - "script_key": "027a17c61fe433aed072dfbecfc2e9877269c8ebf6424dd5da8c98dff2afcb1b16", + "script_key": "0386aae7935e29ad1031a1711678a0e6c44f37bce50c5aa898af66f9386c7eb0cf", "amount": 1 }, "value": { @@ -1139,7 +1143,7 @@ }, "tx_witness": null, "split_commitment": { - "proof": "00026d1f9980a7f04631ceaa085fa7addd19c9b04cddd4cb334b8e4396c34f2e8a620000000000000001903f1d18715e3458ab863e403e4ded7b6440a51911161c7d33d28d1578caf0f00000000000000001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff3f", + "proof": "00024092b772c2dadc642101fc0809226fa5949bb6934766f64908ccd6027b63bec40000000000000001d195f71d9f4425dd60c459e189c98aed36d25609b72ac8d4d0de8f3b736707d00000000000000001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff3f", "root_asset": { "version": 0, "genesis_first_prev_out": "587cb3ad0bb95ff183c471d46cffa2ba517936255aaf95e946278447a4189deb:4085734660", @@ -1166,13 +1170,13 @@ } ], "split_commitment_root": { - "hash": "975cb06a1db1809777575613d4397a0bca31ebdea9a64cabb04edec37b318967", + "hash": "4383ac3c6938448b013f68ba50aad42803e4f4fd579fb80718c24f2026577325", "sum": "3" }, "script_version": 0, "script_key": "02c974ab0bdb78b718947d967969020de23eb809128a9a90290e7e58386b622f73", "group_key": { - "group_key": "03bd854cd4856c86f71fdad527861f022eb0ff1fb81769d22ab6ce9aaaea50c4e7" + "group_key": "03dfe7b2be064d5f17323748e8bb5d9f5088691dd140b3cc58889bf8cec0afc32a" } } } @@ -1180,9 +1184,9 @@ ], "split_commitment_root": null, "script_version": 0, - "script_key": "027a17c61fe433aed072dfbecfc2e9877269c8ebf6424dd5da8c98dff2afcb1b16", + "script_key": "0286aae7935e29ad1031a1711678a0e6c44f37bce50c5aa898af66f9386c7eb0cf", "group_key": { - "group_key": "03bd854cd4856c86f71fdad527861f022eb0ff1fb81769d22ab6ce9aaaea50c4e7" + "group_key": "03dfe7b2be064d5f17323748e8bb5d9f5088691dd140b3cc58889bf8cec0afc32a" } }, "output_index": 1 @@ -1215,7 +1219,7 @@ }, "tx_witness": null, "split_commitment": { - "proof": "0001bfb2815f589b440da9a3c4a788c76daef4c26ceb055585ccca4b482f46368e6f0000000000000002ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f", + "proof": "00017c300c1f826d9761d2241224380db0fccdcd928a1d2ee30a661c14775219abcb0000000000000002ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f", "root_asset": { "version": 0, "genesis_first_prev_out": "587cb3ad0bb95ff183c471d46cffa2ba517936255aaf95e946278447a4189deb:4085734660", @@ -1242,13 +1246,13 @@ } ], "split_commitment_root": { - "hash": "975cb06a1db1809777575613d4397a0bca31ebdea9a64cabb04edec37b318967", + "hash": "4383ac3c6938448b013f68ba50aad42803e4f4fd579fb80718c24f2026577325", "sum": "3" }, "script_version": 0, "script_key": "02c974ab0bdb78b718947d967969020de23eb809128a9a90290e7e58386b622f73", "group_key": { - "group_key": "03bd854cd4856c86f71fdad527861f022eb0ff1fb81769d22ab6ce9aaaea50c4e7" + "group_key": "03dfe7b2be064d5f17323748e8bb5d9f5088691dd140b3cc58889bf8cec0afc32a" } } } @@ -1258,7 +1262,7 @@ "script_version": 0, "script_key": "02e2f26dab9bea4f11b71f0ae0dfb36f4d8800195de92b29f120847b707c0ae12d", "group_key": { - "group_key": "03bd854cd4856c86f71fdad527861f022eb0ff1fb81769d22ab6ce9aaaea50c4e7" + "group_key": "03dfe7b2be064d5f17323748e8bb5d9f5088691dd140b3cc58889bf8cec0afc32a" } }, "output_index": 2 @@ -1297,7 +1301,7 @@ "script_version": 0, "script_key": "02c974ab0bdb78b718947d967969020de23eb809128a9a90290e7e58386b622f73", "group_key": { - "group_key": "03bd854cd4856c86f71fdad527861f022eb0ff1fb81769d22ab6ce9aaaea50c4e7" + "group_key": "03dfe7b2be064d5f17323748e8bb5d9f5088691dd140b3cc58889bf8cec0afc32a" } } } @@ -1323,7 +1327,7 @@ "script_key": "026e8f12fb008b1336754e1a6d6b2db5ae0369e470b2c47f71ab2a8c261fa0d777" }, "tx_witness": [ - "ced06fd90a52ae382da9221d0118a32c52c8af0dabc1a78347df43fc6071ba9d1394494684e1877bd05ebf2ddfc802531d7787185a51ca5efef961e640b84a15", + "ded23afeae5b366c064f0f26883ba090131c77a654c395ac11827b298dc85dc8207529ec2e69f1b5df74b8dd9898fd033d91e68d92261b7b516de954fd942bec", "201421a21d4497ac25a935dfd40a92b1fa71a3bbdd0e09e791e08c947f3b7153a0ac", "c01421a21d4497ac25a935dfd40a92b1fa71a3bbdd0e09e791e08c947f3b7153a06c2e4bb01e316abaaee288d69c06cc608cedefd6e1a06813786c4ec51b6e1d38" ], @@ -1331,13 +1335,13 @@ } ], "split_commitment_root": { - "hash": "0c5759f9a732e114601d469b64f95945e7debb2ce7a8f39d4639803c674244e5", + "hash": "1bdc5deada60cb410932ecb1a560b3014b7750b4cb2fd93f3ff7b3be3b6e2d02", "sum": "3" }, "script_version": 0, "script_key": "026e8f12fb008b1336754e1a6d6b2db5ae0369e470b2c47f71ab2a8c261fa0d777", "group_key": { - "group_key": "03443a015f1061f28a59d7f303f899fad9e7af87b60ccb7dda073f4696a4133ca1" + "group_key": "03b4e3c3b62f93d96dab9ac5f02cf58cc8a033a0e060f170af2f038716e4a62933" } }, "split_set": [ @@ -1368,7 +1372,7 @@ }, "tx_witness": null, "split_commitment": { - "proof": "00028eaaf701833e44a723d55552ffa98d6f4173580e85d3adbaf5f6cd6a67a5b0790000000000000001a8a095b337c47c91dcac9d11594dc3fab9f745caf10da2ff5bdc3d62fab3adc70000000000000001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff77", + "proof": "00020d7ed2d344fd5d2a81903d12775a630aaeb878c1ed95eda894df535de65702c80000000000000001b0546218967d4b9e61bd99e459faed2ed1159a02ef64dc5c24221ea38a028dd90000000000000001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff5f", "root_asset": { "version": 0, "genesis_first_prev_out": "0fd6e47989c16725fd3d7f3ba6f606f665a6a780ea967cd7101f46e83699caf3:1938516009", @@ -1387,7 +1391,7 @@ "script_key": "026e8f12fb008b1336754e1a6d6b2db5ae0369e470b2c47f71ab2a8c261fa0d777" }, "tx_witness": [ - "ced06fd90a52ae382da9221d0118a32c52c8af0dabc1a78347df43fc6071ba9d1394494684e1877bd05ebf2ddfc802531d7787185a51ca5efef961e640b84a15", + "ded23afeae5b366c064f0f26883ba090131c77a654c395ac11827b298dc85dc8207529ec2e69f1b5df74b8dd9898fd033d91e68d92261b7b516de954fd942bec", "201421a21d4497ac25a935dfd40a92b1fa71a3bbdd0e09e791e08c947f3b7153a0ac", "c01421a21d4497ac25a935dfd40a92b1fa71a3bbdd0e09e791e08c947f3b7153a06c2e4bb01e316abaaee288d69c06cc608cedefd6e1a06813786c4ec51b6e1d38" ], @@ -1395,13 +1399,13 @@ } ], "split_commitment_root": { - "hash": "0c5759f9a732e114601d469b64f95945e7debb2ce7a8f39d4639803c674244e5", + "hash": "1bdc5deada60cb410932ecb1a560b3014b7750b4cb2fd93f3ff7b3be3b6e2d02", "sum": "3" }, "script_version": 0, "script_key": "026e8f12fb008b1336754e1a6d6b2db5ae0369e470b2c47f71ab2a8c261fa0d777", "group_key": { - "group_key": "03443a015f1061f28a59d7f303f899fad9e7af87b60ccb7dda073f4696a4133ca1" + "group_key": "03b4e3c3b62f93d96dab9ac5f02cf58cc8a033a0e060f170af2f038716e4a62933" } } } @@ -1411,7 +1415,7 @@ "script_version": 0, "script_key": "026e8f12fb008b1336754e1a6d6b2db5ae0369e470b2c47f71ab2a8c261fa0d777", "group_key": { - "group_key": "03443a015f1061f28a59d7f303f899fad9e7af87b60ccb7dda073f4696a4133ca1" + "group_key": "03b4e3c3b62f93d96dab9ac5f02cf58cc8a033a0e060f170af2f038716e4a62933" } }, "output_index": 0 @@ -1421,7 +1425,7 @@ "key": { "output_index": 1, "asset_id": "bd2652c2f9fc304733f34f211331a49f5e87b3848a7486a2820b010653d6ad57", - "script_key": "0366e3690d91744e1cada4c1821204486e6fd80e63d12a3527973d6cd4e3beda31", + "script_key": "0389c073e999240684ad7e186907d63476a547c44a3c29816eae8ceecff9522c85", "amount": 1 }, "value": { @@ -1444,7 +1448,7 @@ }, "tx_witness": null, "split_commitment": { - "proof": "0002b892956c2c6042f0174924d9f20e98dbe50ddb476688b0dca2957c3559f5a5650000000000000001a8a095b337c47c91dcac9d11594dc3fab9f745caf10da2ff5bdc3d62fab3adc70000000000000001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff77", + "proof": "0002eb8d24dcef4634cc900fa6e009ddff9203f8393fa2be699389e36730d3f4966e0000000000000001b0546218967d4b9e61bd99e459faed2ed1159a02ef64dc5c24221ea38a028dd90000000000000001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff5f", "root_asset": { "version": 0, "genesis_first_prev_out": "0fd6e47989c16725fd3d7f3ba6f606f665a6a780ea967cd7101f46e83699caf3:1938516009", @@ -1463,7 +1467,7 @@ "script_key": "026e8f12fb008b1336754e1a6d6b2db5ae0369e470b2c47f71ab2a8c261fa0d777" }, "tx_witness": [ - "ced06fd90a52ae382da9221d0118a32c52c8af0dabc1a78347df43fc6071ba9d1394494684e1877bd05ebf2ddfc802531d7787185a51ca5efef961e640b84a15", + "ded23afeae5b366c064f0f26883ba090131c77a654c395ac11827b298dc85dc8207529ec2e69f1b5df74b8dd9898fd033d91e68d92261b7b516de954fd942bec", "201421a21d4497ac25a935dfd40a92b1fa71a3bbdd0e09e791e08c947f3b7153a0ac", "c01421a21d4497ac25a935dfd40a92b1fa71a3bbdd0e09e791e08c947f3b7153a06c2e4bb01e316abaaee288d69c06cc608cedefd6e1a06813786c4ec51b6e1d38" ], @@ -1471,13 +1475,13 @@ } ], "split_commitment_root": { - "hash": "0c5759f9a732e114601d469b64f95945e7debb2ce7a8f39d4639803c674244e5", + "hash": "1bdc5deada60cb410932ecb1a560b3014b7750b4cb2fd93f3ff7b3be3b6e2d02", "sum": "3" }, "script_version": 0, "script_key": "026e8f12fb008b1336754e1a6d6b2db5ae0369e470b2c47f71ab2a8c261fa0d777", "group_key": { - "group_key": "03443a015f1061f28a59d7f303f899fad9e7af87b60ccb7dda073f4696a4133ca1" + "group_key": "03b4e3c3b62f93d96dab9ac5f02cf58cc8a033a0e060f170af2f038716e4a62933" } } } @@ -1485,9 +1489,9 @@ ], "split_commitment_root": null, "script_version": 0, - "script_key": "0266e3690d91744e1cada4c1821204486e6fd80e63d12a3527973d6cd4e3beda31", + "script_key": "0289c073e999240684ad7e186907d63476a547c44a3c29816eae8ceecff9522c85", "group_key": { - "group_key": "03443a015f1061f28a59d7f303f899fad9e7af87b60ccb7dda073f4696a4133ca1" + "group_key": "03b4e3c3b62f93d96dab9ac5f02cf58cc8a033a0e060f170af2f038716e4a62933" } }, "output_index": 1 @@ -1520,7 +1524,7 @@ }, "tx_witness": null, "split_commitment": { - "proof": "00010ccb002b981a283e35c4c6f0f9c7c2c7726516981ad1a2d6cc64d81dfae68f300000000000000002ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f", + "proof": "000189886b5067db8c87b6954febdc85e9f4d109f77c2438ba58f65f58ae839e785e0000000000000002ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f", "root_asset": { "version": 0, "genesis_first_prev_out": "0fd6e47989c16725fd3d7f3ba6f606f665a6a780ea967cd7101f46e83699caf3:1938516009", @@ -1539,7 +1543,7 @@ "script_key": "026e8f12fb008b1336754e1a6d6b2db5ae0369e470b2c47f71ab2a8c261fa0d777" }, "tx_witness": [ - "ced06fd90a52ae382da9221d0118a32c52c8af0dabc1a78347df43fc6071ba9d1394494684e1877bd05ebf2ddfc802531d7787185a51ca5efef961e640b84a15", + "ded23afeae5b366c064f0f26883ba090131c77a654c395ac11827b298dc85dc8207529ec2e69f1b5df74b8dd9898fd033d91e68d92261b7b516de954fd942bec", "201421a21d4497ac25a935dfd40a92b1fa71a3bbdd0e09e791e08c947f3b7153a0ac", "c01421a21d4497ac25a935dfd40a92b1fa71a3bbdd0e09e791e08c947f3b7153a06c2e4bb01e316abaaee288d69c06cc608cedefd6e1a06813786c4ec51b6e1d38" ], @@ -1547,13 +1551,13 @@ } ], "split_commitment_root": { - "hash": "0c5759f9a732e114601d469b64f95945e7debb2ce7a8f39d4639803c674244e5", + "hash": "1bdc5deada60cb410932ecb1a560b3014b7750b4cb2fd93f3ff7b3be3b6e2d02", "sum": "3" }, "script_version": 0, "script_key": "026e8f12fb008b1336754e1a6d6b2db5ae0369e470b2c47f71ab2a8c261fa0d777", "group_key": { - "group_key": "03443a015f1061f28a59d7f303f899fad9e7af87b60ccb7dda073f4696a4133ca1" + "group_key": "03b4e3c3b62f93d96dab9ac5f02cf58cc8a033a0e060f170af2f038716e4a62933" } } } @@ -1563,7 +1567,7 @@ "script_version": 0, "script_key": "020d3dae21750b7f324c666a37fd039ddac56e646a81790f73edb8e792f133be10", "group_key": { - "group_key": "03443a015f1061f28a59d7f303f899fad9e7af87b60ccb7dda073f4696a4133ca1" + "group_key": "03b4e3c3b62f93d96dab9ac5f02cf58cc8a033a0e060f170af2f038716e4a62933" } }, "output_index": 2 @@ -1602,7 +1606,7 @@ "script_version": 0, "script_key": "026e8f12fb008b1336754e1a6d6b2db5ae0369e470b2c47f71ab2a8c261fa0d777", "group_key": { - "group_key": "03443a015f1061f28a59d7f303f899fad9e7af87b60ccb7dda073f4696a4133ca1" + "group_key": "03b4e3c3b62f93d96dab9ac5f02cf58cc8a033a0e060f170af2f038716e4a62933" } } } @@ -1628,7 +1632,7 @@ "script_key": "023a1a8108438e6f94b2a53601824a75d195a8588de4ad89cc741eb2c830d8397c" }, "tx_witness": [ - "14f9a6b6cfb456656573ce4ceab3691532661484a2d307f54a34f38b37a144d9ab790f60c91f48220525ab24c2484ef3e381958662b9e92c7bd7f42fe83834fd03", + "09c796dd71c21dc1943224b09cb057e3189cda85fb59c08543791f2577369b9731ef94fdc30546c248274ca1c753f82081228e7482dcf7f3e55bf1b3c8be22e203", "20ddab68e5ceee87aad748779a268f9f5e6f4d7eae97e3ec73b3255868f68e9142ac", "c1ddab68e5ceee87aad748779a268f9f5e6f4d7eae97e3ec73b3255868f68e91426c2e4bb01e316abaaee288d69c06cc608cedefd6e1a06813786c4ec51b6e1d38" ], @@ -1636,13 +1640,13 @@ } ], "split_commitment_root": { - "hash": "05c0fa754e278f0023b801959550beda7fec42eba9a8c932181627cb808699f3", + "hash": "75684f0ae8ceb0ced79412654cbbebf2d13750779c54829eaad0d70b448a32fe", "sum": "3" }, "script_version": 0, "script_key": "023a1a8108438e6f94b2a53601824a75d195a8588de4ad89cc741eb2c830d8397c", "group_key": { - "group_key": "031d02abedcd8d65866caf476c44847ef93e118b53528dd8d078fcaddd5e4390d8" + "group_key": "03ee90de7dfb2d618ad3caeb8e46bfdeeb8f955116d2388362f852742998a5de55" } }, "split_set": [ @@ -1673,7 +1677,7 @@ }, "tx_witness": null, "split_commitment": { - "proof": "0002359b9011b1ebeb1fa43b120f004cd8f6a7d12afcc9c73ce951c676df645aa7f20000000000000001e61dab95aeacb923cacb86f1c684d71193bea07a506b0cfeeb6241440813f5e30000000000000001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff3f", + "proof": "0002107f02d78e8a31f5b3c918b0877e43b0c25d86f1dce112e89e45ead4f171e6700000000000000001fd7fae7130d61fd754160f1ad9f47031c0dd4bdf81b9e96989e98f264051b1d60000000000000001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9f", "root_asset": { "version": 0, "genesis_first_prev_out": "4eef7a2694763d55cb471941e52ad269fd8e5f04756b36dbc9b344e9ab3641fe:3098759927", @@ -1692,7 +1696,7 @@ "script_key": "023a1a8108438e6f94b2a53601824a75d195a8588de4ad89cc741eb2c830d8397c" }, "tx_witness": [ - "14f9a6b6cfb456656573ce4ceab3691532661484a2d307f54a34f38b37a144d9ab790f60c91f48220525ab24c2484ef3e381958662b9e92c7bd7f42fe83834fd03", + "09c796dd71c21dc1943224b09cb057e3189cda85fb59c08543791f2577369b9731ef94fdc30546c248274ca1c753f82081228e7482dcf7f3e55bf1b3c8be22e203", "20ddab68e5ceee87aad748779a268f9f5e6f4d7eae97e3ec73b3255868f68e9142ac", "c1ddab68e5ceee87aad748779a268f9f5e6f4d7eae97e3ec73b3255868f68e91426c2e4bb01e316abaaee288d69c06cc608cedefd6e1a06813786c4ec51b6e1d38" ], @@ -1700,13 +1704,13 @@ } ], "split_commitment_root": { - "hash": "05c0fa754e278f0023b801959550beda7fec42eba9a8c932181627cb808699f3", + "hash": "75684f0ae8ceb0ced79412654cbbebf2d13750779c54829eaad0d70b448a32fe", "sum": "3" }, "script_version": 0, "script_key": "023a1a8108438e6f94b2a53601824a75d195a8588de4ad89cc741eb2c830d8397c", "group_key": { - "group_key": "031d02abedcd8d65866caf476c44847ef93e118b53528dd8d078fcaddd5e4390d8" + "group_key": "03ee90de7dfb2d618ad3caeb8e46bfdeeb8f955116d2388362f852742998a5de55" } } } @@ -1716,7 +1720,7 @@ "script_version": 0, "script_key": "023a1a8108438e6f94b2a53601824a75d195a8588de4ad89cc741eb2c830d8397c", "group_key": { - "group_key": "031d02abedcd8d65866caf476c44847ef93e118b53528dd8d078fcaddd5e4390d8" + "group_key": "03ee90de7dfb2d618ad3caeb8e46bfdeeb8f955116d2388362f852742998a5de55" } }, "output_index": 0 @@ -1726,7 +1730,7 @@ "key": { "output_index": 1, "asset_id": "ee4746099aeff101107f54bc7d2ee1eaaa0c9edc36aa5ed73a7a77f87418d008", - "script_key": "03344d086dc72a58b4da320b955f6461dde961217482d6f906946b88f85e94d96c", + "script_key": "03844584de356cd25ce99f52829a1d71fbca9f03cb8ed754e3205dde126f7bfa7b", "amount": 1 }, "value": { @@ -1749,7 +1753,7 @@ }, "tx_witness": null, "split_commitment": { - "proof": "00019d05a8f38dde01c90cf63be6dcecf64e8f1047fee365f80d7bb1eed3b8b659920000000000000002ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f", + "proof": "0002ad4b6ced62c83d8a1e69cef3184c2fde8effc397f3d6455a8394b736dea470360000000000000001fd7fae7130d61fd754160f1ad9f47031c0dd4bdf81b9e96989e98f264051b1d60000000000000001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9f", "root_asset": { "version": 0, "genesis_first_prev_out": "4eef7a2694763d55cb471941e52ad269fd8e5f04756b36dbc9b344e9ab3641fe:3098759927", @@ -1768,7 +1772,7 @@ "script_key": "023a1a8108438e6f94b2a53601824a75d195a8588de4ad89cc741eb2c830d8397c" }, "tx_witness": [ - "14f9a6b6cfb456656573ce4ceab3691532661484a2d307f54a34f38b37a144d9ab790f60c91f48220525ab24c2484ef3e381958662b9e92c7bd7f42fe83834fd03", + "09c796dd71c21dc1943224b09cb057e3189cda85fb59c08543791f2577369b9731ef94fdc30546c248274ca1c753f82081228e7482dcf7f3e55bf1b3c8be22e203", "20ddab68e5ceee87aad748779a268f9f5e6f4d7eae97e3ec73b3255868f68e9142ac", "c1ddab68e5ceee87aad748779a268f9f5e6f4d7eae97e3ec73b3255868f68e91426c2e4bb01e316abaaee288d69c06cc608cedefd6e1a06813786c4ec51b6e1d38" ], @@ -1776,13 +1780,13 @@ } ], "split_commitment_root": { - "hash": "05c0fa754e278f0023b801959550beda7fec42eba9a8c932181627cb808699f3", + "hash": "75684f0ae8ceb0ced79412654cbbebf2d13750779c54829eaad0d70b448a32fe", "sum": "3" }, "script_version": 0, "script_key": "023a1a8108438e6f94b2a53601824a75d195a8588de4ad89cc741eb2c830d8397c", "group_key": { - "group_key": "031d02abedcd8d65866caf476c44847ef93e118b53528dd8d078fcaddd5e4390d8" + "group_key": "03ee90de7dfb2d618ad3caeb8e46bfdeeb8f955116d2388362f852742998a5de55" } } } @@ -1790,9 +1794,9 @@ ], "split_commitment_root": null, "script_version": 0, - "script_key": "02344d086dc72a58b4da320b955f6461dde961217482d6f906946b88f85e94d96c", + "script_key": "02844584de356cd25ce99f52829a1d71fbca9f03cb8ed754e3205dde126f7bfa7b", "group_key": { - "group_key": "031d02abedcd8d65866caf476c44847ef93e118b53528dd8d078fcaddd5e4390d8" + "group_key": "03ee90de7dfb2d618ad3caeb8e46bfdeeb8f955116d2388362f852742998a5de55" } }, "output_index": 1 @@ -1825,7 +1829,7 @@ }, "tx_witness": null, "split_commitment": { - "proof": "000205cbf73ce24aab12cc0e0bb0dea9dd4ee5b8b2b64998ee47817517030270151c0000000000000001e61dab95aeacb923cacb86f1c684d71193bea07a506b0cfeeb6241440813f5e30000000000000001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff3f", + "proof": "0001177d52484867c2e202828baf8244120f618d4eb12b3025ab4c52cb4184ebd6510000000000000002ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbf", "root_asset": { "version": 0, "genesis_first_prev_out": "4eef7a2694763d55cb471941e52ad269fd8e5f04756b36dbc9b344e9ab3641fe:3098759927", @@ -1844,7 +1848,7 @@ "script_key": "023a1a8108438e6f94b2a53601824a75d195a8588de4ad89cc741eb2c830d8397c" }, "tx_witness": [ - "14f9a6b6cfb456656573ce4ceab3691532661484a2d307f54a34f38b37a144d9ab790f60c91f48220525ab24c2484ef3e381958662b9e92c7bd7f42fe83834fd03", + "09c796dd71c21dc1943224b09cb057e3189cda85fb59c08543791f2577369b9731ef94fdc30546c248274ca1c753f82081228e7482dcf7f3e55bf1b3c8be22e203", "20ddab68e5ceee87aad748779a268f9f5e6f4d7eae97e3ec73b3255868f68e9142ac", "c1ddab68e5ceee87aad748779a268f9f5e6f4d7eae97e3ec73b3255868f68e91426c2e4bb01e316abaaee288d69c06cc608cedefd6e1a06813786c4ec51b6e1d38" ], @@ -1852,13 +1856,13 @@ } ], "split_commitment_root": { - "hash": "05c0fa754e278f0023b801959550beda7fec42eba9a8c932181627cb808699f3", + "hash": "75684f0ae8ceb0ced79412654cbbebf2d13750779c54829eaad0d70b448a32fe", "sum": "3" }, "script_version": 0, "script_key": "023a1a8108438e6f94b2a53601824a75d195a8588de4ad89cc741eb2c830d8397c", "group_key": { - "group_key": "031d02abedcd8d65866caf476c44847ef93e118b53528dd8d078fcaddd5e4390d8" + "group_key": "03ee90de7dfb2d618ad3caeb8e46bfdeeb8f955116d2388362f852742998a5de55" } } } @@ -1868,7 +1872,7 @@ "script_version": 0, "script_key": "028ba8afafd51afa7a2b5cfffd6517a2f8762b607389967c0ba3fde5641e2d254a", "group_key": { - "group_key": "031d02abedcd8d65866caf476c44847ef93e118b53528dd8d078fcaddd5e4390d8" + "group_key": "03ee90de7dfb2d618ad3caeb8e46bfdeeb8f955116d2388362f852742998a5de55" } }, "output_index": 2 @@ -1907,7 +1911,7 @@ "script_version": 0, "script_key": "023a1a8108438e6f94b2a53601824a75d195a8588de4ad89cc741eb2c830d8397c", "group_key": { - "group_key": "031d02abedcd8d65866caf476c44847ef93e118b53528dd8d078fcaddd5e4390d8" + "group_key": "03ee90de7dfb2d618ad3caeb8e46bfdeeb8f955116d2388362f852742998a5de55" } } } diff --git a/vm/testdata/vm_validation_generated_error_cases.json b/vm/testdata/vm_validation_generated_error_cases.json index 5fe43ee3d..9f7c58894 100644 --- a/vm/testdata/vm_validation_generated_error_cases.json +++ b/vm/testdata/vm_validation_generated_error_cases.json @@ -5,8 +5,8 @@ "asset": { "version": 0, "genesis_first_prev_out": "b73c32ed8c4694a54af747ed64e9bcd44eb4a44786139efcca7d8ebf3da5475c:196162024", - "genesis_tag": "2887aa113b9ca740f80c9382d9c6034ad2960c796503e1ce221725f50caf1fbf", - "genesis_meta_hash": "2887aa113b9ca740f80c9382d9c6034ad2960c796503e1ce221725f50caf1fbf", + "genesis_tag": "8928d5a23b9ca740f80c9382d9c6034ad2960c796503e1ce221725f50caf1fbf", + "genesis_meta_hash": "8928d5a23b9ca740f80c9382d9c6034ad2960c796503e1ce221725f50caf1fbf", "genesis_output_index": 2674673580, "genesis_type": 1, "amount": 1, @@ -19,15 +19,17 @@ "asset_id": "0000000000000000000000000000000000000000000000000000000000000000", "script_key": "000000000000000000000000000000000000000000000000000000000000000000" }, - "tx_witness": null, + "tx_witness": [ + "cd189bee8e75aa0021d0f324d461f3083af5843726f913fa62ce2b73aed62e189e0e33d815714bed7b4b51e6c1495d2bdce29717389d89afa260ef6bb2b96696" + ], "split_commitment": null } ], "split_commitment_root": null, "script_version": 0, - "script_key": "021696b75f70dadd6efbbd05e7ebd5fc5e07d58b123846c68c9673c14b62d538c8", + "script_key": "02e1c7468afddf5a26c9dd63e45ccd73e452cdc1d8799e3290316e7ae56ab957a9", "group_key": { - "group_key": "03ca714fcfc937a0eaec53f666ba88166f6f115a87357f19314d18f0e1a23d1ee7" + "group_key": "02bfe975fcfe32d6f87307f3457e5e28e266adc4f975c5db45fa8049894b092b63" } }, "split_set": [], @@ -41,8 +43,8 @@ "asset": { "version": 0, "genesis_first_prev_out": "b73c32ed8c4694a54af747ed64e9bcd44eb4a44786139efcca7d8ebf3da5475c:196162024", - "genesis_tag": "2887aa113b9ca740f80c9382d9c6034ad2960c796503e1ce221725f50caf1fbf", - "genesis_meta_hash": "2887aa113b9ca740f80c9382d9c6034ad2960c796503e1ce221725f50caf1fbf", + "genesis_tag": "8928d5a23b9ca740f80c9382d9c6034ad2960c796503e1ce221725f50caf1fbf", + "genesis_meta_hash": "8928d5a23b9ca740f80c9382d9c6034ad2960c796503e1ce221725f50caf1fbf", "genesis_output_index": 2674673580, "genesis_type": 1, "amount": 1, @@ -55,15 +57,17 @@ "asset_id": "0000000000000000000000000000000000000000000000000000000000000000", "script_key": "000000000000000000000000000000000000000000000000000000000000000000" }, - "tx_witness": null, + "tx_witness": [ + "cd189bee8e75aa0021d0f324d461f3083af5843726f913fa62ce2b73aed62e189e0e33d815714bed7b4b51e6c1495d2bdce29717389d89afa260ef6bb2b96696" + ], "split_commitment": null } ], "split_commitment_root": null, "script_version": 0, - "script_key": "021696b75f70dadd6efbbd05e7ebd5fc5e07d58b123846c68c9673c14b62d538c8", + "script_key": "02e1c7468afddf5a26c9dd63e45ccd73e452cdc1d8799e3290316e7ae56ab957a9", "group_key": { - "group_key": "03ca714fcfc937a0eaec53f666ba88166f6f115a87357f19314d18f0e1a23d1ee7" + "group_key": "02bfe975fcfe32d6f87307f3457e5e28e266adc4f975c5db45fa8049894b092b63" } } } @@ -87,22 +91,22 @@ "prev_id": { "out_point": "0000000000000000000000000000000000000000000000000000000000000000:0", "asset_id": "5bd514450208479701c49b5441a87c652b41b5d9decb2c508149b4596061d51f", - "script_key": "027a6109322820fe97863ad62d579f8393fa058cc8e60300233bb816fc0941f520" + "script_key": "02b3270194556867c9a3a70b54df62b7ebbb070d0d9868d0f64b784658d6c241fb" }, "tx_witness": [ - "74b70328f8c57342af89669f6370a4338047c419af612cb6858f06ed5e6542d37dcc9547fbfd0b9f6531726ca8e3914f5e9a0b2bd99df1ca213a181d6b3aba8f" + "73f715f54560d5f42f0e367854c1597eb26e4b15b449257515e892171191e59e824a17111eca21d5f2bf7249fdbc644e87d882d2320ea3763b7b6bbbcedee8ba" ], "split_commitment": null } ], "split_commitment_root": { - "hash": "51c2570532bfe1831c75b9706c801c1d46fb9e0e9dccc8d6f3ad101704239af8", + "hash": "75b1b63f19108940bea7b1e99c69e915e5cacfc587cbe6c5f55657684a2b1ba8", "sum": "1" }, "script_version": 0, "script_key": "027c79b9b26e463895eef5679d8558942c86c4ad2233adef01bc3e6d540b3653fe", "group_key": { - "group_key": "03316168dcae498b33518be40890ab1c4aced753c456e3886abda5bd14297752a5" + "group_key": "02d873b3ac2e180ab3c0854a2f8e470c433a709b6a79aef381dc2fb26b9c458a49" } }, "split_set": [ @@ -133,7 +137,7 @@ }, "tx_witness": null, "split_commitment": { - "proof": "00011d6698add8b0b1b4d7cdcc8ef378bbe5b7ebabd7d3e914c89fb8b691ebdd08f70000000000000001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbf", + "proof": "00010ebf02020a470a9a10dede60fc52c1be094e13c1394c294258631510dc48910a0000000000000001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbf", "root_asset": { "version": 0, "genesis_first_prev_out": "3b6bd9c19e7792417fc335327a49f6d261a82947a67e52b1a000e8cb4409507b:83480210", @@ -149,22 +153,22 @@ "prev_id": { "out_point": "0000000000000000000000000000000000000000000000000000000000000000:0", "asset_id": "5bd514450208479701c49b5441a87c652b41b5d9decb2c508149b4596061d51f", - "script_key": "027a6109322820fe97863ad62d579f8393fa058cc8e60300233bb816fc0941f520" + "script_key": "02b3270194556867c9a3a70b54df62b7ebbb070d0d9868d0f64b784658d6c241fb" }, "tx_witness": [ - "74b70328f8c57342af89669f6370a4338047c419af612cb6858f06ed5e6542d37dcc9547fbfd0b9f6531726ca8e3914f5e9a0b2bd99df1ca213a181d6b3aba8f" + "73f715f54560d5f42f0e367854c1597eb26e4b15b449257515e892171191e59e824a17111eca21d5f2bf7249fdbc644e87d882d2320ea3763b7b6bbbcedee8ba" ], "split_commitment": null } ], "split_commitment_root": { - "hash": "51c2570532bfe1831c75b9706c801c1d46fb9e0e9dccc8d6f3ad101704239af8", + "hash": "75b1b63f19108940bea7b1e99c69e915e5cacfc587cbe6c5f55657684a2b1ba8", "sum": "1" }, "script_version": 0, "script_key": "027c79b9b26e463895eef5679d8558942c86c4ad2233adef01bc3e6d540b3653fe", "group_key": { - "group_key": "03316168dcae498b33518be40890ab1c4aced753c456e3886abda5bd14297752a5" + "group_key": "02d873b3ac2e180ab3c0854a2f8e470c433a709b6a79aef381dc2fb26b9c458a49" } } } @@ -174,7 +178,7 @@ "script_version": 0, "script_key": "027c79b9b26e463895eef5679d8558942c86c4ad2233adef01bc3e6d540b3653fe", "group_key": { - "group_key": "03316168dcae498b33518be40890ab1c4aced753c456e3886abda5bd14297752a5" + "group_key": "02d873b3ac2e180ab3c0854a2f8e470c433a709b6a79aef381dc2fb26b9c458a49" } }, "output_index": 0 @@ -207,7 +211,7 @@ }, "tx_witness": null, "split_commitment": { - "proof": "00015e2b476dc43965e327ab8f3741e9864af101fa24af24f51ce25968c57534f6790000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbf", + "proof": "0001721a01971cfde174c4dfb8e7ea8347d5c1ca9778555baaff9ff083dafc137f8e0000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbf", "root_asset": { "version": 0, "genesis_first_prev_out": "3b6bd9c19e7792417fc335327a49f6d261a82947a67e52b1a000e8cb4409507b:83480210", @@ -223,22 +227,22 @@ "prev_id": { "out_point": "0000000000000000000000000000000000000000000000000000000000000000:0", "asset_id": "5bd514450208479701c49b5441a87c652b41b5d9decb2c508149b4596061d51f", - "script_key": "027a6109322820fe97863ad62d579f8393fa058cc8e60300233bb816fc0941f520" + "script_key": "02b3270194556867c9a3a70b54df62b7ebbb070d0d9868d0f64b784658d6c241fb" }, "tx_witness": [ - "74b70328f8c57342af89669f6370a4338047c419af612cb6858f06ed5e6542d37dcc9547fbfd0b9f6531726ca8e3914f5e9a0b2bd99df1ca213a181d6b3aba8f" + "73f715f54560d5f42f0e367854c1597eb26e4b15b449257515e892171191e59e824a17111eca21d5f2bf7249fdbc644e87d882d2320ea3763b7b6bbbcedee8ba" ], "split_commitment": null } ], "split_commitment_root": { - "hash": "51c2570532bfe1831c75b9706c801c1d46fb9e0e9dccc8d6f3ad101704239af8", + "hash": "75b1b63f19108940bea7b1e99c69e915e5cacfc587cbe6c5f55657684a2b1ba8", "sum": "1" }, "script_version": 0, "script_key": "027c79b9b26e463895eef5679d8558942c86c4ad2233adef01bc3e6d540b3653fe", "group_key": { - "group_key": "03316168dcae498b33518be40890ab1c4aced753c456e3886abda5bd14297752a5" + "group_key": "02d873b3ac2e180ab3c0854a2f8e470c433a709b6a79aef381dc2fb26b9c458a49" } } } @@ -248,7 +252,7 @@ "script_version": 0, "script_key": "02056c5e3feae572f444f0ba7f140a6e97f9536c5419aed6d95653ea46416e0b65", "group_key": { - "group_key": "03316168dcae498b33518be40890ab1c4aced753c456e3886abda5bd14297752a5" + "group_key": "02d873b3ac2e180ab3c0854a2f8e470c433a709b6a79aef381dc2fb26b9c458a49" } }, "output_index": 1 @@ -260,7 +264,7 @@ "prev_id": { "out_point": "0000000000000000000000000000000000000000000000000000000000000000:0", "asset_id": "5bd514450208479701c49b5441a87c652b41b5d9decb2c508149b4596061d51f", - "script_key": "027a6109322820fe97863ad62d579f8393fa058cc8e60300233bb816fc0941f520" + "script_key": "02b3270194556867c9a3a70b54df62b7ebbb070d0d9868d0f64b784658d6c241fb" }, "asset": { "version": 0, @@ -285,9 +289,9 @@ ], "split_commitment_root": null, "script_version": 0, - "script_key": "027a6109322820fe97863ad62d579f8393fa058cc8e60300233bb816fc0941f520", + "script_key": "02b3270194556867c9a3a70b54df62b7ebbb070d0d9868d0f64b784658d6c241fb", "group_key": { - "group_key": "03316168dcae498b33518be40890ab1c4aced753c456e3886abda5bd14297752a5" + "group_key": "02d873b3ac2e180ab3c0854a2f8e470c433a709b6a79aef381dc2fb26b9c458a49" } } } @@ -299,11 +303,11 @@ "asset": { "version": 0, "genesis_first_prev_out": "c76fad5e0ce6e5cd00c4e533e9a3bb18c948b9e962e5dcfd887953e8e57d0f8a:3701924107", - "genesis_tag": "b93d1676c1bdd19ab8e2925c6daee4de5ef9f9dcf08dfcbd02b8080939858592", - "genesis_meta_hash": "b93d1676c1bdd19ab8e2925c6daee4de5ef9f9dcf08dfcbd02b8080939858592", + "genesis_tag": "ea3d1676c1bdd19ab8e2925c6daee4de5ef9f9dcf08dfcbd02b8080939858592", + "genesis_meta_hash": "ea3d1676c1bdd19ab8e2925c6daee4de5ef9f9dcf08dfcbd02b8080939858592", "genesis_output_index": 498759598, "genesis_type": 0, - "amount": 7432855125997443448, + "amount": 2863951798888068529, "lock_time": 0, "relative_lock_time": 0, "prev_witnesses": [ @@ -313,15 +317,17 @@ "asset_id": "0000000000000000000000000000000000000000000000000000000000000000", "script_key": "000000000000000000000000000000000000000000000000000000000000000000" }, - "tx_witness": null, + "tx_witness": [ + "065c44e9f8a2b84055ce761dddb668d0e34f8fdfac61cf0b2ea1be1fb9b77ca674a9ef01c8d20950173fbb0196ce019c8fccbc21a6a2d7b8ee755f5041ebe6ff" + ], "split_commitment": null } ], "split_commitment_root": null, "script_version": 0, - "script_key": "02a790cebfdd68c513e9d3c6d5f674c5eb5ed86b9c28335bd1c1dc7a4b87b975ee", + "script_key": "025ed5b176508010993cc05660edf8bd1d23bba1464548dcfc5e6e8305d21f064f", "group_key": { - "group_key": "03f65f286d0ab66acfc955fe0de598f1c0a12ac478cf53b26b5d680e13af6e2b93" + "group_key": "02070a20c84da2ab2e17f0fa0315a86b12412fe3e94c93084970749e74b607d072" } }, "split_set": [ @@ -376,19 +382,19 @@ "script_key": "02f08c2c9b2290ab7115753fb489c19b89db20b415187fdff1f8fe615ca6bc2258" }, "tx_witness": [ - "ad02d7eb8ca4e6caf524be7d76bb138d94085ab667959539e5684b39d6aa7a116f6b591bbaabcf4223538b96e5909275207040cefea5883356200c65706f58f5" + "527d17bba3ada7bf31b0abaa260f8db47b5ba07850371f0eaf0d261f072972730efb69ea928969b165bfa86ff59e6015934d0f8223787b8dc43c8134e8de62d3" ], "split_commitment": null } ], "split_commitment_root": { - "hash": "a790d995e0cedcd7c3962947f2f3aad6bd403276c3ad8876d66e1512a4b7fec3", + "hash": "f715c9521f206c18b3534f45e58206f38bc9a30391f9e9ce917d981e6916fdec", "sum": "3" }, "script_version": 0, "script_key": "02f08c2c9b2290ab7115753fb489c19b89db20b415187fdff1f8fe615ca6bc2258", "group_key": { - "group_key": "03d76153896a0ce8201f6a31d9e97528c58091405c5362b40071bd22e13aeef4db" + "group_key": "0237a0abb17ba02a05663276bce226f314fad7d28085b6b286bdc7074caf744c08" } }, "split_set": [ @@ -419,7 +425,7 @@ }, "tx_witness": null, "split_commitment": { - "proof": "00017d0e0cce7961d0e8d2d4517f64da2c154938c1b6e0f59939dbf2daca8fcde2a80000000000000003ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f", + "proof": "0001eb0d6b100ef74993516440a4d402afe50d396b3ed3be43e5e490bb5c6c4e428a0000000000000003ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f", "root_asset": { "version": 0, "genesis_first_prev_out": "a349b0bcf930b4e027f21867fd10a4cb7ec70332fa39157426e50ec28bf4b1fd:4178205505", @@ -438,19 +444,19 @@ "script_key": "02f08c2c9b2290ab7115753fb489c19b89db20b415187fdff1f8fe615ca6bc2258" }, "tx_witness": [ - "ad02d7eb8ca4e6caf524be7d76bb138d94085ab667959539e5684b39d6aa7a116f6b591bbaabcf4223538b96e5909275207040cefea5883356200c65706f58f5" + "527d17bba3ada7bf31b0abaa260f8db47b5ba07850371f0eaf0d261f072972730efb69ea928969b165bfa86ff59e6015934d0f8223787b8dc43c8134e8de62d3" ], "split_commitment": null } ], "split_commitment_root": { - "hash": "a790d995e0cedcd7c3962947f2f3aad6bd403276c3ad8876d66e1512a4b7fec3", + "hash": "f715c9521f206c18b3534f45e58206f38bc9a30391f9e9ce917d981e6916fdec", "sum": "3" }, "script_version": 0, "script_key": "027c79b9b26e463895eef5679d8558942c86c4ad2233adef01bc3e6d540b3653fe", "group_key": { - "group_key": "03d76153896a0ce8201f6a31d9e97528c58091405c5362b40071bd22e13aeef4db" + "group_key": "0237a0abb17ba02a05663276bce226f314fad7d28085b6b286bdc7074caf744c08" } } } @@ -460,7 +466,7 @@ "script_version": 0, "script_key": "027c79b9b26e463895eef5679d8558942c86c4ad2233adef01bc3e6d540b3653fe", "group_key": { - "group_key": "03d76153896a0ce8201f6a31d9e97528c58091405c5362b40071bd22e13aeef4db" + "group_key": "0237a0abb17ba02a05663276bce226f314fad7d28085b6b286bdc7074caf744c08" } }, "output_index": 0 @@ -470,7 +476,7 @@ "key": { "output_index": 1, "asset_id": "9fc4a8671e62ec453348a2acb3ae22f885e3359fccdae4eb60f1100cdf335293", - "script_key": "0374631e0dbdd29280a5ded9bf0d6e20c8cd71b1118dc10a109e09ec9b79334809", + "script_key": "0350c7b05fa47eae2d8430e410d94ac039247f3add3ada7a4cb700223d3b1b4b4f", "amount": 3 }, "value": { @@ -493,7 +499,7 @@ }, "tx_witness": null, "split_commitment": { - "proof": "0001da7fdad121cad78c32b2945d574862296f451ae147c35bc500e6bf5773d86bad0000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f", + "proof": "00019ef743c4705940587523bd08e553e3fd68c53955688d488605f28de0d3cb5dba0000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f", "root_asset": { "version": 0, "genesis_first_prev_out": "a349b0bcf930b4e027f21867fd10a4cb7ec70332fa39157426e50ec28bf4b1fd:4178205505", @@ -512,19 +518,19 @@ "script_key": "02f08c2c9b2290ab7115753fb489c19b89db20b415187fdff1f8fe615ca6bc2258" }, "tx_witness": [ - "ad02d7eb8ca4e6caf524be7d76bb138d94085ab667959539e5684b39d6aa7a116f6b591bbaabcf4223538b96e5909275207040cefea5883356200c65706f58f5" + "527d17bba3ada7bf31b0abaa260f8db47b5ba07850371f0eaf0d261f072972730efb69ea928969b165bfa86ff59e6015934d0f8223787b8dc43c8134e8de62d3" ], "split_commitment": null } ], "split_commitment_root": { - "hash": "a790d995e0cedcd7c3962947f2f3aad6bd403276c3ad8876d66e1512a4b7fec3", + "hash": "f715c9521f206c18b3534f45e58206f38bc9a30391f9e9ce917d981e6916fdec", "sum": "3" }, "script_version": 0, "script_key": "027c79b9b26e463895eef5679d8558942c86c4ad2233adef01bc3e6d540b3653fe", "group_key": { - "group_key": "03d76153896a0ce8201f6a31d9e97528c58091405c5362b40071bd22e13aeef4db" + "group_key": "0237a0abb17ba02a05663276bce226f314fad7d28085b6b286bdc7074caf744c08" } } } @@ -532,9 +538,9 @@ ], "split_commitment_root": null, "script_version": 0, - "script_key": "0274631e0dbdd29280a5ded9bf0d6e20c8cd71b1118dc10a109e09ec9b79334809", + "script_key": "0250c7b05fa47eae2d8430e410d94ac039247f3add3ada7a4cb700223d3b1b4b4f", "group_key": { - "group_key": "03d76153896a0ce8201f6a31d9e97528c58091405c5362b40071bd22e13aeef4db" + "group_key": "0237a0abb17ba02a05663276bce226f314fad7d28085b6b286bdc7074caf744c08" } }, "output_index": 1 @@ -573,7 +579,7 @@ "script_version": 0, "script_key": "02f08c2c9b2290ab7115753fb489c19b89db20b415187fdff1f8fe615ca6bc2258", "group_key": { - "group_key": "03d76153896a0ce8201f6a31d9e97528c58091405c5362b40071bd22e13aeef4db" + "group_key": "0237a0abb17ba02a05663276bce226f314fad7d28085b6b286bdc7074caf744c08" } } } @@ -600,19 +606,19 @@ "script_key": "0204f400bc8950d521d0905763c1cd64b75716172bb6b0d731ea0cb1e9833f5c96" }, "tx_witness": [ - "4596c45a29d1064e6a5e2e31ccade536758d8ca9b07c45300c6c625c6c39963910fdaed8de44bbc2b9e5822d3cb7037f01b38259014376826291af41b91117e9" + "4c3e26abf028316b6bfdc00157d75173723e0fe536e96a4c871aee6012905298e23a39557e25d0d843d6803a8fec283ca10c76b66d83743f2f814b79064b0308" ], "split_commitment": null } ], "split_commitment_root": { - "hash": "22460b794fe9457cac48b443114fdd62defc50b39389b5aaf529ec927e3f6df1", + "hash": "62dfc8764cc94036c90f843729602bf98b005fd3e76803d35a2c585469765f6b", "sum": "3" }, "script_version": 0, "script_key": "027c79b9b26e463895eef5679d8558942c86c4ad2233adef01bc3e6d540b3653fe", "group_key": { - "group_key": "03bb449e7bbbeb2e9caad2ffe7e2ee2e161a790ec17e9490643c7b8d6ab1568981" + "group_key": "0369629d40e07cd3a0aca6d1988fb844a91a4691ddaf3e6f174ae5b3e1a1cc011e" } }, "split_set": [ @@ -643,7 +649,7 @@ }, "tx_witness": null, "split_commitment": { - "proof": "00010db0c64cd044ff7fe663df4a9e20fab345fea01570c2c924a5da9a49a2950a130000000000000003ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffef", + "proof": "0001e89c10ceaff4d4bef1890626a310cc82dd4883b222af5ff4ee6d9a6f490011800000000000000003ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f", "root_asset": { "version": 0, "genesis_first_prev_out": "48c57dfab88cbeeef48ee65b1cda321559b47697c6f9348b36270033bbc7e416:193811675", @@ -662,19 +668,19 @@ "script_key": "0204f400bc8950d521d0905763c1cd64b75716172bb6b0d731ea0cb1e9833f5c96" }, "tx_witness": [ - "4596c45a29d1064e6a5e2e31ccade536758d8ca9b07c45300c6c625c6c39963910fdaed8de44bbc2b9e5822d3cb7037f01b38259014376826291af41b91117e9" + "4c3e26abf028316b6bfdc00157d75173723e0fe536e96a4c871aee6012905298e23a39557e25d0d843d6803a8fec283ca10c76b66d83743f2f814b79064b0308" ], "split_commitment": null } ], "split_commitment_root": { - "hash": "22460b794fe9457cac48b443114fdd62defc50b39389b5aaf529ec927e3f6df1", + "hash": "62dfc8764cc94036c90f843729602bf98b005fd3e76803d35a2c585469765f6b", "sum": "3" }, "script_version": 0, "script_key": "027c79b9b26e463895eef5679d8558942c86c4ad2233adef01bc3e6d540b3653fe", "group_key": { - "group_key": "03bb449e7bbbeb2e9caad2ffe7e2ee2e161a790ec17e9490643c7b8d6ab1568981" + "group_key": "0369629d40e07cd3a0aca6d1988fb844a91a4691ddaf3e6f174ae5b3e1a1cc011e" } } } @@ -684,7 +690,7 @@ "script_version": 0, "script_key": "0204f400bc8950d521d0905763c1cd64b75716172bb6b0d731ea0cb1e9833f5c96", "group_key": { - "group_key": "03bb449e7bbbeb2e9caad2ffe7e2ee2e161a790ec17e9490643c7b8d6ab1568981" + "group_key": "0369629d40e07cd3a0aca6d1988fb844a91a4691ddaf3e6f174ae5b3e1a1cc011e" } }, "output_index": 0 @@ -694,7 +700,7 @@ "key": { "output_index": 1, "asset_id": "7ccbf927e37c82e18d894e0dbdef95444984f564da5d7c2b8c07e9c0671da31b", - "script_key": "036da333a6ae9260f122ab56a8ce00f3864d35c569e8bb500af8ba0fba42f86c9d", + "script_key": "0247d4b3ad49b943e998b13d4cf344f3ab9dcafc297c2115bd82916dbe10e86438", "amount": 3 }, "value": { @@ -717,7 +723,7 @@ }, "tx_witness": null, "split_commitment": { - "proof": "00016b386ceda8916f49d2fefc5e42704e431032fabb1259436693ca5e2d69068e180000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffef", + "proof": "0001d67b99652e914ffaad004c027684e1e5c87405d8fade7a96ff96eea9a2e92e500000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f", "root_asset": { "version": 0, "genesis_first_prev_out": "48c57dfab88cbeeef48ee65b1cda321559b47697c6f9348b36270033bbc7e416:193811675", @@ -736,19 +742,19 @@ "script_key": "0204f400bc8950d521d0905763c1cd64b75716172bb6b0d731ea0cb1e9833f5c96" }, "tx_witness": [ - "4596c45a29d1064e6a5e2e31ccade536758d8ca9b07c45300c6c625c6c39963910fdaed8de44bbc2b9e5822d3cb7037f01b38259014376826291af41b91117e9" + "4c3e26abf028316b6bfdc00157d75173723e0fe536e96a4c871aee6012905298e23a39557e25d0d843d6803a8fec283ca10c76b66d83743f2f814b79064b0308" ], "split_commitment": null } ], "split_commitment_root": { - "hash": "22460b794fe9457cac48b443114fdd62defc50b39389b5aaf529ec927e3f6df1", + "hash": "62dfc8764cc94036c90f843729602bf98b005fd3e76803d35a2c585469765f6b", "sum": "3" }, "script_version": 0, "script_key": "027c79b9b26e463895eef5679d8558942c86c4ad2233adef01bc3e6d540b3653fe", "group_key": { - "group_key": "03bb449e7bbbeb2e9caad2ffe7e2ee2e161a790ec17e9490643c7b8d6ab1568981" + "group_key": "0369629d40e07cd3a0aca6d1988fb844a91a4691ddaf3e6f174ae5b3e1a1cc011e" } } } @@ -756,9 +762,9 @@ ], "split_commitment_root": null, "script_version": 0, - "script_key": "026da333a6ae9260f122ab56a8ce00f3864d35c569e8bb500af8ba0fba42f86c9d", + "script_key": "0247d4b3ad49b943e998b13d4cf344f3ab9dcafc297c2115bd82916dbe10e86438", "group_key": { - "group_key": "03bb449e7bbbeb2e9caad2ffe7e2ee2e161a790ec17e9490643c7b8d6ab1568981" + "group_key": "0369629d40e07cd3a0aca6d1988fb844a91a4691ddaf3e6f174ae5b3e1a1cc011e" } }, "output_index": 1 @@ -797,7 +803,7 @@ "script_version": 0, "script_key": "0204f400bc8950d521d0905763c1cd64b75716172bb6b0d731ea0cb1e9833f5c96", "group_key": { - "group_key": "03bb449e7bbbeb2e9caad2ffe7e2ee2e161a790ec17e9490643c7b8d6ab1568981" + "group_key": "0369629d40e07cd3a0aca6d1988fb844a91a4691ddaf3e6f174ae5b3e1a1cc011e" } } } @@ -832,13 +838,13 @@ } ], "split_commitment_root": { - "hash": "6d676302f69379d98e09161f87903d9fd08ecef3f59daa758d3597d72fa912c4", + "hash": "8d33cb00ea95fb647a43d0114c0cb3fe64a00ba78e03dc9be70a5846570d8632", "sum": "3" }, "script_version": 0, "script_key": "02d6d5d3a0e9f4b67db54e56efaa518e6b81324e2ddd34da8adc5f2898e5b239a2", "group_key": { - "group_key": "020187c1a7c5b55b37aba0975f9f858b13fc2159166894fd39e766fadbcf228bf7" + "group_key": "03d0af945d7272e8ebcaca2099e2ca72aaa79bb8ec827f2adc8bce1658644684fe" } }, "split_set": [ @@ -869,7 +875,7 @@ }, "tx_witness": null, "split_commitment": { - "proof": "00018f34afe7fee4b6b51a1ab6860db454d1d623e92ed49eeba7168f94172ace3e050000000000000002ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbf", + "proof": "000237015880a698ec5a78c0d4fe38dc42b192c1213af5cf725170259109f72c35c300000000000000010ac4d57d3b994e9cc5071aa3ee874079d9e97debe70dea497e340b585bef84570000000000000001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff3f", "root_asset": { "version": 0, "genesis_first_prev_out": "3329d9f17d9e8fbca62343b186b51fa6e3cafccae22442c29291018d7c984b92:1064433867", @@ -896,13 +902,13 @@ } ], "split_commitment_root": { - "hash": "6d676302f69379d98e09161f87903d9fd08ecef3f59daa758d3597d72fa912c4", + "hash": "8d33cb00ea95fb647a43d0114c0cb3fe64a00ba78e03dc9be70a5846570d8632", "sum": "3" }, "script_version": 0, "script_key": "02d6d5d3a0e9f4b67db54e56efaa518e6b81324e2ddd34da8adc5f2898e5b239a2", "group_key": { - "group_key": "020187c1a7c5b55b37aba0975f9f858b13fc2159166894fd39e766fadbcf228bf7" + "group_key": "03d0af945d7272e8ebcaca2099e2ca72aaa79bb8ec827f2adc8bce1658644684fe" } } } @@ -912,7 +918,7 @@ "script_version": 0, "script_key": "02d6d5d3a0e9f4b67db54e56efaa518e6b81324e2ddd34da8adc5f2898e5b239a2", "group_key": { - "group_key": "020187c1a7c5b55b37aba0975f9f858b13fc2159166894fd39e766fadbcf228bf7" + "group_key": "03d0af945d7272e8ebcaca2099e2ca72aaa79bb8ec827f2adc8bce1658644684fe" } }, "output_index": 0 @@ -922,7 +928,7 @@ "key": { "output_index": 1, "asset_id": "2edf66074b1efe054cfb4118b300368c2d67c46a421491bf6b6dc190c81fd71d", - "script_key": "035a8c954982096a8edf7eceb71aac9b5c43464207dcb1d202ece7b9759b2a00c3", + "script_key": "0363746d5d85cffc8483665cd62977ec640b0256a339f3dc89b0ed6f8ef5d9e023", "amount": 1 }, "value": { @@ -945,7 +951,7 @@ }, "tx_witness": null, "split_commitment": { - "proof": "0002cd28160793e33c9a42c732e84ce7a5d77c02c4d0553a73a13917ed22657d1e9c00000000000000010b1b5355bc6ced5d2cef21941309d31f6c2d74d6ea91ca805f75cd812400e5d50000000000000001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb7", + "proof": "00019dac15976fdfd36aaa283472d3ed9610643706c76034a98342c3c19d28ad03c20000000000000002ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f", "root_asset": { "version": 0, "genesis_first_prev_out": "3329d9f17d9e8fbca62343b186b51fa6e3cafccae22442c29291018d7c984b92:1064433867", @@ -972,13 +978,13 @@ } ], "split_commitment_root": { - "hash": "6d676302f69379d98e09161f87903d9fd08ecef3f59daa758d3597d72fa912c4", + "hash": "8d33cb00ea95fb647a43d0114c0cb3fe64a00ba78e03dc9be70a5846570d8632", "sum": "3" }, "script_version": 0, "script_key": "02d6d5d3a0e9f4b67db54e56efaa518e6b81324e2ddd34da8adc5f2898e5b239a2", "group_key": { - "group_key": "020187c1a7c5b55b37aba0975f9f858b13fc2159166894fd39e766fadbcf228bf7" + "group_key": "03d0af945d7272e8ebcaca2099e2ca72aaa79bb8ec827f2adc8bce1658644684fe" } } } @@ -986,9 +992,9 @@ ], "split_commitment_root": null, "script_version": 0, - "script_key": "025a8c954982096a8edf7eceb71aac9b5c43464207dcb1d202ece7b9759b2a00c3", + "script_key": "0263746d5d85cffc8483665cd62977ec640b0256a339f3dc89b0ed6f8ef5d9e023", "group_key": { - "group_key": "020187c1a7c5b55b37aba0975f9f858b13fc2159166894fd39e766fadbcf228bf7" + "group_key": "03d0af945d7272e8ebcaca2099e2ca72aaa79bb8ec827f2adc8bce1658644684fe" } }, "output_index": 1 @@ -1021,7 +1027,7 @@ }, "tx_witness": null, "split_commitment": { - "proof": "000210b2c86b908a6b5022b961e65ccba4e6c0cac435870aa84df44571be2b6b981d00000000000000010b1b5355bc6ced5d2cef21941309d31f6c2d74d6ea91ca805f75cd812400e5d50000000000000001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb7", + "proof": "00025d91dbb7ec19ef7517bfcfa9da61c44fc6ae4e61e035424969a1c00f92a56dc500000000000000010ac4d57d3b994e9cc5071aa3ee874079d9e97debe70dea497e340b585bef84570000000000000001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff3f", "root_asset": { "version": 0, "genesis_first_prev_out": "3329d9f17d9e8fbca62343b186b51fa6e3cafccae22442c29291018d7c984b92:1064433867", @@ -1048,13 +1054,13 @@ } ], "split_commitment_root": { - "hash": "6d676302f69379d98e09161f87903d9fd08ecef3f59daa758d3597d72fa912c4", + "hash": "8d33cb00ea95fb647a43d0114c0cb3fe64a00ba78e03dc9be70a5846570d8632", "sum": "3" }, "script_version": 0, "script_key": "02d6d5d3a0e9f4b67db54e56efaa518e6b81324e2ddd34da8adc5f2898e5b239a2", "group_key": { - "group_key": "020187c1a7c5b55b37aba0975f9f858b13fc2159166894fd39e766fadbcf228bf7" + "group_key": "03d0af945d7272e8ebcaca2099e2ca72aaa79bb8ec827f2adc8bce1658644684fe" } } } @@ -1064,7 +1070,7 @@ "script_version": 0, "script_key": "02421922a6a95c5888ce299c7b6cde1f3ef12ea93bc11fb1155eaf121c5505f2e0", "group_key": { - "group_key": "020187c1a7c5b55b37aba0975f9f858b13fc2159166894fd39e766fadbcf228bf7" + "group_key": "03d0af945d7272e8ebcaca2099e2ca72aaa79bb8ec827f2adc8bce1658644684fe" } }, "output_index": 2 @@ -1103,7 +1109,7 @@ "script_version": 0, "script_key": "02d6d5d3a0e9f4b67db54e56efaa518e6b81324e2ddd34da8adc5f2898e5b239a2", "group_key": { - "group_key": "020187c1a7c5b55b37aba0975f9f858b13fc2159166894fd39e766fadbcf228bf7" + "group_key": "03d0af945d7272e8ebcaca2099e2ca72aaa79bb8ec827f2adc8bce1658644684fe" } } } @@ -1138,13 +1144,13 @@ } ], "split_commitment_root": { - "hash": "14923e38cc97edcb8d746ef94da2b0841fe6557503094197e7f03585c2879cde", + "hash": "7387d1aea88f8d7cf27610af92a8fca765830f975f6e392c535f55a83ace6293", "sum": "3" }, "script_version": 0, "script_key": "02e30e00c78627b72797ac8e6dacf0249ec7423f018579976942fa2963e6192ca4", "group_key": { - "group_key": "03165da1622f6dd47789762cfb7790cf9ba7a14a6e2fc9d60408f0440b7271b66a" + "group_key": "032f6a210f1da1ba7f8d42f7ef44a6c6aab6054e99b7f9a2d2444adbfec3d1bcd2" } }, "split_set": [ @@ -1175,7 +1181,7 @@ }, "tx_witness": null, "split_commitment": { - "proof": "00026d854db4998ea0adcb06300c5ca13e4b60e2076b6e7425342006008c56f8cc0b000000000000000109196639fc6163a37b4776ff5969f7749e3b8e31f03e10a5d41787bf8c9877df0000000000000001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff5f", + "proof": "0002a394c5bc09226a6863e37acbc14470ddd1a443495d7b7df4a5053d05cc897f830000000000000001853344e329fe145c52521690260e8ff0504d6f5a1f187244c50785726b2652c90000000000000001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff5f", "root_asset": { "version": 0, "genesis_first_prev_out": "190476a1ffb522d554b41900fb4ffbf3a9e2e98ef360412c04d6353cb62f07cf:2736238143", @@ -1202,13 +1208,13 @@ } ], "split_commitment_root": { - "hash": "14923e38cc97edcb8d746ef94da2b0841fe6557503094197e7f03585c2879cde", + "hash": "7387d1aea88f8d7cf27610af92a8fca765830f975f6e392c535f55a83ace6293", "sum": "3" }, "script_version": 0, "script_key": "02e30e00c78627b72797ac8e6dacf0249ec7423f018579976942fa2963e6192ca4", "group_key": { - "group_key": "03165da1622f6dd47789762cfb7790cf9ba7a14a6e2fc9d60408f0440b7271b66a" + "group_key": "032f6a210f1da1ba7f8d42f7ef44a6c6aab6054e99b7f9a2d2444adbfec3d1bcd2" } } } @@ -1218,7 +1224,7 @@ "script_version": 0, "script_key": "02e30e00c78627b72797ac8e6dacf0249ec7423f018579976942fa2963e6192ca4", "group_key": { - "group_key": "03165da1622f6dd47789762cfb7790cf9ba7a14a6e2fc9d60408f0440b7271b66a" + "group_key": "032f6a210f1da1ba7f8d42f7ef44a6c6aab6054e99b7f9a2d2444adbfec3d1bcd2" } }, "output_index": 0 @@ -1251,7 +1257,7 @@ }, "tx_witness": null, "split_commitment": { - "proof": "0002109430e60fc641b99e1ca41882d8036ebcccb34aaf7fd311028db15d7f61c066000000000000000109196639fc6163a37b4776ff5969f7749e3b8e31f03e10a5d41787bf8c9877df0000000000000001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff5f", + "proof": "00020b2f98ef31a1b2d9cea122f4736b52742da6094e2267673457a7fcd454751df40000000000000001853344e329fe145c52521690260e8ff0504d6f5a1f187244c50785726b2652c90000000000000001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff5f", "root_asset": { "version": 0, "genesis_first_prev_out": "190476a1ffb522d554b41900fb4ffbf3a9e2e98ef360412c04d6353cb62f07cf:2736238143", @@ -1278,13 +1284,13 @@ } ], "split_commitment_root": { - "hash": "14923e38cc97edcb8d746ef94da2b0841fe6557503094197e7f03585c2879cde", + "hash": "7387d1aea88f8d7cf27610af92a8fca765830f975f6e392c535f55a83ace6293", "sum": "3" }, "script_version": 0, "script_key": "02e30e00c78627b72797ac8e6dacf0249ec7423f018579976942fa2963e6192ca4", "group_key": { - "group_key": "03165da1622f6dd47789762cfb7790cf9ba7a14a6e2fc9d60408f0440b7271b66a" + "group_key": "032f6a210f1da1ba7f8d42f7ef44a6c6aab6054e99b7f9a2d2444adbfec3d1bcd2" } } } @@ -1294,7 +1300,7 @@ "script_version": 0, "script_key": "028b7a758fd496f084bdfab7b4fea092f57449f61db59652ddf351fd1841e4a2eb", "group_key": { - "group_key": "03165da1622f6dd47789762cfb7790cf9ba7a14a6e2fc9d60408f0440b7271b66a" + "group_key": "032f6a210f1da1ba7f8d42f7ef44a6c6aab6054e99b7f9a2d2444adbfec3d1bcd2" } }, "output_index": 1 @@ -1327,7 +1333,7 @@ }, "tx_witness": null, "split_commitment": { - "proof": "000188433aea0cbb6f037e487bb75e9cedf1e2d0b46991948ef9f28e3e974c965f620000000000000002ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f", + "proof": "000169bb0e978627dcc95e717ab88652c7c9d63217b15a499a4b36449e582e20007f0000000000000002ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f", "root_asset": { "version": 0, "genesis_first_prev_out": "190476a1ffb522d554b41900fb4ffbf3a9e2e98ef360412c04d6353cb62f07cf:2736238143", @@ -1354,13 +1360,13 @@ } ], "split_commitment_root": { - "hash": "14923e38cc97edcb8d746ef94da2b0841fe6557503094197e7f03585c2879cde", + "hash": "7387d1aea88f8d7cf27610af92a8fca765830f975f6e392c535f55a83ace6293", "sum": "3" }, "script_version": 0, "script_key": "02e30e00c78627b72797ac8e6dacf0249ec7423f018579976942fa2963e6192ca4", "group_key": { - "group_key": "03165da1622f6dd47789762cfb7790cf9ba7a14a6e2fc9d60408f0440b7271b66a" + "group_key": "032f6a210f1da1ba7f8d42f7ef44a6c6aab6054e99b7f9a2d2444adbfec3d1bcd2" } } } @@ -1370,7 +1376,7 @@ "script_version": 0, "script_key": "021fa4a3511fbd6078357ce60c13f53a745a2e8871699b3cfdd398d66eb86fb319", "group_key": { - "group_key": "03165da1622f6dd47789762cfb7790cf9ba7a14a6e2fc9d60408f0440b7271b66a" + "group_key": "032f6a210f1da1ba7f8d42f7ef44a6c6aab6054e99b7f9a2d2444adbfec3d1bcd2" } }, "output_index": 2 @@ -1409,7 +1415,7 @@ "script_version": 0, "script_key": "02e30e00c78627b72797ac8e6dacf0249ec7423f018579976942fa2963e6192ca4", "group_key": { - "group_key": "03165da1622f6dd47789762cfb7790cf9ba7a14a6e2fc9d60408f0440b7271b66a" + "group_key": "032f6a210f1da1ba7f8d42f7ef44a6c6aab6054e99b7f9a2d2444adbfec3d1bcd2" } } } diff --git a/vm/vm.go b/vm/vm.go index c7cb2e088..63928ce4d 100644 --- a/vm/vm.go +++ b/vm/vm.go @@ -191,24 +191,37 @@ func (vm *Engine) validateWitnessV0(virtualTx *wire.MsgTx, inputIdx uint32, return ErrInvalidScriptVersion } - // An input MUST have a prev out and also a valid witness. - if witness.PrevID == nil || len(witness.TxWitness) == 0 { + // An input must have a valid witness. + if len(witness.TxWitness) == 0 { return newErrKind(ErrInvalidTransferWitness) } - // The parameters of the new and old asset much match exactly. - err := matchesAssetParams(vm.newAsset, prevAsset, witness) - if err != nil { - return err - } - - // Update the virtual transaction input with details for the specific - // Taproot Asset input and proceed to validate its witness. - virtualTxCopy := tapscript.VirtualTxWithInput( - virtualTx, prevAsset, inputIdx, witness.TxWitness, + var ( + prevOutFetcher *txscript.CannedPrevOutputFetcher + err error ) - prevOutFetcher, err := tapscript.InputPrevOutFetcher(*prevAsset) + // Genesis grouped assets will have a nil PrevID and match the prevAsset + // since it is a copy of the original asset. The prevOut used will need + // to built from the group key and not the script key. + switch { + case vm.newAsset.HasGenesisWitnessForGroup(): + prevOutFetcher, err = asset.GenesisPrevOutFetcher(*prevAsset) + + default: + // An input MUST have a prev out and also a valid witness. + if witness.PrevID == nil { + return newErrKind(ErrInvalidTransferWitness) + } + + // The parameters of the new and old asset much match exactly. + err = matchesAssetParams(vm.newAsset, prevAsset, witness) + if err != nil { + return err + } + + prevOutFetcher, err = tapscript.InputPrevOutFetcher(*prevAsset) + } if err != nil { if errors.Is(err, tapscript.ErrInvalidScriptVersion) { return ErrInvalidScriptVersion @@ -221,6 +234,12 @@ func (vm *Engine) validateWitnessV0(virtualTx *wire.MsgTx, inputIdx uint32, // every time. prevOut := prevOutFetcher.FetchPrevOutput(wire.OutPoint{}) + // Update the virtual transaction input with details for the specific + // Taproot Asset input and proceed to validate its witness. + virtualTxCopy := asset.VirtualTxWithInput( + virtualTx, prevAsset, inputIdx, witness.TxWitness, + ) + sigHashes := txscript.NewTxSigHashes(virtualTxCopy, prevOutFetcher) // With all the components mapped into a virtual transaction, will @@ -290,6 +309,20 @@ func (vm *Engine) Execute() error { return nil } + // Genesis assets in an asset group have a witness that must be + // verified to prove group membership. + if vm.newAsset.HasGenesisWitnessForGroup() { + if len(vm.splitAssets) > 0 || len(vm.prevAssets) > 0 { + return newErrKind(ErrInvalidGenesisStateTransition) + } + + // For genesis assets in an asset group, set the previous asset + // as the genesis asset. + vm.prevAssets = commitment.InputSet{ + asset.ZeroPrevID: vm.newAsset, + } + } + // If we have an asset split, then we need to validate the state // transition by verifying the split commitment proof before verify the // final asset witness. diff --git a/vm/vm_test.go b/vm/vm_test.go index fe59d9e84..e52814f14 100644 --- a/vm/vm_test.go +++ b/vm/vm_test.go @@ -36,10 +36,13 @@ func randAsset(t *testing.T, assetType asset.Type, t.Helper() genesis := asset.RandGenesis(t, assetType) - groupKey := asset.RandGroupKey(t, genesis) scriptKey := asset.NewScriptKey(scriptKeyPub) + protoAsset := asset.RandAssetWithValues(t, genesis, nil, scriptKey) + groupKey := asset.RandGroupKey(t, genesis, protoAsset) - return asset.RandAssetWithValues(t, genesis, groupKey, scriptKey) + fullAsset := protoAsset.Copy() + fullAsset.GroupKey = groupKey + return fullAsset } func genTaprootKeySpend(t *testing.T, privKey btcec.PrivateKey, @@ -47,7 +50,7 @@ func genTaprootKeySpend(t *testing.T, privKey btcec.PrivateKey, t.Helper() - virtualTxCopy := tapscript.VirtualTxWithInput( + virtualTxCopy := asset.VirtualTxWithInput( virtualTx, input, idx, nil, ) sigHash, err := tapscript.InputKeySpendSigHash( @@ -73,7 +76,7 @@ func genTaprootScriptSpend(t *testing.T, privKey btcec.PrivateKey, require.NoError(t, err) if scriptWitness == nil { - virtualTxCopy := tapscript.VirtualTxWithInput( + virtualTxCopy := asset.VirtualTxWithInput( virtualTx, input, idx, nil, ) sigHash, err := tapscript.InputScriptSpendSigHash(