github.com/MetalBlockchain/metalgo@v1.11.9/vms/propertyfx/fx.go (about) 1 // Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. 2 // See the file LICENSE for licensing terms. 3 4 package propertyfx 5 6 import ( 7 "errors" 8 9 "github.com/MetalBlockchain/metalgo/vms/components/verify" 10 "github.com/MetalBlockchain/metalgo/vms/secp256k1fx" 11 ) 12 13 var ( 14 errWrongTxType = errors.New("wrong tx type") 15 errWrongUTXOType = errors.New("wrong utxo type") 16 errWrongOperationType = errors.New("wrong operation type") 17 errWrongCredentialType = errors.New("wrong credential type") 18 errWrongNumberOfUTXOs = errors.New("wrong number of UTXOs for the operation") 19 errWrongMintOutput = errors.New("wrong mint output provided") 20 errCantTransfer = errors.New("cant transfer with this fx") 21 ) 22 23 type Fx struct{ secp256k1fx.Fx } 24 25 func (fx *Fx) Initialize(vmIntf interface{}) error { 26 if err := fx.InitializeVM(vmIntf); err != nil { 27 return err 28 } 29 30 log := fx.VM.Logger() 31 log.Debug("initializing nft fx") 32 33 c := fx.VM.CodecRegistry() 34 return errors.Join( 35 c.RegisterType(&MintOutput{}), 36 c.RegisterType(&OwnedOutput{}), 37 c.RegisterType(&MintOperation{}), 38 c.RegisterType(&BurnOperation{}), 39 c.RegisterType(&Credential{}), 40 ) 41 } 42 43 func (fx *Fx) VerifyOperation(txIntf, opIntf, credIntf interface{}, utxosIntf []interface{}) error { 44 tx, ok := txIntf.(secp256k1fx.UnsignedTx) 45 switch { 46 case !ok: 47 return errWrongTxType 48 case len(utxosIntf) != 1: 49 return errWrongNumberOfUTXOs 50 } 51 52 cred, ok := credIntf.(*Credential) 53 if !ok { 54 return errWrongCredentialType 55 } 56 57 switch op := opIntf.(type) { 58 case *MintOperation: 59 return fx.VerifyMintOperation(tx, op, cred, utxosIntf[0]) 60 case *BurnOperation: 61 return fx.VerifyTransferOperation(tx, op, cred, utxosIntf[0]) 62 default: 63 return errWrongOperationType 64 } 65 } 66 67 func (fx *Fx) VerifyMintOperation(tx secp256k1fx.UnsignedTx, op *MintOperation, cred *Credential, utxoIntf interface{}) error { 68 out, ok := utxoIntf.(*MintOutput) 69 if !ok { 70 return errWrongUTXOType 71 } 72 73 if err := verify.All(op, cred, out); err != nil { 74 return err 75 } 76 77 switch { 78 case !out.OutputOwners.Equals(&op.MintOutput.OutputOwners): 79 return errWrongMintOutput 80 default: 81 return fx.Fx.VerifyCredentials(tx, &op.MintInput, &cred.Credential, &out.OutputOwners) 82 } 83 } 84 85 func (fx *Fx) VerifyTransferOperation(tx secp256k1fx.UnsignedTx, op *BurnOperation, cred *Credential, utxoIntf interface{}) error { 86 out, ok := utxoIntf.(*OwnedOutput) 87 if !ok { 88 return errWrongUTXOType 89 } 90 91 if err := verify.All(op, cred, out); err != nil { 92 return err 93 } 94 95 return fx.VerifyCredentials(tx, &op.Input, &cred.Credential, &out.OutputOwners) 96 } 97 98 func (*Fx) VerifyTransfer(_, _, _, _ interface{}) error { 99 return errCantTransfer 100 }