From ca476cbf8a2048849d15973efeb0badc2d7d7819 Mon Sep 17 00:00:00 2001 From: Evgenii Stratonikov Date: Thu, 12 Mar 2020 19:41:54 +0300 Subject: [PATCH] cli: implement Fixed8Flag Parsing gas from float value is not always a right idea as a transform from float is not 1-to-1. This commit implements Fixed8Flag which parses Fixed8 value from string. --- cli/flags/fixed8.go | 75 +++++++++++++++++++++++++++++ cli/smartcontract/smart_contract.go | 6 +-- cli/wallet/nep5.go | 11 +---- 3 files changed, 80 insertions(+), 12 deletions(-) create mode 100644 cli/flags/fixed8.go diff --git a/cli/flags/fixed8.go b/cli/flags/fixed8.go new file mode 100644 index 000000000..5c199c16b --- /dev/null +++ b/cli/flags/fixed8.go @@ -0,0 +1,75 @@ +package flags + +import ( + "flag" + "strings" + + "github.com/nspcc-dev/neo-go/pkg/util" + "github.com/urfave/cli" +) + +// Fixed8 is a wrapper for Uint160 with flag.Value methods. +type Fixed8 struct { + Value util.Fixed8 +} + +// Fixed8Flag is a flag with type string. +type Fixed8Flag struct { + Name string + Usage string + Value Fixed8 +} + +var ( + _ flag.Value = (*Fixed8)(nil) + _ cli.Flag = Fixed8Flag{} +) + +// String implements fmt.Stringer interface. +func (a Fixed8) String() string { + return a.Value.String() +} + +// Set implements flag.Value interface. +func (a *Fixed8) Set(s string) error { + f, err := util.Fixed8FromString(s) + if err != nil { + return cli.NewExitError(err, 1) + } + a.Value = f + return nil +} + +// Fixed8 casts address to util.Fixed8. +func (a *Fixed8) Fixed8() util.Fixed8 { + return a.Value +} + +// String returns a readable representation of this value +// (for usage defaults). +func (f Fixed8Flag) String() string { + var names []string + eachName(f.Name, func(name string) { + names = append(names, getNameHelp(name)) + }) + + return strings.Join(names, ", ") + "\t" + f.Usage +} + +// GetName returns the name of the flag. +func (f Fixed8Flag) GetName() string { + return f.Name +} + +// Apply populates the flag given the flag set and environment +// Ignores errors. +func (f Fixed8Flag) Apply(set *flag.FlagSet) { + eachName(f.Name, func(name string) { + set.Var(&f.Value, name, f.Usage) + }) +} + +// Fixed8FromContext returns parsed util.Fixed8 value provided flag name. +func Fixed8FromContext(ctx *cli.Context, name string) util.Fixed8 { + return ctx.Generic(name).(*Fixed8Flag).Value.Fixed8() +} diff --git a/cli/smartcontract/smart_contract.go b/cli/smartcontract/smart_contract.go index 54efe463b..5de59e69e 100644 --- a/cli/smartcontract/smart_contract.go +++ b/cli/smartcontract/smart_contract.go @@ -51,7 +51,7 @@ var ( Name: "address, a", Usage: "address to use as transaction signee (and gas source)", } - gasFlag = cli.Float64Flag{ + gasFlag = flags.Fixed8Flag{ Name: "gas, g", Usage: "gas to add to the transaction", } @@ -411,7 +411,7 @@ func invokeInternal(ctx *cli.Context, withMethod bool, signAndPush bool) error { } if signAndPush { - gas = util.Fixed8FromFloat(ctx.Float64("gas")) + gas = flags.Fixed8FromContext(ctx, "gas") acc, err = getAccFromContext(ctx) if err != nil { return err @@ -593,7 +593,7 @@ func contractDeploy(ctx *cli.Context) error { if len(endpoint) == 0 { return cli.NewExitError(errNoEndpoint, 1) } - gas := util.Fixed8FromFloat(ctx.Float64("gas")) + gas := flags.Fixed8FromContext(ctx, "gas") acc, err := getAccFromContext(ctx) if err != nil { diff --git a/cli/wallet/nep5.go b/cli/wallet/nep5.go index dc738325b..5640c045f 100644 --- a/cli/wallet/nep5.go +++ b/cli/wallet/nep5.go @@ -85,7 +85,7 @@ func newNEP5Commands() []cli.Command { Name: "amount", Usage: "Amount of asset to send", }, - cli.StringFlag{ + flags.Fixed8Flag{ Name: "gas", Usage: "Amount of GAS to attach to a tx", }, @@ -309,14 +309,7 @@ func transferNEP5(ctx *cli.Context) error { emit.AppCall(w.BinWriter, token.Hash, false) emit.Opcode(w.BinWriter, opcode.THROWIFNOT) - var gas util.Fixed8 - if gasString := ctx.String("gas"); gasString != "" { - gas, err = util.Fixed8FromString(gasString) - if err != nil { - return cli.NewExitError(fmt.Errorf("invalid GAS amount: %v", err), 1) - } - } - + gas := flags.Fixed8FromContext(ctx, "gas") tx := transaction.NewInvocationTX(w.Bytes(), gas) tx.Attributes = append(tx.Attributes, transaction.Attribute{ Usage: transaction.Script,