cli/wallet: deduplicate some transfer code
This commit is contained in:
parent
3402b870c8
commit
f60fa02a96
2 changed files with 41 additions and 76 deletions
|
@ -9,18 +9,13 @@ import (
|
||||||
|
|
||||||
"github.com/nspcc-dev/neo-go/cli/cmdargs"
|
"github.com/nspcc-dev/neo-go/cli/cmdargs"
|
||||||
"github.com/nspcc-dev/neo-go/cli/flags"
|
"github.com/nspcc-dev/neo-go/cli/flags"
|
||||||
"github.com/nspcc-dev/neo-go/cli/input"
|
|
||||||
"github.com/nspcc-dev/neo-go/cli/options"
|
"github.com/nspcc-dev/neo-go/cli/options"
|
||||||
"github.com/nspcc-dev/neo-go/cli/paramcontext"
|
|
||||||
"github.com/nspcc-dev/neo-go/pkg/config"
|
"github.com/nspcc-dev/neo-go/pkg/config"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
|
|
||||||
"github.com/nspcc-dev/neo-go/pkg/encoding/address"
|
"github.com/nspcc-dev/neo-go/pkg/encoding/address"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/encoding/fixedn"
|
"github.com/nspcc-dev/neo-go/pkg/encoding/fixedn"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/rpcclient/actor"
|
|
||||||
"github.com/nspcc-dev/neo-go/pkg/rpcclient/invoker"
|
"github.com/nspcc-dev/neo-go/pkg/rpcclient/invoker"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/rpcclient/nep11"
|
"github.com/nspcc-dev/neo-go/pkg/rpcclient/nep11"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/manifest"
|
"github.com/nspcc-dev/neo-go/pkg/smartcontract/manifest"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
|
||||||
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
|
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/wallet"
|
"github.com/nspcc-dev/neo-go/pkg/wallet"
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli"
|
||||||
|
@ -262,48 +257,6 @@ func transferNEP11(ctx *cli.Context) error {
|
||||||
return transferNEP(ctx, manifest.NEP11StandardName)
|
return transferNEP(ctx, manifest.NEP11StandardName)
|
||||||
}
|
}
|
||||||
|
|
||||||
func signAndSendNEP11Transfer(ctx *cli.Context, act *actor.Actor, acc *wallet.Account, token, to util.Uint160, tokenID []byte, amount *big.Int, data interface{}) error {
|
|
||||||
var (
|
|
||||||
err error
|
|
||||||
gas = flags.Fixed8FromContext(ctx, "gas")
|
|
||||||
sysgas = flags.Fixed8FromContext(ctx, "sysgas")
|
|
||||||
tx *transaction.Transaction
|
|
||||||
)
|
|
||||||
if amount != nil {
|
|
||||||
n11 := nep11.NewDivisible(act, token)
|
|
||||||
tx, err = n11.TransferDUnsigned(act.Sender(), to, amount, tokenID, data)
|
|
||||||
} else {
|
|
||||||
n11 := nep11.NewNonDivisible(act, token)
|
|
||||||
tx, err = n11.TransferUnsigned(to, tokenID, data)
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
return cli.NewExitError(err, 1)
|
|
||||||
}
|
|
||||||
tx.SystemFee += int64(sysgas)
|
|
||||||
tx.NetworkFee += int64(gas)
|
|
||||||
|
|
||||||
if outFile := ctx.String("out"); outFile != "" {
|
|
||||||
ver := act.GetVersion()
|
|
||||||
// Make a long-lived transaction, it's to be signed manually.
|
|
||||||
tx.ValidUntilBlock += (ver.Protocol.MaxValidUntilBlockIncrement - uint32(ver.Protocol.ValidatorsCount)) - 2
|
|
||||||
err = paramcontext.InitAndSave(ver.Protocol.Network, tx, acc, outFile)
|
|
||||||
} else {
|
|
||||||
if !ctx.Bool("force") {
|
|
||||||
err := input.ConfirmTx(ctx.App.Writer, tx)
|
|
||||||
if err != nil {
|
|
||||||
return cli.NewExitError(err, 1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_, _, err = act.SignAndSend(tx)
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
return cli.NewExitError(err, 1)
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt.Fprintln(ctx.App.Writer, tx.Hash().StringLE())
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func printNEP11NDOwner(ctx *cli.Context) error {
|
func printNEP11NDOwner(ctx *cli.Context) error {
|
||||||
return printNEP11Owner(ctx, false)
|
return printNEP11Owner(ctx, false)
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,8 @@ import (
|
||||||
"github.com/nspcc-dev/neo-go/pkg/rpcclient/gas"
|
"github.com/nspcc-dev/neo-go/pkg/rpcclient/gas"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/rpcclient/invoker"
|
"github.com/nspcc-dev/neo-go/pkg/rpcclient/invoker"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/rpcclient/neo"
|
"github.com/nspcc-dev/neo-go/pkg/rpcclient/neo"
|
||||||
|
"github.com/nspcc-dev/neo-go/pkg/rpcclient/nep11"
|
||||||
|
"github.com/nspcc-dev/neo-go/pkg/rpcclient/nep17"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract"
|
"github.com/nspcc-dev/neo-go/pkg/smartcontract"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/manifest"
|
"github.com/nspcc-dev/neo-go/pkg/smartcontract/manifest"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||||
|
@ -558,7 +560,11 @@ func multiTransferNEP17(ctx *cli.Context) error {
|
||||||
return cli.NewExitError(fmt.Errorf("failed to create RPC actor: %w", err), 1)
|
return cli.NewExitError(fmt.Errorf("failed to create RPC actor: %w", err), 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
return signAndSendNEP17Transfer(ctx, act, acc, recipients)
|
tx, err := makeMultiTransferNEP17(act, recipients)
|
||||||
|
if err != nil {
|
||||||
|
return cli.NewExitError(fmt.Errorf("can't make transaction: %w", err), 1)
|
||||||
|
}
|
||||||
|
return signAndSendSomeTransaction(ctx, act, acc, tx)
|
||||||
}
|
}
|
||||||
|
|
||||||
func transferNEP17(ctx *cli.Context) error {
|
func transferNEP17(ctx *cli.Context) error {
|
||||||
|
@ -566,6 +572,8 @@ func transferNEP17(ctx *cli.Context) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func transferNEP(ctx *cli.Context, standard string) error {
|
func transferNEP(ctx *cli.Context, standard string) error {
|
||||||
|
var tx *transaction.Transaction
|
||||||
|
|
||||||
wall, pass, err := readWallet(ctx)
|
wall, pass, err := readWallet(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return cli.NewExitError(err, 1)
|
return cli.NewExitError(err, 1)
|
||||||
|
@ -621,44 +629,42 @@ func transferNEP(ctx *cli.Context, standard string) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
amountArg := ctx.String("amount")
|
amountArg := ctx.String("amount")
|
||||||
switch standard {
|
|
||||||
case manifest.NEP17StandardName:
|
|
||||||
amount, err := fixedn.FromString(amountArg, int(token.Decimals))
|
amount, err := fixedn.FromString(amountArg, int(token.Decimals))
|
||||||
if err != nil {
|
// It's OK for NEP-11 transfer to not have amount set.
|
||||||
|
if err != nil && (standard == manifest.NEP17StandardName || amountArg != "") {
|
||||||
return cli.NewExitError(fmt.Errorf("invalid amount: %w", err), 1)
|
return cli.NewExitError(fmt.Errorf("invalid amount: %w", err), 1)
|
||||||
}
|
}
|
||||||
return signAndSendNEP17Transfer(ctx, act, acc, []rpcclient.TransferTarget{{
|
switch standard {
|
||||||
Token: token.Hash,
|
case manifest.NEP17StandardName:
|
||||||
Address: to,
|
n17 := nep17.New(act, token.Hash)
|
||||||
Amount: amount.Int64(),
|
tx, err = n17.TransferUnsigned(act.Sender(), to, amount, data)
|
||||||
Data: data,
|
|
||||||
}})
|
|
||||||
case manifest.NEP11StandardName:
|
case manifest.NEP11StandardName:
|
||||||
tokenID := ctx.String("id")
|
tokenID := ctx.String("id")
|
||||||
if tokenID == "" {
|
if tokenID == "" {
|
||||||
return cli.NewExitError(errors.New("token ID should be specified"), 1)
|
return cli.NewExitError(errors.New("token ID should be specified"), 1)
|
||||||
}
|
}
|
||||||
tokenIDBytes, err := hex.DecodeString(tokenID)
|
tokenIDBytes, terr := hex.DecodeString(tokenID)
|
||||||
if err != nil {
|
if terr != nil {
|
||||||
return cli.NewExitError(fmt.Errorf("invalid token ID: %w", err), 1)
|
return cli.NewExitError(fmt.Errorf("invalid token ID: %w", terr), 1)
|
||||||
}
|
}
|
||||||
if amountArg == "" {
|
if amountArg == "" {
|
||||||
return signAndSendNEP11Transfer(ctx, act, acc, token.Hash, to, tokenIDBytes, nil, data)
|
n11 := nep11.NewNonDivisible(act, token.Hash)
|
||||||
|
tx, err = n11.TransferUnsigned(to, tokenIDBytes, data)
|
||||||
|
} else {
|
||||||
|
n11 := nep11.NewDivisible(act, token.Hash)
|
||||||
|
tx, err = n11.TransferDUnsigned(act.Sender(), to, amount, tokenIDBytes, data)
|
||||||
}
|
}
|
||||||
amount, err := fixedn.FromString(amountArg, int(token.Decimals))
|
|
||||||
if err != nil {
|
|
||||||
return cli.NewExitError(fmt.Errorf("invalid amount: %w", err), 1)
|
|
||||||
}
|
|
||||||
return signAndSendNEP11Transfer(ctx, act, acc, token.Hash, to, tokenIDBytes, amount, data)
|
|
||||||
default:
|
default:
|
||||||
return cli.NewExitError(fmt.Errorf("unsupported token standard %s", standard), 1)
|
return cli.NewExitError(fmt.Errorf("unsupported token standard %s", standard), 1)
|
||||||
}
|
}
|
||||||
|
if err != nil {
|
||||||
|
return cli.NewExitError(fmt.Errorf("can't make transaction: %w", err), 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
return signAndSendSomeTransaction(ctx, act, acc, tx)
|
||||||
}
|
}
|
||||||
|
|
||||||
func signAndSendNEP17Transfer(ctx *cli.Context, act *actor.Actor, acc *wallet.Account, recipients []rpcclient.TransferTarget) error {
|
func makeMultiTransferNEP17(act *actor.Actor, recipients []rpcclient.TransferTarget) (*transaction.Transaction, error) {
|
||||||
gas := flags.Fixed8FromContext(ctx, "gas")
|
|
||||||
sysgas := flags.Fixed8FromContext(ctx, "sysgas")
|
|
||||||
|
|
||||||
scr := smartcontract.NewBuilder()
|
scr := smartcontract.NewBuilder()
|
||||||
for i := range recipients {
|
for i := range recipients {
|
||||||
scr.InvokeWithAssert(recipients[i].Token, "transfer", act.Sender(),
|
scr.InvokeWithAssert(recipients[i].Token, "transfer", act.Sender(),
|
||||||
|
@ -666,12 +672,18 @@ func signAndSendNEP17Transfer(ctx *cli.Context, act *actor.Actor, acc *wallet.Ac
|
||||||
}
|
}
|
||||||
script, err := scr.Script()
|
script, err := scr.Script()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return nil, err
|
||||||
}
|
|
||||||
tx, err := act.MakeUnsignedRun(script, nil)
|
|
||||||
if err != nil {
|
|
||||||
return cli.NewExitError(err, 1)
|
|
||||||
}
|
}
|
||||||
|
return act.MakeUnsignedRun(script, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
func signAndSendSomeTransaction(ctx *cli.Context, act *actor.Actor, acc *wallet.Account, tx *transaction.Transaction) error {
|
||||||
|
var (
|
||||||
|
err error
|
||||||
|
gas = flags.Fixed8FromContext(ctx, "gas")
|
||||||
|
sysgas = flags.Fixed8FromContext(ctx, "sysgas")
|
||||||
|
)
|
||||||
|
|
||||||
tx.SystemFee += int64(sysgas)
|
tx.SystemFee += int64(sysgas)
|
||||||
tx.NetworkFee += int64(gas)
|
tx.NetworkFee += int64(gas)
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue