/
addfee.go
119 lines (103 loc) · 3.19 KB
/
addfee.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
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
// Copyright 2015 Factom Foundation
// Use of this source code is governed by the MIT
// license that can be found in the LICENSE file.
package main
import (
"bytes"
"encoding/hex"
"fmt"
fct "github.com/FactomProject/factoid"
"github.com/FactomProject/factoid/wallet"
"github.com/FactomProject/fctwallet/Wallet/Utility"
"strconv"
"strings"
)
/************************************************************
* AddFee
************************************************************/
type AddFee struct {
ICommand
}
// AddFee <key> <name|address> amount
//
//
func (AddFee) Execute(state IState, args []string) (err error) {
if len(args) != 3 && len(args) != 4 {
return fmt.Errorf("Invalid Parameters")
}
key := args[1]
adr := args[2]
rate := int64(0)
if len(args) == 4 {
srate, err := fct.ConvertFixedPoint(args[3])
if err != nil {
return fmt.Errorf("Could not parse exchange rate: %v", err)
}
rate, err = strconv.ParseInt(srate, 10, 64)
} else {
if rate, err = GetRate(state); err != nil {
return fmt.Errorf("Could not reach the server to get the exchange rate")
}
}
ib := state.GetFS().GetDB().GetRaw([]byte(fct.DB_BUILD_TRANS), []byte(key))
trans, ok := ib.(fct.ITransaction)
if ib == nil || !ok {
return fmt.Errorf("Unknown Transaction")
}
var addr fct.IAddress
if fct.ValidateFUserStr(adr) {
addr = fct.NewAddress(fct.ConvertUserStrToAddress(adr))
} else if Utility.IsValidHexAddress(adr) {
badr, _ := hex.DecodeString(adr)
addr = fct.NewAddress(badr)
} else if Utility.IsValidNickname(adr) {
we := state.GetFS().GetDB().GetRaw([]byte(fct.W_NAME), []byte(adr))
if we != nil {
we2 := we.(wallet.IWalletEntry)
addr, _ = we2.GetAddress()
adr = hex.EncodeToString(addr.Bytes())
} else {
return fmt.Errorf("Name is undefined.")
}
}
fee, err := trans.CalculateFee(uint64(rate))
var tin, tout, tec uint64
if tin, err = trans.TotalInputs(); err != nil {
return err
}
if tout, err = trans.TotalOutputs(); err != nil {
return err
}
if tec, err = trans.TotalECs(); err != nil {
return err
}
if tin != tout+tec {
msg := fmt.Sprintf("%s Total Inputs\n", fct.ConvertDecimal(tin))
msg += fmt.Sprintf("%s Total Outputs and Entry Credits\n", fct.ConvertDecimal(tout+tec))
msg += fmt.Sprintf("\nThe Inputs must match the outputs to use AddFee to add the fee to an input")
return fmt.Errorf(msg)
}
for _, input := range trans.GetInputs() {
if bytes.Equal(input.GetAddress().Bytes(), addr.Bytes()) {
input.SetAmount(input.GetAmount() + fee)
fmt.Printf("Added fee of %v\n", strings.TrimSpace(fct.ConvertDecimal(fee)))
break
}
}
return nil
}
func (AddFee) Name() string {
return "addfee"
}
func (AddFee) ShortHelp() string {
return "AddFee <key> <name/address> -- Adds a fee to the given input.\n" +
" Inputs must match Outputs, and the input address\n" +
" must be one of the inputs to the transaction\n"
}
func (AddFee) LongHelp() string {
return `
AddFee <key> <name> Adds a fee to the given transaction. The name must give
match an input to the transaction, and all the inputs
must equal the outputs.
`
}