github.com/avahowell/sia@v0.5.1-beta.0.20160524050156-83dcc3d37c94/modules/wallet/money.go (about) 1 package wallet 2 3 import ( 4 "github.com/NebulousLabs/Sia/build" 5 "github.com/NebulousLabs/Sia/types" 6 ) 7 8 // sortedOutputs is a struct containing a slice of siacoin outputs and their 9 // corresponding ids. sortedOutputs can be sorted using the sort package. 10 type sortedOutputs struct { 11 ids []types.SiacoinOutputID 12 outputs []types.SiacoinOutput 13 } 14 15 // ConfirmedBalance returns the balance of the wallet according to all of the 16 // confirmed transactions. 17 func (w *Wallet) ConfirmedBalance() (siacoinBalance types.Currency, siafundBalance types.Currency, siafundClaimBalance types.Currency) { 18 w.mu.Lock() 19 defer w.mu.Unlock() 20 21 for _, sco := range w.siacoinOutputs { 22 siacoinBalance = siacoinBalance.Add(sco.Value) 23 } 24 for _, sfo := range w.siafundOutputs { 25 siafundBalance = siafundBalance.Add(sfo.Value) 26 siafundClaimBalance = siafundClaimBalance.Add(w.siafundPool.Sub(sfo.ClaimStart).Mul(sfo.Value).Div(types.SiafundCount)) 27 } 28 return 29 } 30 31 // UnconfirmedBalance returns the number of outgoing and incoming siacoins in 32 // the unconfirmed transaction set. Refund outputs are included in this 33 // reporting. 34 func (w *Wallet) UnconfirmedBalance() (outgoingSiacoins types.Currency, incomingSiacoins types.Currency) { 35 w.mu.Lock() 36 defer w.mu.Unlock() 37 38 for _, upt := range w.unconfirmedProcessedTransactions { 39 for _, input := range upt.Inputs { 40 if input.FundType == types.SpecifierSiacoinInput && input.WalletAddress { 41 outgoingSiacoins = outgoingSiacoins.Add(input.Value) 42 } 43 } 44 for _, output := range upt.Outputs { 45 if output.FundType == types.SpecifierSiacoinOutput && output.WalletAddress { 46 incomingSiacoins = incomingSiacoins.Add(output.Value) 47 } 48 } 49 } 50 return 51 } 52 53 // SendSiacoins creates a transaction sending 'amount' to 'dest'. The transaction 54 // is submitted to the transaction pool and is also returned. 55 func (w *Wallet) SendSiacoins(amount types.Currency, dest types.UnlockHash) ([]types.Transaction, error) { 56 tpoolFee := types.SiacoinPrecision.Mul64(10) // TODO: better fee algo. 57 output := types.SiacoinOutput{ 58 Value: amount, 59 UnlockHash: dest, 60 } 61 62 txnBuilder := w.StartTransaction() 63 err := txnBuilder.FundSiacoins(amount.Add(tpoolFee)) 64 if err != nil { 65 return nil, err 66 } 67 txnBuilder.AddMinerFee(tpoolFee) 68 txnBuilder.AddSiacoinOutput(output) 69 txnSet, err := txnBuilder.Sign(true) 70 if err != nil { 71 return nil, err 72 } 73 err = w.tpool.AcceptTransactionSet(txnSet) 74 if err != nil { 75 return nil, err 76 } 77 return txnSet, nil 78 } 79 80 // SendSiafunds creates a transaction sending 'amount' to 'dest'. The transaction 81 // is submitted to the transaction pool and is also returned. 82 func (w *Wallet) SendSiafunds(amount types.Currency, dest types.UnlockHash) ([]types.Transaction, error) { 83 tpoolFee := types.SiacoinPrecision.Mul64(10) // TODO: better fee algo. 84 output := types.SiafundOutput{ 85 Value: amount, 86 UnlockHash: dest, 87 } 88 89 txnBuilder := w.StartTransaction() 90 err := txnBuilder.FundSiacoins(tpoolFee) 91 if err != nil { 92 return nil, err 93 } 94 err = txnBuilder.FundSiafunds(amount) 95 if err != nil { 96 return nil, err 97 } 98 txnBuilder.AddMinerFee(tpoolFee) 99 txnBuilder.AddSiafundOutput(output) 100 txnSet, err := txnBuilder.Sign(true) 101 if err != nil { 102 return nil, err 103 } 104 err = w.tpool.AcceptTransactionSet(txnSet) 105 if err != nil { 106 return nil, err 107 } 108 return txnSet, nil 109 } 110 111 // Len returns the number of elements in the sortedOutputs struct. 112 func (so sortedOutputs) Len() int { 113 if build.DEBUG && len(so.ids) != len(so.outputs) { 114 panic("sortedOutputs object is corrupt") 115 } 116 return len(so.ids) 117 } 118 119 // Less returns whether element 'i' is less than element 'j'. The currency 120 // value of each output is used for comparison. 121 func (so sortedOutputs) Less(i, j int) bool { 122 return so.outputs[i].Value.Cmp(so.outputs[j].Value) < 0 123 } 124 125 // Swap swaps two elements in the sortedOutputs set. 126 func (so sortedOutputs) Swap(i, j int) { 127 so.ids[i], so.ids[j] = so.ids[j], so.ids[i] 128 so.outputs[i], so.outputs[j] = so.outputs[j], so.outputs[i] 129 }