Skip to content

Commit 4fa9f73

Browse files
committed
proof+tappsbt: remove package dependency between proof and tappsbt
We don't want to have a dependency from the proof package to the tappsbt package as that makes it impossible for us to have a proof within a virtual package. To resolve that potential circular dependency, we split the code of the ownership proving code into two pieces.
1 parent e5d2aa4 commit 4fa9f73

File tree

2 files changed

+40
-35
lines changed

2 files changed

+40
-35
lines changed

proof/verifier.go

Lines changed: 38 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,8 @@ import (
1010
"github.com/btcsuite/btcd/btcec/v2"
1111
"github.com/btcsuite/btcd/txscript"
1212
"github.com/btcsuite/btcd/wire"
13-
"github.com/lightninglabs/taproot-assets/address"
1413
"github.com/lightninglabs/taproot-assets/asset"
1514
"github.com/lightninglabs/taproot-assets/commitment"
16-
"github.com/lightninglabs/taproot-assets/tappsbt"
1715
"github.com/lightninglabs/taproot-assets/vm"
1816
"golang.org/x/sync/errgroup"
1917
)
@@ -255,28 +253,58 @@ func (p *Proof) verifyChallengeWitness() (bool, error) {
255253
// independent of how the asset was created. The chain params are only
256254
// needed when encoding/decoding a vPkt, so it doesn't matter what
257255
// network we choose as we only need the packet to get the witness.
258-
vPkt := tappsbt.OwnershipProofPacket(
259-
p.Asset.Copy(), &address.MainNetTap,
260-
)
261-
vIn := vPkt.Inputs[0]
262-
vOut := vPkt.Outputs[0]
256+
ownedAsset := p.Asset.Copy()
257+
prevId, proofAsset := CreateOwnershipProofAsset(ownedAsset)
263258

264259
// The 1-in-1-out packet for the challenge witness is well-defined, we
265260
// don't have to do any extra checks, just set the witness and then
266261
// validate it.
267-
vOut.Asset.PrevWitnesses[0].TxWitness = p.ChallengeWitness
262+
proofAsset.PrevWitnesses[0].TxWitness = p.ChallengeWitness
268263

269264
prevAssets := commitment.InputSet{
270-
vIn.PrevID: vIn.Asset(),
265+
prevId: ownedAsset,
271266
}
272-
engine, err := vm.New(vOut.Asset, nil, prevAssets)
267+
engine, err := vm.New(proofAsset, nil, prevAssets)
273268
if err != nil {
274269
return false, err
275270
}
276271

277272
return p.Asset.HasSplitCommitmentWitness(), engine.Execute()
278273
}
279274

275+
// CreateOwnershipProofAsset creates a virtual asset that can be used to prove
276+
// ownership of an asset. The virtual asset is created by spending the full
277+
// asset into a NUMS key.
278+
func CreateOwnershipProofAsset(
279+
ownedAsset *asset.Asset) (asset.PrevID, *asset.Asset) {
280+
281+
// We create the ownership proof by creating a virtual input and output
282+
// that spends the full asset into a NUMS key. But in order to prevent
283+
// that witness to be used in an actual state transition by a malicious
284+
// actor, we create the signature over an empty outpoint. This means the
285+
// witness is fully valid, but a full transition proof can never be
286+
// created, as the previous outpoint would not match the one that
287+
// actually goes on chain.
288+
//
289+
// TODO(guggero): Revisit this proof once we support pocket universes.
290+
emptyOutPoint := wire.OutPoint{}
291+
prevId := asset.PrevID{
292+
ID: ownedAsset.ID(),
293+
OutPoint: emptyOutPoint,
294+
ScriptKey: asset.ToSerialized(
295+
ownedAsset.ScriptKey.PubKey,
296+
),
297+
}
298+
299+
outputAsset := ownedAsset.Copy()
300+
outputAsset.ScriptKey = asset.NUMSScriptKey
301+
outputAsset.PrevWitnesses = []asset.Witness{{
302+
PrevID: &prevId,
303+
}}
304+
305+
return prevId, outputAsset
306+
}
307+
280308
// verifyGenesisReveal checks that the genesis reveal present in the proof at
281309
// minting validates against the asset ID and proof details.
282310
func (p *Proof) verifyGenesisReveal() error {

tappsbt/address.go

Lines changed: 2 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@ package tappsbt
33
import (
44
"fmt"
55

6-
"github.com/btcsuite/btcd/wire"
76
"github.com/lightninglabs/taproot-assets/address"
87
"github.com/lightninglabs/taproot-assets/asset"
8+
"github.com/lightninglabs/taproot-assets/proof"
99
"github.com/lightningnetwork/lnd/keychain"
1010
)
1111

@@ -135,30 +135,7 @@ func AddOutput(pkt *VPacket, amount uint64, scriptAddr asset.ScriptKey,
135135
func OwnershipProofPacket(ownedAsset *asset.Asset,
136136
chainParams *address.ChainParams) *VPacket {
137137

138-
// We create the ownership proof by creating a virtual packet that
139-
// spends the full asset into a NUMS key. But in order to prevent that
140-
// witness to be used in an actual state transition by a malicious
141-
// actor, we create the signature over an empty outpoint. This means the
142-
// witness is fully valid, but a full transition proof can never be
143-
// created, as the previous outpoint would not match the one that
144-
// actually goes on chain.
145-
//
146-
// TODO(guggero): Revisit this proof once we support pocket universes.
147-
emptyOutPoint := wire.OutPoint{}
148-
prevId := asset.PrevID{
149-
ID: ownedAsset.ID(),
150-
OutPoint: emptyOutPoint,
151-
ScriptKey: asset.ToSerialized(
152-
ownedAsset.ScriptKey.PubKey,
153-
),
154-
}
155-
156-
outputAsset := ownedAsset.Copy()
157-
outputAsset.ScriptKey = asset.NUMSScriptKey
158-
outputAsset.PrevWitnesses = []asset.Witness{{
159-
PrevID: &prevId,
160-
}}
161-
138+
prevId, outputAsset := proof.CreateOwnershipProofAsset(ownedAsset)
162139
vPkt := &VPacket{
163140
Inputs: []*VInput{{
164141
PrevID: prevId,

0 commit comments

Comments
 (0)