decred.org/dcrdex@v1.0.3/client/asset/btc/types.go (about) 1 package btc 2 3 import ( 4 "fmt" 5 "strconv" 6 "time" 7 8 "decred.org/dcrdex/client/asset" 9 "decred.org/dcrdex/dex" 10 "github.com/btcsuite/btcd/btcutil" 11 "github.com/btcsuite/btcd/chaincfg/chainhash" 12 "github.com/btcsuite/btcd/wire" 13 ) 14 15 type UTxO struct { 16 TxHash *chainhash.Hash 17 Vout uint32 18 Address string 19 Amount uint64 20 } 21 22 // OutPoint is the hash and output index of a transaction output. 23 type OutPoint struct { 24 TxHash chainhash.Hash 25 Vout uint32 26 } 27 28 // NewOutPoint is the constructor for a new OutPoint. 29 func NewOutPoint(txHash *chainhash.Hash, vout uint32) OutPoint { 30 return OutPoint{ 31 TxHash: *txHash, 32 Vout: vout, 33 } 34 } 35 36 // String is a string representation of the outPoint. 37 func (pt OutPoint) String() string { 38 return pt.TxHash.String() + ":" + strconv.Itoa(int(pt.Vout)) 39 } 40 41 // Output is information about a transaction Output. Output satisfies the 42 // asset.Coin interface. 43 type Output struct { 44 Pt OutPoint 45 Val uint64 46 } 47 48 // NewOutput is the constructor for an output. 49 func NewOutput(txHash *chainhash.Hash, vout uint32, value uint64) *Output { 50 return &Output{ 51 Pt: NewOutPoint(txHash, vout), 52 Val: value, 53 } 54 } 55 56 // Value returns the value of the Output. Part of the asset.Coin interface. 57 func (op *Output) Value() uint64 { 58 return op.Val 59 } 60 61 // ID is the Output's coin ID. Part of the asset.Coin interface. For BTC, the 62 // coin ID is 36 bytes = 32 bytes tx hash + 4 bytes big-endian vout. 63 func (op *Output) ID() dex.Bytes { 64 return ToCoinID(op.txHash(), op.vout()) 65 } 66 67 // String is a string representation of the coin. 68 func (op *Output) String() string { 69 return op.Pt.String() 70 } 71 72 // TxID is the ID of the transaction used to create the coin. 73 func (op *Output) TxID() string { 74 return op.txHash().String() 75 } 76 77 // txHash returns the pointer of the wire.OutPoint's Hash. 78 func (op *Output) txHash() *chainhash.Hash { 79 return &op.Pt.TxHash 80 } 81 82 // vout returns the wire.OutPoint's Index. 83 func (op *Output) vout() uint32 { 84 return op.Pt.Vout 85 } 86 87 // WireOutPoint creates and returns a new *wire.OutPoint for the output. 88 func (op *Output) WireOutPoint() *wire.OutPoint { 89 return wire.NewOutPoint(op.txHash(), op.vout()) 90 } 91 92 // ConvertCoin converts the asset.Coin to an Output. 93 func ConvertCoin(coin asset.Coin) (*Output, error) { 94 op, _ := coin.(*Output) 95 if op != nil { 96 return op, nil 97 } 98 txHash, vout, err := decodeCoinID(coin.ID()) 99 if err != nil { 100 return nil, err 101 } 102 return NewOutput(txHash, vout, coin.Value()), nil 103 } 104 105 // AuditInfo is information about a swap contract on that blockchain. 106 type AuditInfo struct { 107 Output *Output 108 Recipient btcutil.Address // caution: use stringAddr, not the Stringer 109 contract []byte 110 secretHash []byte 111 expiration time.Time 112 } 113 114 // Expiration returns the expiration time of the contract, which is the earliest 115 // time that a refund can be issued for an un-redeemed contract. 116 func (ci *AuditInfo) Expiration() time.Time { 117 return ci.expiration 118 } 119 120 // Coin returns the output as an asset.Coin. 121 func (ci *AuditInfo) Coin() asset.Coin { 122 return ci.Output 123 } 124 125 // Contract is the contract script. 126 func (ci *AuditInfo) Contract() dex.Bytes { 127 return ci.contract 128 } 129 130 // SecretHash is the contract's secret hash. 131 func (ci *AuditInfo) SecretHash() dex.Bytes { 132 return ci.secretHash 133 } 134 135 type BlockVector struct { 136 Height int64 137 Hash chainhash.Hash 138 } 139 140 // TxOutFromTxBytes parses the specified *wire.TxOut from the serialized 141 // transaction. 142 func TxOutFromTxBytes( 143 txB []byte, 144 vout uint32, 145 deserializeTx func([]byte) (*wire.MsgTx, error), 146 hashTx func(*wire.MsgTx) *chainhash.Hash, 147 ) (*wire.TxOut, error) { 148 msgTx, err := deserializeTx(txB) 149 if err != nil { 150 return nil, fmt.Errorf("error decoding transaction bytes: %v", err) 151 } 152 153 if len(msgTx.TxOut) <= int(vout) { 154 return nil, fmt.Errorf("no vout %d in tx %s", vout, hashTx(msgTx)) 155 } 156 return msgTx.TxOut[vout], nil 157 } 158 159 // SwapReceipt is information about a swap contract that was broadcast by this 160 // wallet. Satisfies the asset.Receipt interface. 161 type SwapReceipt struct { 162 Output *Output 163 SwapContract []byte 164 SignedRefundBytes []byte 165 ExpirationTime time.Time 166 } 167 168 // Expiration is the time that the contract will expire, allowing the user to 169 // issue a refund transaction. Part of the asset.Receipt interface. 170 func (r *SwapReceipt) Expiration() time.Time { 171 return r.ExpirationTime 172 } 173 174 // Contract is the contract script. Part of the asset.Receipt interface. 175 func (r *SwapReceipt) Contract() dex.Bytes { 176 return r.SwapContract 177 } 178 179 // Coin is the output information as an asset.Coin. Part of the asset.Receipt 180 // interface. 181 func (r *SwapReceipt) Coin() asset.Coin { 182 return r.Output 183 } 184 185 // String provides a human-readable representation of the contract's Coin. 186 func (r *SwapReceipt) String() string { 187 return r.Output.String() 188 } 189 190 // SignedRefund is a signed refund script that can be used to return 191 // funds to the user in the case a contract expires. 192 func (r *SwapReceipt) SignedRefund() dex.Bytes { 193 return r.SignedRefundBytes 194 }