From 1880e96844ac0962daf49f5ff9503928fa15a73b Mon Sep 17 00:00:00 2001 From: Anna Shaleva Date: Mon, 6 Jul 2020 10:01:14 +0300 Subject: [PATCH 1/4] cli: fix contract deploy&invoke We should add cosigners to deplyment and invocation transactions. --- cli/smartcontract/smart_contract.go | 4 ++-- pkg/rpc/client/rpc.go | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/cli/smartcontract/smart_contract.go b/cli/smartcontract/smart_contract.go index a1575755b..10ca9c2cf 100644 --- a/cli/smartcontract/smart_contract.go +++ b/cli/smartcontract/smart_contract.go @@ -460,7 +460,7 @@ func invokeInternal(ctx *cli.Context, signAndPush bool) error { if err != nil { return cli.NewExitError(fmt.Errorf("bad script returned from the RPC node: %v", err), 1) } - txHash, err := c.SignAndPushInvocationTx(script, acc, 0, gas) + txHash, err := c.SignAndPushInvocationTx(script, acc, 0, gas, cosigners) if err != nil { return cli.NewExitError(fmt.Errorf("failed to push invocation tx: %v", err), 1) } @@ -665,7 +665,7 @@ func contractDeploy(ctx *cli.Context) error { return cli.NewExitError(fmt.Errorf("failed to test-invoke deployment script: %v", err), 1) } - txHash, err := c.SignAndPushInvocationTx(txScript, acc, invRes.GasConsumed, gas) + txHash, err := c.SignAndPushInvocationTx(txScript, acc, invRes.GasConsumed, gas, nil) if err != nil { return cli.NewExitError(fmt.Errorf("failed to push invocation tx: %v", err), 1) } diff --git a/pkg/rpc/client/rpc.go b/pkg/rpc/client/rpc.go index 7aac5ff41..0bb161b96 100644 --- a/pkg/rpc/client/rpc.go +++ b/pkg/rpc/client/rpc.go @@ -429,12 +429,13 @@ func (c *Client) SubmitBlock(b block.Block) error { // SignAndPushInvocationTx signs and pushes given script as an invocation // transaction using given wif to sign it and spending the amount of gas // specified. It returns a hash of the invocation transaction and an error. -func (c *Client) SignAndPushInvocationTx(script []byte, acc *wallet.Account, sysfee int64, netfee util.Fixed8) (util.Uint256, error) { +func (c *Client) SignAndPushInvocationTx(script []byte, acc *wallet.Account, sysfee int64, netfee util.Fixed8, cosigners []transaction.Cosigner) (util.Uint256, error) { var txHash util.Uint256 var err error tx := transaction.New(c.opts.Network, script, sysfee) tx.SystemFee = sysfee + tx.Cosigners = cosigners validUntilBlock, err := c.CalculateValidUntilBlock() if err != nil { From 3c551788c97cfeabfecb04b063fafcd1c9d6d271 Mon Sep 17 00:00:00 2001 From: Anna Shaleva Date: Fri, 3 Jul 2020 23:35:22 +0300 Subject: [PATCH 2/4] cli: fix parseCosigner method --- cli/smartcontract/smart_contract.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cli/smartcontract/smart_contract.go b/cli/smartcontract/smart_contract.go index 10ca9c2cf..fe8b15a6c 100644 --- a/cli/smartcontract/smart_contract.go +++ b/cli/smartcontract/smart_contract.go @@ -427,7 +427,7 @@ func invokeInternal(ctx *cli.Context, signAndPush bool) error { for i, c := range args[cosignersStart:] { cosigner, err := parseCosigner(c) if err != nil { - return cli.NewExitError(fmt.Errorf("failed to parse cosigner #%d: %v", i+cosignersStart+1, err), 1) + return cli.NewExitError(fmt.Errorf("failed to parse cosigner #%d: %v", i+1, err), 1) } cosigners = append(cosigners, cosigner) } @@ -692,7 +692,7 @@ func parseCosigner(c string) (transaction.Cosigner, error) { err error res = transaction.Cosigner{} ) - data := strings.SplitN(strings.ToLower(c), ":", 2) + data := strings.SplitN(c, ":", 2) s := data[0] if len(s) == 2*util.Uint160Size+2 && s[0:2] == "0x" { s = s[2:] From 966ad8a0b15279bb77eb7a051e86f8ffebca35c7 Mon Sep 17 00:00:00 2001 From: Anna Shaleva Date: Mon, 6 Jul 2020 10:49:24 +0300 Subject: [PATCH 3/4] rpc: fix adding extra network fee to tx --- pkg/rpc/client/nep5.go | 23 ++++++++--------------- pkg/rpc/client/rpc.go | 9 +++++---- 2 files changed, 13 insertions(+), 19 deletions(-) diff --git a/pkg/rpc/client/nep5.go b/pkg/rpc/client/nep5.go index b8b84722d..e921871cc 100644 --- a/pkg/rpc/client/nep5.go +++ b/pkg/rpc/client/nep5.go @@ -115,17 +115,6 @@ func (c *Client) CreateNEP5TransferTx(acc *wallet.Account, to util.Uint160, toke emit.Opcode(w.BinWriter, opcode.ASSERT) script := w.Bytes() - tx := transaction.New(c.opts.Network, script, gas) - tx.Sender = from - tx.Cosigners = []transaction.Cosigner{ - { - Account: from, - Scopes: transaction.CalledByEntry, - AllowedContracts: nil, - AllowedGroups: nil, - }, - } - result, err := c.InvokeScript(script, []transaction.Cosigner{ { Account: from, @@ -135,16 +124,20 @@ func (c *Client) CreateNEP5TransferTx(acc *wallet.Account, to util.Uint160, toke if err != nil { return nil, fmt.Errorf("can't add system fee to transaction: %v", err) } - if result.GasConsumed > 0 { - tx.SystemFee = result.GasConsumed + tx := transaction.New(c.opts.Network, script, result.GasConsumed) + tx.Sender = from + tx.Cosigners = []transaction.Cosigner{ + { + Account: from, + Scopes: transaction.CalledByEntry, + }, } - tx.ValidUntilBlock, err = c.CalculateValidUntilBlock() if err != nil { return nil, fmt.Errorf("can't calculate validUntilBlock: %v", err) } - err = c.AddNetworkFee(tx, acc) + err = c.AddNetworkFee(tx, gas, acc) if err != nil { return nil, fmt.Errorf("can't add network fee to transaction: %v", err) } diff --git a/pkg/rpc/client/rpc.go b/pkg/rpc/client/rpc.go index 0bb161b96..d734d1104 100644 --- a/pkg/rpc/client/rpc.go +++ b/pkg/rpc/client/rpc.go @@ -449,7 +449,7 @@ func (c *Client) SignAndPushInvocationTx(script []byte, acc *wallet.Account, sys } tx.Sender = addr - err = c.AddNetworkFee(tx, acc) + err = c.AddNetworkFee(tx, int64(netfee), acc) if err != nil { return txHash, errors.Wrapf(err, "failed to add network fee") } @@ -512,8 +512,9 @@ func (c *Client) CalculateValidUntilBlock() (uint32, error) { return blockCount + validatorsCount, nil } -// AddNetworkFee adds network fee for each witness script to transaction. -func (c *Client) AddNetworkFee(tx *transaction.Transaction, acc *wallet.Account) error { +// AddNetworkFee adds network fee for each witness script and optional extra +// network fee to transaction. +func (c *Client) AddNetworkFee(tx *transaction.Transaction, extraFee int64, acc *wallet.Account) error { size := io.GetVarSize(tx) if acc.Contract != nil { netFee, sizeDelta := core.CalculateNetworkFee(acc.Contract.Script) @@ -540,6 +541,6 @@ func (c *Client) AddNetworkFee(tx *transaction.Transaction, acc *wallet.Account) if err != nil { return err } - tx.NetworkFee += int64(size) * fee + tx.NetworkFee += int64(size)*fee + extraFee return nil } From 7b90ad9337cce840cc00bb60a4de4e6190cea886 Mon Sep 17 00:00:00 2001 From: Anna Shaleva Date: Mon, 6 Jul 2020 11:03:21 +0300 Subject: [PATCH 4/4] rpc: fix cosigner scope in CreateNEP5TransferTx It should be the same as transaction's cosigner scope. --- pkg/rpc/client/nep5.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/rpc/client/nep5.go b/pkg/rpc/client/nep5.go index e921871cc..673503cce 100644 --- a/pkg/rpc/client/nep5.go +++ b/pkg/rpc/client/nep5.go @@ -118,7 +118,7 @@ func (c *Client) CreateNEP5TransferTx(acc *wallet.Account, to util.Uint160, toke result, err := c.InvokeScript(script, []transaction.Cosigner{ { Account: from, - Scopes: transaction.Global, + Scopes: transaction.CalledByEntry, }, }) if err != nil {