-
Notifications
You must be signed in to change notification settings - Fork 0
/
coin.go
97 lines (87 loc) · 2.88 KB
/
coin.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
package util
import (
"strconv"
"github.com/OpenBazaar/wallet-interface"
"github.com/btcsuite/btcd/chaincfg"
"github.com/btcsuite/btcd/chaincfg/chainhash"
"github.com/btcsuite/btcd/wire"
"github.com/btcsuite/btcutil"
"github.com/btcsuite/btcutil/coinset"
hd "github.com/btcsuite/btcutil/hdkeychain"
)
type Coin struct {
TxHash *chainhash.Hash
TxIndex uint32
TxValue btcutil.Amount
TxNumConfs int64
ScriptPubKey []byte
}
func (c *Coin) Hash() *chainhash.Hash { return c.TxHash }
func (c *Coin) Index() uint32 { return c.TxIndex }
func (c *Coin) Value() btcutil.Amount { return c.TxValue }
func (c *Coin) PkScript() []byte { return c.ScriptPubKey }
func (c *Coin) NumConfs() int64 { return c.TxNumConfs }
func (c *Coin) ValueAge() int64 { return int64(c.TxValue) * c.TxNumConfs }
func NewCoin(txid chainhash.Hash, index uint32, value btcutil.Amount, numConfs int64, scriptPubKey []byte) (coinset.Coin, error) {
c := &Coin{
TxHash: &txid,
TxIndex: index,
TxValue: value,
TxNumConfs: numConfs,
ScriptPubKey: scriptPubKey,
}
return coinset.Coin(c), nil
}
func GatherCoins(height uint32, utxos []wallet.Utxo, scriptToAddress func(script []byte) (btcutil.Address, error), getKeyForScript func(scriptAddress []byte) (*hd.ExtendedKey, error)) map[coinset.Coin]*hd.ExtendedKey {
m := make(map[coinset.Coin]*hd.ExtendedKey)
for _, u := range utxos {
if u.WatchOnly {
continue
}
var confirmations int32
if u.AtHeight > 0 {
confirmations = int32(height) - u.AtHeight
}
val, _ := strconv.ParseInt(u.Value, 10, 64)
c, err := NewCoin(u.Op.Hash, u.Op.Index, btcutil.Amount(val), int64(confirmations), u.ScriptPubkey)
if err != nil {
continue
}
addr, err := scriptToAddress(u.ScriptPubkey)
if err != nil {
continue
}
key, err := getKeyForScript(addr.ScriptAddress())
if err != nil {
continue
}
m[c] = key
}
return m
}
func LoadAllInputs(tx *wire.MsgTx, coinMap map[coinset.Coin]*hd.ExtendedKey, params *chaincfg.Params) (int64, map[wire.OutPoint]int64, map[wire.OutPoint][]byte, map[string]*btcutil.WIF) {
inVals := make(map[wire.OutPoint]int64)
totalIn := int64(0)
additionalPrevScripts := make(map[wire.OutPoint][]byte)
additionalKeysByAddress := make(map[string]*btcutil.WIF)
for coin, key := range coinMap {
outpoint := wire.NewOutPoint(coin.Hash(), coin.Index())
in := wire.NewTxIn(outpoint, nil, nil)
additionalPrevScripts[*outpoint] = coin.PkScript()
tx.TxIn = append(tx.TxIn, in)
val := int64(coin.Value().ToUnit(btcutil.AmountSatoshi))
totalIn += val
inVals[*outpoint] = val
addr, err := key.Address(params)
if err != nil {
continue
}
privKey, err := key.ECPrivKey()
if err != nil {
continue
}
wif, _ := btcutil.NewWIF(privKey, params, true)
additionalKeysByAddress[addr.EncodeAddress()] = wif
}
return totalIn, inVals, additionalPrevScripts, additionalKeysByAddress
}