rpc, cli: encode script in base64 for Invoke*
This commit is contained in:
parent
d58c50fb77
commit
c50f3db6ad
6 changed files with 38 additions and 33 deletions
|
@ -500,11 +500,7 @@ func invokeInternal(ctx *cli.Context, signAndPush bool) error {
|
|||
fmt.Fprintln(ctx.App.Writer, errText+". Sending transaction...")
|
||||
}
|
||||
if out := ctx.String("out"); out != "" {
|
||||
script, err := hex.DecodeString(resp.Script)
|
||||
if err != nil {
|
||||
return cli.NewExitError(fmt.Errorf("bad script returned from the RPC node: %w", err), 1)
|
||||
}
|
||||
tx, err := c.CreateTxFromScript(script, acc, resp.GasConsumed, int64(gas), cosigners...)
|
||||
tx, err := c.CreateTxFromScript(resp.Script, acc, resp.GasConsumed, int64(gas), cosigners...)
|
||||
if err != nil {
|
||||
return cli.NewExitError(fmt.Errorf("failed to create tx: %w", err), 1)
|
||||
}
|
||||
|
@ -518,11 +514,7 @@ func invokeInternal(ctx *cli.Context, signAndPush bool) error {
|
|||
if len(resp.Script) == 0 {
|
||||
return cli.NewExitError(errors.New("no script returned from the RPC node"), 1)
|
||||
}
|
||||
script, err := hex.DecodeString(resp.Script)
|
||||
if err != nil {
|
||||
return cli.NewExitError(fmt.Errorf("bad script returned from the RPC node: %w", err), 1)
|
||||
}
|
||||
txHash, err := c.SignAndPushInvocationTx(script, acc, resp.GasConsumed, gas, cosigners)
|
||||
txHash, err := c.SignAndPushInvocationTx(resp.Script, acc, resp.GasConsumed, gas, cosigners)
|
||||
if err != nil {
|
||||
return cli.NewExitError(fmt.Errorf("failed to push invocation tx: %w", err), 1)
|
||||
}
|
||||
|
|
|
@ -381,7 +381,7 @@ func (c *Client) GetVersion() (*result.Version, error) {
|
|||
// 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.
|
||||
func (c *Client) InvokeScript(script []byte, signers []transaction.Signer) (*result.Invoke, error) {
|
||||
var p = request.NewRawParams(hex.EncodeToString(script))
|
||||
var p = request.NewRawParams(script)
|
||||
return c.invokeSomething("invokescript", p, signers)
|
||||
}
|
||||
|
||||
|
|
|
@ -347,7 +347,7 @@ var rpcClientTestCases = map[string][]rpcClientTestCase{
|
|||
invoke: func(c *Client) (interface{}, error) {
|
||||
return c.GetFeePerByte()
|
||||
},
|
||||
serverResponse: `{"id":1,"jsonrpc":"2.0","result":{"state":"HALT","gasconsumed":"2007390","script":"10c00c0d676574466565506572427974650c149a61a46eec97b89306d7ce81f15b462091d0093241627d5b52","stack":[{"type":"Integer","value":"1000"}],"tx":null}}`,
|
||||
serverResponse: `{"id":1,"jsonrpc":"2.0","result":{"state":"HALT","gasconsumed":"2007390","script":"EMAMDWdldEZlZVBlckJ5dGUMFJphpG7sl7iTBtfOgfFbRiCR0AkyQWJ9W1I=","stack":[{"type":"Integer","value":"1000"}],"tx":null}}`,
|
||||
result: func(c *Client) interface{} {
|
||||
return int64(1000)
|
||||
},
|
||||
|
@ -359,7 +359,7 @@ var rpcClientTestCases = map[string][]rpcClientTestCase{
|
|||
invoke: func(c *Client) (interface{}, error) {
|
||||
return c.GetMaxTransactionsPerBlock()
|
||||
},
|
||||
serverResponse: `{"id":1,"jsonrpc":"2.0","result":{"state":"HALT","gasconsumed":"2007390","script":"10c00c1a6765744d61785472616e73616374696f6e73506572426c6f636b0c149a61a46eec97b89306d7ce81f15b462091d0093241627d5b52","stack":[{"type":"Integer","value":"512"}],"tx":null}}`,
|
||||
serverResponse: `{"id":1,"jsonrpc":"2.0","result":{"state":"HALT","gasconsumed":"2007390","script":"EMAMGmdldE1heFRyYW5zYWN0aW9uc1BlckJsb2NrDBSaYaRu7Je4kwbXzoHxW0YgkdAJMkFifVtS","stack":[{"type":"Integer","value":"512"}],"tx":null}}`,
|
||||
result: func(c *Client) interface{} {
|
||||
return int64(512)
|
||||
},
|
||||
|
@ -371,7 +371,7 @@ var rpcClientTestCases = map[string][]rpcClientTestCase{
|
|||
invoke: func(c *Client) (interface{}, error) {
|
||||
return c.GetMaxBlockSize()
|
||||
},
|
||||
serverResponse: `{"id":1,"jsonrpc":"2.0","result":{"state":"HALT","gasconsumed":"2007390","script":"10c00c0f6765744d6178426c6f636b53697a650c149a61a46eec97b89306d7ce81f15b462091d0093241627d5b52","stack":[{"type":"Integer","value":"262144"}],"tx":null}}`,
|
||||
serverResponse: `{"id":1,"jsonrpc":"2.0","result":{"state":"HALT","gasconsumed":"2007390","script":"EMAMD2dldE1heEJsb2NrU2l6ZQwUmmGkbuyXuJMG186B8VtGIJHQCTJBYn1bUg==","stack":[{"type":"Integer","value":"262144"}],"tx":null}}`,
|
||||
result: func(c *Client) interface{} {
|
||||
return int64(262144)
|
||||
},
|
||||
|
@ -383,7 +383,7 @@ var rpcClientTestCases = map[string][]rpcClientTestCase{
|
|||
invoke: func(c *Client) (interface{}, error) {
|
||||
return c.GetBlockedAccounts()
|
||||
},
|
||||
serverResponse: `{"id":1,"jsonrpc":"2.0","result":{"state":"HALT","gasconsumed":"2007390","script":"10c00c12676574426c6f636b65644163636f756e74730c149a61a46eec97b89306d7ce81f15b462091d0093241627d5b52","stack":[{"type":"Array","value":[]}],"tx":null}}`,
|
||||
serverResponse: `{"id":1,"jsonrpc":"2.0","result":{"state":"HALT","gasconsumed":"2007390","script":"EMAMEmdldEJsb2NrZWRBY2NvdW50cwwUmmGkbuyXuJMG186B8VtGIJHQCTJBYn1bUg==","stack":[{"type":"Array","value":[]}],"tx":null}}`,
|
||||
result: func(c *Client) interface{} {
|
||||
return native.BlockedAccounts{}
|
||||
},
|
||||
|
@ -663,7 +663,7 @@ var rpcClientTestCases = map[string][]rpcClientTestCase{
|
|||
Account: util.Uint160{1, 2, 3},
|
||||
}})
|
||||
},
|
||||
serverResponse: `{"jsonrpc":"2.0","id":1,"result":{"script":"01e8030c14aa8acf859d4fe402b34e673f2156821796a488eb0c14e79eb66d3c134a4a776ee807d2e5b846dda4fdb013c00c087472616e736665720c14e79eb66d3c134a4a776ee807d2e5b846dda4fdb041627d5b5238","state":"HALT","gasconsumed":"31100000","stack":[{"type":"ByteString","value":"JivsCEQy"}],"tx":"000800000080969800000000000204130000000000b004000001aa8acf859d4fe402b34e673f2156821796a488eb01005701e8030c14aa8acf859d4fe402b34e673f2156821796a488eb0c14e79eb66d3c134a4a776ee807d2e5b846dda4fdb013c00c087472616e736665720c14e79eb66d3c134a4a776ee807d2e5b846dda4fdb041627d5b523801420c40d83408774d4bd8b19ae870561d06f2744eb7678f58d1b90cf2f50e98ae83f60b0824e2feeadef6de6418a4cfc43bbc1f916c33ec594cbe662a9d924786e17a14290c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc20b4195440d78"}}`,
|
||||
serverResponse: `{"jsonrpc":"2.0","id":1,"result":{"script":"FCaufGyYYexBhGjB8P3Ep/KWPriRUcEJYmFsYW5jZU9mZ74557Vi9gy/4q68o3Wi5e4oc3yv","state":"HALT","gasconsumed":"31100000","stack":[{"type":"ByteString","value":"JivsCEQy"}],"tx":"000800000080969800000000000204130000000000b004000001aa8acf859d4fe402b34e673f2156821796a488eb01005701e8030c14aa8acf859d4fe402b34e673f2156821796a488eb0c14e79eb66d3c134a4a776ee807d2e5b846dda4fdb013c00c087472616e736665720c14e79eb66d3c134a4a776ee807d2e5b846dda4fdb041627d5b523801420c40d83408774d4bd8b19ae870561d06f2744eb7678f58d1b90cf2f50e98ae83f60b0824e2feeadef6de6418a4cfc43bbc1f916c33ec594cbe662a9d924786e17a14290c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc20b4195440d78"}}`,
|
||||
result: func(c *Client) interface{} {
|
||||
return &result.Invoke{}
|
||||
},
|
||||
|
@ -674,9 +674,13 @@ var rpcClientTestCases = map[string][]rpcClientTestCase{
|
|||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
script, err := base64.StdEncoding.DecodeString("FCaufGyYYexBhGjB8P3Ep/KWPriRUcEJYmFsYW5jZU9mZ74557Vi9gy/4q68o3Wi5e4oc3yv")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
assert.Equal(t, "HALT", res.State)
|
||||
assert.Equal(t, int64(31100000), res.GasConsumed)
|
||||
assert.Equal(t, "01e8030c14aa8acf859d4fe402b34e673f2156821796a488eb0c14e79eb66d3c134a4a776ee807d2e5b846dda4fdb013c00c087472616e736665720c14e79eb66d3c134a4a776ee807d2e5b846dda4fdb041627d5b5238", res.Script)
|
||||
assert.Equal(t, script, res.Script)
|
||||
assert.Equal(t, []stackitem.Item{stackitem.NewByteArray(bytes)}, res.Stack)
|
||||
assert.NotNil(t, res.Transaction)
|
||||
},
|
||||
|
@ -701,7 +705,7 @@ var rpcClientTestCases = map[string][]rpcClientTestCase{
|
|||
Account: util.Uint160{1, 2, 3},
|
||||
}})
|
||||
},
|
||||
serverResponse: `{"jsonrpc":"2.0","id":1,"result":{"script":"1426ae7c6c9861ec418468c1f0fdc4a7f2963eb89151c10962616c616e63654f6667be39e7b562f60cbfe2aebca375a2e5ee28737caf","state":"FAULT","gasconsumed":"31100000","stack":[{"type":"ByteString","value":"JivsCEQy"}],"tx":"000800000080969800000000000204130000000000b004000001aa8acf859d4fe402b34e673f2156821796a488eb01005701e8030c14aa8acf859d4fe402b34e673f2156821796a488eb0c14e79eb66d3c134a4a776ee807d2e5b846dda4fdb013c00c087472616e736665720c14e79eb66d3c134a4a776ee807d2e5b846dda4fdb041627d5b523801420c40d83408774d4bd8b19ae870561d06f2744eb7678f58d1b90cf2f50e98ae83f60b0824e2feeadef6de6418a4cfc43bbc1f916c33ec594cbe662a9d924786e17a14290c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc20b4195440d78","exception":"gas limit exceeded"}}`,
|
||||
serverResponse: `{"jsonrpc":"2.0","id":1,"result":{"script":"FCaufGyYYexBhGjB8P3Ep/KWPriRUcEJYmFsYW5jZU9mZ74557Vi9gy/4q68o3Wi5e4oc3yv","state":"FAULT","gasconsumed":"31100000","stack":[{"type":"ByteString","value":"JivsCEQy"}],"tx":"000800000080969800000000000204130000000000b004000001aa8acf859d4fe402b34e673f2156821796a488eb01005701e8030c14aa8acf859d4fe402b34e673f2156821796a488eb0c14e79eb66d3c134a4a776ee807d2e5b846dda4fdb013c00c087472616e736665720c14e79eb66d3c134a4a776ee807d2e5b846dda4fdb041627d5b523801420c40d83408774d4bd8b19ae870561d06f2744eb7678f58d1b90cf2f50e98ae83f60b0824e2feeadef6de6418a4cfc43bbc1f916c33ec594cbe662a9d924786e17a14290c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc20b4195440d78","exception":"gas limit exceeded"}}`,
|
||||
result: func(c *Client) interface{} {
|
||||
return &result.Invoke{}
|
||||
},
|
||||
|
@ -712,9 +716,13 @@ var rpcClientTestCases = map[string][]rpcClientTestCase{
|
|||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
script, err := base64.StdEncoding.DecodeString("FCaufGyYYexBhGjB8P3Ep/KWPriRUcEJYmFsYW5jZU9mZ74557Vi9gy/4q68o3Wi5e4oc3yv")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
assert.Equal(t, "FAULT", res.State)
|
||||
assert.Equal(t, int64(31100000), res.GasConsumed)
|
||||
assert.Equal(t, "1426ae7c6c9861ec418468c1f0fdc4a7f2963eb89151c10962616c616e63654f6667be39e7b562f60cbfe2aebca375a2e5ee28737caf", res.Script)
|
||||
assert.Equal(t, script, res.Script)
|
||||
assert.Equal(t, []stackitem.Item{stackitem.NewByteArray(bytes)}, res.Stack)
|
||||
assert.NotNil(t, res.Transaction)
|
||||
},
|
||||
|
@ -724,7 +732,7 @@ var rpcClientTestCases = map[string][]rpcClientTestCase{
|
|||
{
|
||||
name: "positive",
|
||||
invoke: func(c *Client) (interface{}, error) {
|
||||
script, err := hex.DecodeString("00046e616d656724058e5e1b6008847cd662728549088a9ee82191")
|
||||
script, err := base64.StdEncoding.DecodeString("AARuYW1lZyQFjl4bYAiEfNZicoVJCIqe6CGR")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
@ -732,16 +740,20 @@ var rpcClientTestCases = map[string][]rpcClientTestCase{
|
|||
Account: util.Uint160{1, 2, 3},
|
||||
}})
|
||||
},
|
||||
serverResponse: `{"jsonrpc":"2.0","id":1,"result":{"script":"00046e616d656724058e5e1b6008847cd662728549088a9ee82191","state":"HALT","gasconsumed":"16100000","stack":[{"type":"ByteString","value":"TkVQNSBHQVM="}],"tx":null}}`,
|
||||
serverResponse: `{"jsonrpc":"2.0","id":1,"result":{"script":"AARuYW1lZyQFjl4bYAiEfNZicoVJCIqe6CGR","state":"HALT","gasconsumed":"16100000","stack":[{"type":"ByteString","value":"TkVQNSBHQVM="}],"tx":null}}`,
|
||||
result: func(c *Client) interface{} {
|
||||
bytes, err := hex.DecodeString("4e45503520474153")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
script, err := base64.StdEncoding.DecodeString("AARuYW1lZyQFjl4bYAiEfNZicoVJCIqe6CGR")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return &result.Invoke{
|
||||
State: "HALT",
|
||||
GasConsumed: 16100000,
|
||||
Script: "00046e616d656724058e5e1b6008847cd662728549088a9ee82191",
|
||||
Script: script,
|
||||
Stack: []stackitem.Item{stackitem.NewByteArray(bytes)},
|
||||
}
|
||||
},
|
||||
|
|
|
@ -18,7 +18,7 @@ import (
|
|||
type Invoke struct {
|
||||
State string
|
||||
GasConsumed int64
|
||||
Script string
|
||||
Script []byte
|
||||
Stack []stackitem.Item
|
||||
FaultException string
|
||||
// Transaction represents transaction bytes. Use GetTransaction method to decode it.
|
||||
|
@ -28,7 +28,7 @@ type Invoke struct {
|
|||
type invokeAux struct {
|
||||
State string `json:"state"`
|
||||
GasConsumed int64 `json:"gasconsumed,string"`
|
||||
Script string `json:"script"`
|
||||
Script []byte `json:"script"`
|
||||
Stack json.RawMessage `json:"stack"`
|
||||
FaultException string `json:"exception,omitempty"`
|
||||
Transaction string `json:"tx,omitempty"`
|
||||
|
|
|
@ -977,7 +977,7 @@ func (s *Server) invokescript(reqParams request.Params) (interface{}, *response.
|
|||
return nil, response.ErrInvalidParams
|
||||
}
|
||||
|
||||
script, err := reqParams[0].GetBytesHex()
|
||||
script, err := reqParams[0].GetBytesBase64()
|
||||
if err != nil {
|
||||
return nil, response.ErrInvalidParams
|
||||
}
|
||||
|
@ -1011,7 +1011,7 @@ func (s *Server) runScriptInVM(script []byte, tx *transaction.Transaction) *resu
|
|||
result := &result.Invoke{
|
||||
State: vm.State().String(),
|
||||
GasConsumed: vm.GasConsumed(),
|
||||
Script: hex.EncodeToString(script),
|
||||
Script: script,
|
||||
Stack: vm.Estack().ToArray(),
|
||||
FaultException: faultException,
|
||||
}
|
||||
|
|
|
@ -60,6 +60,7 @@ const deploymentTxHash = "59f7b22b90e26f883a56b916c1580e3ee4f13caded686353cd7757
|
|||
|
||||
const verifyContractHash = "c1213693b22cb0454a436d6e0bd76b8c0a3bfdf7"
|
||||
const verifyContractAVM = "570300412d51083021700c14aa8acf859d4fe402b34e673f2156821796a488ebdb30716813cedb2869db289740"
|
||||
const testVerifyContractAVM = "VwcADBQBDAMOBQYMDQIODw0DDgcJAAAAANswcGgRVUH4J+yMIaonBwAAABFADBQNDwMCCQACAQMHAwQFAgEADgYMCdswcWkRVUH4J+yMIaonBwAAABJAE0A="
|
||||
|
||||
var rpcTestCases = map[string][]rpcTestCase{
|
||||
"getapplicationlog": {
|
||||
|
@ -537,7 +538,7 @@ var rpcTestCases = map[string][]rpcTestCase{
|
|||
check: func(t *testing.T, e *executor, inv interface{}) {
|
||||
res, ok := inv.(*result.Invoke)
|
||||
require.True(t, ok)
|
||||
assert.NotEqual(t, "", res.Script)
|
||||
assert.NotNil(t, res.Script)
|
||||
assert.NotEqual(t, "", res.State)
|
||||
assert.NotEqual(t, 0, res.GasConsumed)
|
||||
},
|
||||
|
@ -566,7 +567,7 @@ var rpcTestCases = map[string][]rpcTestCase{
|
|||
"invokescript": {
|
||||
{
|
||||
name: "positive",
|
||||
params: `["51c56b0d48656c6c6f2c20776f726c6421680f4e656f2e52756e74696d652e4c6f67616c7566"]`,
|
||||
params: `["UcVrDUhlbGxvLCB3b3JsZCFoD05lby5SdW50aW1lLkxvZ2FsdWY="]`,
|
||||
result: func(e *executor) interface{} { return &result.Invoke{} },
|
||||
check: func(t *testing.T, e *executor, inv interface{}) {
|
||||
res, ok := inv.(*result.Invoke)
|
||||
|
@ -578,8 +579,8 @@ var rpcTestCases = map[string][]rpcTestCase{
|
|||
},
|
||||
{
|
||||
name: "positive, good witness",
|
||||
// script is hex-encoded `test_verify.avm` representation, hashes are hex-encoded LE bytes of hashes used in the contract with `0x` prefix
|
||||
params: `["5707000c14010c030e05060c0d020e0f0d030e070900000000db307068115541f827ec8c21aa270700000011400c140d0f03020900020103070304050201000e060c09db307169115541f827ec8c21aa270700000012401340",["0x0000000009070e030d0f0e020d0c06050e030c01","0x090c060e00010205040307030102000902030f0d"]]`,
|
||||
// script is base64-encoded `test_verify.avm` representation, hashes are hex-encoded LE bytes of hashes used in the contract with `0x` prefix
|
||||
params: fmt.Sprintf(`["%s",["0x0000000009070e030d0f0e020d0c06050e030c01","0x090c060e00010205040307030102000902030f0d"]]`, testVerifyContractAVM),
|
||||
result: func(e *executor) interface{} { return &result.Invoke{} },
|
||||
check: func(t *testing.T, e *executor, inv interface{}) {
|
||||
res, ok := inv.(*result.Invoke)
|
||||
|
@ -591,7 +592,7 @@ var rpcTestCases = map[string][]rpcTestCase{
|
|||
},
|
||||
{
|
||||
name: "positive, bad witness of second hash",
|
||||
params: `["5707000c14010c030e05060c0d020e0f0d030e070900000000db307068115541f827ec8c21aa270700000011400c140d0f03020900020103070304050201000e060c09db307169115541f827ec8c21aa270700000012401340",["0x0000000009070e030d0f0e020d0c06050e030c01"]]`,
|
||||
params: fmt.Sprintf(`["%s",["0x0000000009070e030d0f0e020d0c06050e030c01"]]`, testVerifyContractAVM),
|
||||
result: func(e *executor) interface{} { return &result.Invoke{} },
|
||||
check: func(t *testing.T, e *executor, inv interface{}) {
|
||||
res, ok := inv.(*result.Invoke)
|
||||
|
@ -603,7 +604,7 @@ var rpcTestCases = map[string][]rpcTestCase{
|
|||
},
|
||||
{
|
||||
name: "positive, no good hashes",
|
||||
params: `["5707000c14010c030e05060c0d020e0f0d030e070900000000db307068115541f827ec8c21aa270700000011400c140d0f03020900020103070304050201000e060c09db307169115541f827ec8c21aa270700000012401340"]`,
|
||||
params: fmt.Sprintf(`["%s"]`, testVerifyContractAVM),
|
||||
result: func(e *executor) interface{} { return &result.Invoke{} },
|
||||
check: func(t *testing.T, e *executor, inv interface{}) {
|
||||
res, ok := inv.(*result.Invoke)
|
||||
|
@ -615,7 +616,7 @@ var rpcTestCases = map[string][]rpcTestCase{
|
|||
},
|
||||
{
|
||||
name: "positive, bad hashes witness",
|
||||
params: `["5707000c14010c030e05060c0d020e0f0d030e070900000000db307068115541f827ec8c21aa270700000011400c140d0f03020900020103070304050201000e060c09db307169115541f827ec8c21aa270700000012401340",["0x0000000009070e030d0f0e020d0c06050e030c02"]]`,
|
||||
params: fmt.Sprintf(`["%s",["0x0000000009070e030d0f0e020d0c06050e030c02"]]`, testVerifyContractAVM),
|
||||
result: func(e *executor) interface{} { return &result.Invoke{} },
|
||||
check: func(t *testing.T, e *executor, inv interface{}) {
|
||||
res, ok := inv.(*result.Invoke)
|
||||
|
|
Loading…
Reference in a new issue