forked from TrueCloudLab/neoneo-go
Merge pull request #1139 from nspcc-dev/fix-deployment-sysfee-and-invokes
Fix deployment sysfee and invokes
This commit is contained in:
commit
6cd166fb7a
6 changed files with 63 additions and 50 deletions
|
@ -399,8 +399,10 @@ func invokeInternal(ctx *cli.Context, signAndPush bool) error {
|
||||||
if !args.Present() {
|
if !args.Present() {
|
||||||
return cli.NewExitError(errNoScriptHash, 1)
|
return cli.NewExitError(errNoScriptHash, 1)
|
||||||
}
|
}
|
||||||
script := args[0]
|
script, err := util.Uint160DecodeStringLE(args[0])
|
||||||
|
if err != nil {
|
||||||
|
return cli.NewExitError(fmt.Errorf("incorrect script hash: %v", err), 1)
|
||||||
|
}
|
||||||
if len(args) <= 1 {
|
if len(args) <= 1 {
|
||||||
return cli.NewExitError(errNoMethod, 1)
|
return cli.NewExitError(errNoMethod, 1)
|
||||||
}
|
}
|
||||||
|
@ -510,8 +512,7 @@ func testInvokeScript(ctx *cli.Context) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
scriptHex := hex.EncodeToString(nefFile.Script)
|
resp, err := c.InvokeScript(nefFile.Script, cosigners)
|
||||||
resp, err := c.InvokeScript(scriptHex, cosigners)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return cli.NewExitError(err, 1)
|
return cli.NewExitError(err, 1)
|
||||||
}
|
}
|
||||||
|
@ -654,12 +655,17 @@ func contractDeploy(ctx *cli.Context) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
txScript, sysfee, err := request.CreateDeploymentScript(nefFile.Script, m)
|
txScript, err := request.CreateDeploymentScript(nefFile.Script, m)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return cli.NewExitError(fmt.Errorf("failed to create deployment script: %v", err), 1)
|
return cli.NewExitError(fmt.Errorf("failed to create deployment script: %v", err), 1)
|
||||||
}
|
}
|
||||||
|
// It doesn't require any cosigners.
|
||||||
|
invRes, err := c.InvokeScript(txScript, nil)
|
||||||
|
if err != nil {
|
||||||
|
return cli.NewExitError(fmt.Errorf("failed to test-invoke deployment script: %v", err), 1)
|
||||||
|
}
|
||||||
|
|
||||||
txHash, err := c.SignAndPushInvocationTx(txScript, acc, sysfee, gas)
|
txHash, err := c.SignAndPushInvocationTx(txScript, acc, invRes.GasConsumed, gas)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return cli.NewExitError(fmt.Errorf("failed to push invocation tx: %v", err), 1)
|
return cli.NewExitError(fmt.Errorf("failed to push invocation tx: %v", err), 1)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package client
|
package client
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/hex"
|
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
|
@ -25,7 +24,7 @@ var (
|
||||||
|
|
||||||
// NEP5Decimals invokes `decimals` NEP5 method on a specified contract.
|
// NEP5Decimals invokes `decimals` NEP5 method on a specified contract.
|
||||||
func (c *Client) NEP5Decimals(tokenHash util.Uint160) (int64, error) {
|
func (c *Client) NEP5Decimals(tokenHash util.Uint160) (int64, error) {
|
||||||
result, err := c.InvokeFunction(tokenHash.StringLE(), "decimals", []smartcontract.Parameter{}, nil)
|
result, err := c.InvokeFunction(tokenHash, "decimals", []smartcontract.Parameter{}, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
} else if result.State != "HALT" || len(result.Stack) == 0 {
|
} else if result.State != "HALT" || len(result.Stack) == 0 {
|
||||||
|
@ -37,7 +36,7 @@ func (c *Client) NEP5Decimals(tokenHash util.Uint160) (int64, error) {
|
||||||
|
|
||||||
// NEP5Name invokes `name` NEP5 method on a specified contract.
|
// NEP5Name invokes `name` NEP5 method on a specified contract.
|
||||||
func (c *Client) NEP5Name(tokenHash util.Uint160) (string, error) {
|
func (c *Client) NEP5Name(tokenHash util.Uint160) (string, error) {
|
||||||
result, err := c.InvokeFunction(tokenHash.StringLE(), "name", []smartcontract.Parameter{}, nil)
|
result, err := c.InvokeFunction(tokenHash, "name", []smartcontract.Parameter{}, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
} else if result.State != "HALT" || len(result.Stack) == 0 {
|
} else if result.State != "HALT" || len(result.Stack) == 0 {
|
||||||
|
@ -49,7 +48,7 @@ func (c *Client) NEP5Name(tokenHash util.Uint160) (string, error) {
|
||||||
|
|
||||||
// NEP5Symbol invokes `symbol` NEP5 method on a specified contract.
|
// NEP5Symbol invokes `symbol` NEP5 method on a specified contract.
|
||||||
func (c *Client) NEP5Symbol(tokenHash util.Uint160) (string, error) {
|
func (c *Client) NEP5Symbol(tokenHash util.Uint160) (string, error) {
|
||||||
result, err := c.InvokeFunction(tokenHash.StringLE(), "symbol", []smartcontract.Parameter{}, nil)
|
result, err := c.InvokeFunction(tokenHash, "symbol", []smartcontract.Parameter{}, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
} else if result.State != "HALT" || len(result.Stack) == 0 {
|
} else if result.State != "HALT" || len(result.Stack) == 0 {
|
||||||
|
@ -61,7 +60,7 @@ func (c *Client) NEP5Symbol(tokenHash util.Uint160) (string, error) {
|
||||||
|
|
||||||
// NEP5TotalSupply invokes `totalSupply` NEP5 method on a specified contract.
|
// NEP5TotalSupply invokes `totalSupply` NEP5 method on a specified contract.
|
||||||
func (c *Client) NEP5TotalSupply(tokenHash util.Uint160) (int64, error) {
|
func (c *Client) NEP5TotalSupply(tokenHash util.Uint160) (int64, error) {
|
||||||
result, err := c.InvokeFunction(tokenHash.StringLE(), "totalSupply", []smartcontract.Parameter{}, nil)
|
result, err := c.InvokeFunction(tokenHash, "totalSupply", []smartcontract.Parameter{}, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
} else if result.State != "HALT" || len(result.Stack) == 0 {
|
} else if result.State != "HALT" || len(result.Stack) == 0 {
|
||||||
|
@ -73,7 +72,7 @@ func (c *Client) NEP5TotalSupply(tokenHash util.Uint160) (int64, error) {
|
||||||
|
|
||||||
// NEP5BalanceOf invokes `balanceOf` NEP5 method on a specified contract.
|
// NEP5BalanceOf invokes `balanceOf` NEP5 method on a specified contract.
|
||||||
func (c *Client) NEP5BalanceOf(tokenHash util.Uint160) (int64, error) {
|
func (c *Client) NEP5BalanceOf(tokenHash util.Uint160) (int64, error) {
|
||||||
result, err := c.InvokeFunction(tokenHash.StringLE(), "balanceOf", []smartcontract.Parameter{}, nil)
|
result, err := c.InvokeFunction(tokenHash, "balanceOf", []smartcontract.Parameter{}, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
} else if result.State != "HALT" || len(result.Stack) == 0 {
|
} else if result.State != "HALT" || len(result.Stack) == 0 {
|
||||||
|
@ -127,7 +126,7 @@ func (c *Client) CreateNEP5TransferTx(acc *wallet.Account, to util.Uint160, toke
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
result, err := c.InvokeScript(hex.EncodeToString(script), []transaction.Cosigner{
|
result, err := c.InvokeScript(script, []transaction.Cosigner{
|
||||||
{
|
{
|
||||||
Account: from,
|
Account: from,
|
||||||
Scopes: transaction.Global,
|
Scopes: transaction.Global,
|
||||||
|
|
|
@ -29,7 +29,7 @@ func (c *Client) GetFeePerByte() (int64, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Client) invokeNativePolicyMethod(operation string) (int64, error) {
|
func (c *Client) invokeNativePolicyMethod(operation string) (int64, error) {
|
||||||
result, err := c.InvokeFunction(PolicyContractHash.StringLE(), operation, []smartcontract.Parameter{}, nil)
|
result, err := c.InvokeFunction(PolicyContractHash, operation, []smartcontract.Parameter{}, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
} else if result.State != "HALT" || len(result.Stack) == 0 {
|
} else if result.State != "HALT" || len(result.Stack) == 0 {
|
||||||
|
@ -41,7 +41,7 @@ func (c *Client) invokeNativePolicyMethod(operation string) (int64, error) {
|
||||||
|
|
||||||
// GetBlockedAccounts invokes `getBlockedAccounts` method on a native Policy contract.
|
// GetBlockedAccounts invokes `getBlockedAccounts` method on a native Policy contract.
|
||||||
func (c *Client) GetBlockedAccounts() (native.BlockedAccounts, error) {
|
func (c *Client) GetBlockedAccounts() (native.BlockedAccounts, error) {
|
||||||
result, err := c.InvokeFunction(PolicyContractHash.StringLE(), "getBlockedAccounts", []smartcontract.Parameter{}, nil)
|
result, err := c.InvokeFunction(PolicyContractHash, "getBlockedAccounts", []smartcontract.Parameter{}, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
} else if result.State != "HALT" || len(result.Stack) == 0 {
|
} else if result.State != "HALT" || len(result.Stack) == 0 {
|
||||||
|
|
|
@ -349,36 +349,38 @@ func (c *Client) GetVersion() (*result.Version, error) {
|
||||||
|
|
||||||
// InvokeScript returns the result of the given script after running it true the VM.
|
// InvokeScript returns the result of the given script after running it true the VM.
|
||||||
// NOTE: This is a test invoke and will not affect the blockchain.
|
// NOTE: This is a test invoke and will not affect the blockchain.
|
||||||
func (c *Client) InvokeScript(script string, cosigners []transaction.Cosigner) (*result.Invoke, error) {
|
func (c *Client) InvokeScript(script []byte, cosigners []transaction.Cosigner) (*result.Invoke, error) {
|
||||||
var (
|
var p = request.NewRawParams(hex.EncodeToString(script))
|
||||||
params request.RawParams
|
return c.invokeSomething("invokescript", p, cosigners)
|
||||||
resp = &result.Invoke{}
|
|
||||||
)
|
|
||||||
if cosigners != nil {
|
|
||||||
params = request.NewRawParams(script, cosigners)
|
|
||||||
} else {
|
|
||||||
params = request.NewRawParams(script)
|
|
||||||
}
|
|
||||||
if err := c.performRequest("invokescript", params, resp); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return resp, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// InvokeFunction returns the results after calling the smart contract scripthash
|
// InvokeFunction returns the results after calling the smart contract scripthash
|
||||||
// with the given operation and parameters.
|
// with the given operation and parameters.
|
||||||
// NOTE: this is test invoke and will not affect the blockchain.
|
// NOTE: this is test invoke and will not affect the blockchain.
|
||||||
func (c *Client) InvokeFunction(script, operation string, params []smartcontract.Parameter, cosigners []transaction.Cosigner) (*result.Invoke, error) {
|
func (c *Client) InvokeFunction(contract util.Uint160, operation string, params []smartcontract.Parameter, cosigners []transaction.Cosigner) (*result.Invoke, error) {
|
||||||
var (
|
var p = request.NewRawParams(contract.StringLE(), operation, params)
|
||||||
p request.RawParams
|
return c.invokeSomething("invokefunction", p, cosigners)
|
||||||
resp = &result.Invoke{}
|
}
|
||||||
)
|
|
||||||
if cosigners != nil {
|
// invokeSomething is an inner wrapper for Invoke* functions
|
||||||
p = request.NewRawParams(script, operation, params, cosigners)
|
func (c *Client) invokeSomething(method string, p request.RawParams, cosigners []transaction.Cosigner) (*result.Invoke, error) {
|
||||||
} else {
|
var resp = new(result.Invoke)
|
||||||
p = request.NewRawParams(script, operation, params)
|
if cosigners != nil {
|
||||||
|
p.Values = append(p.Values, cosigners)
|
||||||
|
}
|
||||||
|
if err := c.performRequest(method, p, resp); err != nil {
|
||||||
|
// Retry with old-fashioned hashes (see neo/neo-modules#260).
|
||||||
|
if cosigners != nil {
|
||||||
|
var hashes = make([]util.Uint160, len(cosigners))
|
||||||
|
for i := range cosigners {
|
||||||
|
hashes[i] = cosigners[i].Account
|
||||||
|
}
|
||||||
|
p.Values[len(p.Values)-1] = hashes
|
||||||
|
err = c.performRequest(method, p, resp)
|
||||||
|
if err == nil {
|
||||||
|
return resp, nil
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if err := c.performRequest("invokefunction", p, resp); err != nil {
|
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return resp, nil
|
return resp, nil
|
||||||
|
|
|
@ -616,7 +616,11 @@ var rpcClientTestCases = map[string][]rpcClientTestCase{
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
return c.InvokeFunction("af7c7328eee5a275a3bcaee2bf0cf662b5e739be", "balanceOf", []smartcontract.Parameter{
|
contr, err := util.Uint160DecodeStringLE("af7c7328eee5a275a3bcaee2bf0cf662b5e739be")
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
return c.InvokeFunction(contr, "balanceOf", []smartcontract.Parameter{
|
||||||
{
|
{
|
||||||
Type: smartcontract.Hash160Type,
|
Type: smartcontract.Hash160Type,
|
||||||
Value: hash,
|
Value: hash,
|
||||||
|
@ -649,7 +653,11 @@ var rpcClientTestCases = map[string][]rpcClientTestCase{
|
||||||
{
|
{
|
||||||
name: "positive",
|
name: "positive",
|
||||||
invoke: func(c *Client) (interface{}, error) {
|
invoke: func(c *Client) (interface{}, error) {
|
||||||
return c.InvokeScript("00046e616d656724058e5e1b6008847cd662728549088a9ee82191", []transaction.Cosigner{{
|
script, err := hex.DecodeString("00046e616d656724058e5e1b6008847cd662728549088a9ee82191")
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
return c.InvokeScript(script, []transaction.Cosigner{{
|
||||||
Account: util.Uint160{1, 2, 3},
|
Account: util.Uint160{1, 2, 3},
|
||||||
}})
|
}})
|
||||||
},
|
},
|
||||||
|
@ -952,13 +960,13 @@ var rpcClientErrorCases = map[string][]rpcClientErrorCase{
|
||||||
{
|
{
|
||||||
name: "invokefunction_invalid_params_error",
|
name: "invokefunction_invalid_params_error",
|
||||||
invoke: func(c *Client) (interface{}, error) {
|
invoke: func(c *Client) (interface{}, error) {
|
||||||
return c.InvokeFunction("", "", []smartcontract.Parameter{}, nil)
|
return c.InvokeFunction(util.Uint160{}, "", []smartcontract.Parameter{}, nil)
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "invokescript_invalid_params_error",
|
name: "invokescript_invalid_params_error",
|
||||||
invoke: func(c *Client) (interface{}, error) {
|
invoke: func(c *Client) (interface{}, error) {
|
||||||
return c.InvokeScript("", nil)
|
return c.InvokeScript([]byte{}, nil)
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -1134,13 +1142,13 @@ var rpcClientErrorCases = map[string][]rpcClientErrorCase{
|
||||||
{
|
{
|
||||||
name: "invokefunction_unmarshalling_error",
|
name: "invokefunction_unmarshalling_error",
|
||||||
invoke: func(c *Client) (interface{}, error) {
|
invoke: func(c *Client) (interface{}, error) {
|
||||||
return c.InvokeFunction("", "", []smartcontract.Parameter{}, nil)
|
return c.InvokeFunction(util.Uint160{}, "", []smartcontract.Parameter{}, nil)
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "invokescript_unmarshalling_error",
|
name: "invokescript_unmarshalling_error",
|
||||||
invoke: func(c *Client) (interface{}, error) {
|
invoke: func(c *Client) (interface{}, error) {
|
||||||
return c.InvokeScript("", nil)
|
return c.InvokeScript([]byte{}, nil)
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
@ -5,7 +5,6 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core"
|
|
||||||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/io"
|
"github.com/nspcc-dev/neo-go/pkg/io"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract"
|
"github.com/nspcc-dev/neo-go/pkg/smartcontract"
|
||||||
|
@ -16,18 +15,17 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
// CreateDeploymentScript returns a script that deploys given smart contract
|
// CreateDeploymentScript returns a script that deploys given smart contract
|
||||||
// with its metadata and system fee require for this.
|
// with its metadata.
|
||||||
func CreateDeploymentScript(avm []byte, manif *manifest.Manifest) ([]byte, int64, error) {
|
func CreateDeploymentScript(avm []byte, manif *manifest.Manifest) ([]byte, error) {
|
||||||
script := io.NewBufBinWriter()
|
script := io.NewBufBinWriter()
|
||||||
rawManifest, err := manif.MarshalJSON()
|
rawManifest, err := manif.MarshalJSON()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, 0, err
|
return nil, err
|
||||||
}
|
}
|
||||||
emit.Bytes(script.BinWriter, rawManifest)
|
emit.Bytes(script.BinWriter, rawManifest)
|
||||||
emit.Bytes(script.BinWriter, avm)
|
emit.Bytes(script.BinWriter, avm)
|
||||||
emit.Syscall(script.BinWriter, "System.Contract.Create")
|
emit.Syscall(script.BinWriter, "System.Contract.Create")
|
||||||
sysfee := int64(core.StoragePrice * (len(avm) + len(rawManifest)))
|
return script.Bytes(), nil
|
||||||
return script.Bytes(), sysfee, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// expandArrayIntoScript pushes all FuncParam parameters from the given array
|
// expandArrayIntoScript pushes all FuncParam parameters from the given array
|
||||||
|
|
Loading…
Reference in a new issue