Merge pull request #2558 from nspcc-dev/rpc/fix-signature-decoding
rpc: fix compatibility issues of `CreateFunctionInvocationScript`
This commit is contained in:
commit
299d55e539
2 changed files with 40 additions and 25 deletions
|
@ -29,7 +29,7 @@ func ExpandArrayIntoScript(script *io.BinWriter, slice []Param) error {
|
||||||
}
|
}
|
||||||
emit.Bytes(script, str)
|
emit.Bytes(script, str)
|
||||||
case smartcontract.SignatureType:
|
case smartcontract.SignatureType:
|
||||||
str, err := fp.Value.GetBytesHex()
|
str, err := fp.Value.GetBytesBase64()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -83,12 +83,10 @@ func ExpandArrayIntoScript(script *io.BinWriter, slice []Param) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
err = ExpandArrayIntoScript(script, val)
|
err = ExpandArrayIntoScriptAndPack(script, val)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
emit.Int(script, int64(len(val)))
|
|
||||||
emit.Opcodes(script, opcode.PACK)
|
|
||||||
case smartcontract.AnyType:
|
case smartcontract.AnyType:
|
||||||
if fp.Value.IsNull() {
|
if fp.Value.IsNull() {
|
||||||
emit.Opcodes(script, opcode.PUSHNULL)
|
emit.Opcodes(script, opcode.PUSHNULL)
|
||||||
|
@ -100,6 +98,22 @@ func ExpandArrayIntoScript(script *io.BinWriter, slice []Param) error {
|
||||||
return script.Err
|
return script.Err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ExpandArrayIntoScriptAndPack expands provided array into script and packs the
|
||||||
|
// resulting items in the array.
|
||||||
|
func ExpandArrayIntoScriptAndPack(script *io.BinWriter, slice []Param) error {
|
||||||
|
if len(slice) == 0 {
|
||||||
|
emit.Opcodes(script, opcode.NEWARRAY0)
|
||||||
|
return script.Err
|
||||||
|
}
|
||||||
|
err := ExpandArrayIntoScript(script, slice)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
emit.Int(script, int64(len(slice)))
|
||||||
|
emit.Opcodes(script, opcode.PACK)
|
||||||
|
return script.Err
|
||||||
|
}
|
||||||
|
|
||||||
// CreateFunctionInvocationScript creates a script to invoke the given contract with
|
// CreateFunctionInvocationScript creates a script to invoke the given contract with
|
||||||
// the given parameters.
|
// the given parameters.
|
||||||
func CreateFunctionInvocationScript(contract util.Uint160, method string, param *Param) ([]byte, error) {
|
func CreateFunctionInvocationScript(contract util.Uint160, method string, param *Param) ([]byte, error) {
|
||||||
|
@ -107,12 +121,10 @@ func CreateFunctionInvocationScript(contract util.Uint160, method string, param
|
||||||
if param == nil {
|
if param == nil {
|
||||||
emit.Opcodes(script.BinWriter, opcode.NEWARRAY0)
|
emit.Opcodes(script.BinWriter, opcode.NEWARRAY0)
|
||||||
} else if slice, err := param.GetArray(); err == nil {
|
} else if slice, err := param.GetArray(); err == nil {
|
||||||
err = ExpandArrayIntoScript(script.BinWriter, slice)
|
err = ExpandArrayIntoScriptAndPack(script.BinWriter, slice)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
emit.Int(script.BinWriter, int64(len(slice)))
|
|
||||||
emit.Opcodes(script.BinWriter, opcode.PACK)
|
|
||||||
} else {
|
} else {
|
||||||
return nil, fmt.Errorf("failed to convert %s to script parameter", param)
|
return nil, fmt.Errorf("failed to convert %s to script parameter", param)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package request
|
package request
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/hex"
|
"encoding/base64"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math/big"
|
"math/big"
|
||||||
"testing"
|
"testing"
|
||||||
|
@ -23,49 +23,52 @@ func TestInvocationScriptCreationGood(t *testing.T) {
|
||||||
script string
|
script string
|
||||||
}{{
|
}{{
|
||||||
ps: Params{{RawMessage: []byte(`"transfer"`)}},
|
ps: Params{{RawMessage: []byte(`"transfer"`)}},
|
||||||
script: "c21f0c087472616e736665720c146f459162ceeb248b071ec157d9e4f6fd26fdbe5041627d5b52",
|
script: "wh8MCHRyYW5zZmVyDBRvRZFizuskiwcewVfZ5Pb9Jv2+UEFifVtS",
|
||||||
}, {
|
}, {
|
||||||
ps: Params{{RawMessage: []byte(`42`)}},
|
ps: Params{{RawMessage: []byte(`42`)}},
|
||||||
script: "c21f0c0234320c146f459162ceeb248b071ec157d9e4f6fd26fdbe5041627d5b52",
|
script: "wh8MAjQyDBRvRZFizuskiwcewVfZ5Pb9Jv2+UEFifVtS",
|
||||||
}, {
|
}, {
|
||||||
ps: Params{{RawMessage: []byte(`"a"`)}, {RawMessage: []byte(`[]`)}},
|
ps: Params{{RawMessage: []byte(`"a"`)}, {RawMessage: []byte(`[]`)}},
|
||||||
script: "10c01f0c01610c146f459162ceeb248b071ec157d9e4f6fd26fdbe5041627d5b52",
|
script: "wh8MAWEMFG9FkWLO6ySLBx7BV9nk9v0m/b5QQWJ9W1I=",
|
||||||
}, {
|
}, {
|
||||||
ps: Params{{RawMessage: []byte(`"a"`)}, {RawMessage: []byte(`[{"type": "ByteString", "value": "AwEtR+diEK7HO+Oas9GG4KQP6Nhr+j1Pq/2le6E7iPlq"}]`)}},
|
ps: Params{{RawMessage: []byte(`"a"`)}, {RawMessage: []byte(`[{"type": "ByteArray", "value": "AwEtR+diEK7HO+Oas9GG4KQP6Nhr+j1Pq/2le6E7iPlq"}]`)}},
|
||||||
script: "0c2103012d47e76210aec73be39ab3d186e0a40fe8d86bfa3d4fabfda57ba13b88f96a11c01f0c01610c146f459162ceeb248b071ec157d9e4f6fd26fdbe5041627d5b52",
|
script: "DCEDAS1H52IQrsc745qz0YbgpA/o2Gv6PU+r/aV7oTuI+WoRwB8MAWEMFG9FkWLO6ySLBx7BV9nk9v0m/b5QQWJ9W1I=",
|
||||||
}, {
|
}, {
|
||||||
ps: Params{{RawMessage: []byte(`"a"`)}, {RawMessage: []byte(`[{"type": "Signature", "value": "4edf5005771de04619235d5a4c7a9a11bb78e008541f1da7725f654c33380a3c87e2959a025da706d7255cb3a3fa07ebe9c6559d0d9e6213c68049168eb1056f"}]`)}},
|
ps: Params{{RawMessage: []byte(`"a"`)}, {RawMessage: []byte(`[{"type": "Signature", "value": "4edf5005771de04619235d5a4c7a9a11bb78e008541f1da7725f654c33380a3c87e2959a025da706d7255cb3a3fa07ebe9c6559d0d9e6213c68049168eb1056f"}]`)}},
|
||||||
script: "0c404edf5005771de04619235d5a4c7a9a11bb78e008541f1da7725f654c33380a3c87e2959a025da706d7255cb3a3fa07ebe9c6559d0d9e6213c68049168eb1056f11c01f0c01610c146f459162ceeb248b071ec157d9e4f6fd26fdbe5041627d5b52",
|
script: "DGDh51/nTTnvvV17TjrX3bfl3lrhztr1rXVtvvx7TTznjV/V1rvvbl/rnhzfffzRrdzzt7b3n1rTbl1rvTp3vbnlxvdrd9rTt5t71zrnn13R317rbXdzrzTj3Xrx5vXTnp8RwB8MAWEMFG9FkWLO6ySLBx7BV9nk9v0m/b5QQWJ9W1I=",
|
||||||
|
}, {
|
||||||
|
ps: Params{{RawMessage: []byte(`"a"`)}, {RawMessage: []byte(`[{"type": "Signature", "value": "Tt9QBXcd4EYZI11aTHqaEbt44AhUHx2ncl9lTDM4CjyH4pWaAl2nBtclXLOj+gfr6cZVnQ2eYhPGgEkWjrEFbw=="}]`)}},
|
||||||
|
script: "DEBO31AFdx3gRhkjXVpMepoRu3jgCFQfHadyX2VMMzgKPIfilZoCXacG1yVcs6P6B+vpxlWdDZ5iE8aASRaOsQVvEcAfDAFhDBRvRZFizuskiwcewVfZ5Pb9Jv2+UEFifVtS",
|
||||||
}, {
|
}, {
|
||||||
ps: Params{{RawMessage: []byte(`"a"`)}, {RawMessage: []byte(`[{"type": "String", "value": "50befd26fdf6e4d957c11e078b24ebce6291456f"}]`)}},
|
ps: Params{{RawMessage: []byte(`"a"`)}, {RawMessage: []byte(`[{"type": "String", "value": "50befd26fdf6e4d957c11e078b24ebce6291456f"}]`)}},
|
||||||
script: "0c283530626566643236666466366534643935376331316530373862323465626365363239313435366611c01f0c01610c146f459162ceeb248b071ec157d9e4f6fd26fdbe5041627d5b52",
|
script: "DCg1MGJlZmQyNmZkZjZlNGQ5NTdjMTFlMDc4YjI0ZWJjZTYyOTE0NTZmEcAfDAFhDBRvRZFizuskiwcewVfZ5Pb9Jv2+UEFifVtS",
|
||||||
}, {
|
}, {
|
||||||
ps: Params{{RawMessage: []byte(`"a"`)}, {RawMessage: []byte(`[{"type": "Hash160", "value": "50befd26fdf6e4d957c11e078b24ebce6291456f"}]`)}},
|
ps: Params{{RawMessage: []byte(`"a"`)}, {RawMessage: []byte(`[{"type": "Hash160", "value": "50befd26fdf6e4d957c11e078b24ebce6291456f"}]`)}},
|
||||||
script: "0c146f459162ceeb248b071ec157d9e4f6fd26fdbe5011c01f0c01610c146f459162ceeb248b071ec157d9e4f6fd26fdbe5041627d5b52",
|
script: "DBRvRZFizuskiwcewVfZ5Pb9Jv2+UBHAHwwBYQwUb0WRYs7rJIsHHsFX2eT2/Sb9vlBBYn1bUg==",
|
||||||
}, {
|
}, {
|
||||||
ps: Params{{RawMessage: []byte(`"a"`)}, {RawMessage: []byte(`[{"type": "Hash256", "value": "602c79718b16e442de58778e148d0b1084e3b2dffd5de6b7b16cee7969282de7"}]`)}},
|
ps: Params{{RawMessage: []byte(`"a"`)}, {RawMessage: []byte(`[{"type": "Hash256", "value": "602c79718b16e442de58778e148d0b1084e3b2dffd5de6b7b16cee7969282de7"}]`)}},
|
||||||
script: "0c20e72d286979ee6cb1b7e65dfddfb2e384100b8d148e7758de42e4168b71792c6011c01f0c01610c146f459162ceeb248b071ec157d9e4f6fd26fdbe5041627d5b52",
|
script: "DCDnLShpee5ssbfmXf3fsuOEEAuNFI53WN5C5BaLcXksYBHAHwwBYQwUb0WRYs7rJIsHHsFX2eT2/Sb9vlBBYn1bUg==",
|
||||||
}, {
|
}, {
|
||||||
ps: Params{{RawMessage: []byte(`"a"`)}, {RawMessage: []byte(`[{"type": "PublicKey", "value": "03c089d7122b840a4935234e82e26ae5efd0c2acb627239dc9f207311337b6f2c1"}]`)}},
|
ps: Params{{RawMessage: []byte(`"a"`)}, {RawMessage: []byte(`[{"type": "PublicKey", "value": "03c089d7122b840a4935234e82e26ae5efd0c2acb627239dc9f207311337b6f2c1"}]`)}},
|
||||||
script: "0c2103c089d7122b840a4935234e82e26ae5efd0c2acb627239dc9f207311337b6f2c111c01f0c01610c146f459162ceeb248b071ec157d9e4f6fd26fdbe5041627d5b52",
|
script: "DCEDwInXEiuECkk1I06C4mrl79DCrLYnI53J8gcxEze28sERwB8MAWEMFG9FkWLO6ySLBx7BV9nk9v0m/b5QQWJ9W1I=",
|
||||||
}, {
|
}, {
|
||||||
ps: Params{{RawMessage: []byte(`"a"`)}, {RawMessage: []byte(`[{"type": "Integer", "value": 42}]`)}},
|
ps: Params{{RawMessage: []byte(`"a"`)}, {RawMessage: []byte(`[{"type": "Integer", "value": 42}]`)}},
|
||||||
script: "002a11c01f0c01610c146f459162ceeb248b071ec157d9e4f6fd26fdbe5041627d5b52",
|
script: "ACoRwB8MAWEMFG9FkWLO6ySLBx7BV9nk9v0m/b5QQWJ9W1I=",
|
||||||
}, {
|
}, {
|
||||||
ps: Params{{RawMessage: []byte(`"a"`)}, {RawMessage: []byte(`[{"type": "Integer", "value": "42"}]`)}}, // C# code doesn't use strict type assertions for JSON-ised params
|
ps: Params{{RawMessage: []byte(`"a"`)}, {RawMessage: []byte(`[{"type": "Integer", "value": "42"}]`)}}, // C# code doesn't use strict type assertions for JSON-ised params
|
||||||
script: "002a11c01f0c01610c146f459162ceeb248b071ec157d9e4f6fd26fdbe5041627d5b52",
|
script: "ACoRwB8MAWEMFG9FkWLO6ySLBx7BV9nk9v0m/b5QQWJ9W1I=",
|
||||||
}, {
|
}, {
|
||||||
ps: Params{{RawMessage: []byte(`"a"`)}, {RawMessage: []byte(`[{"type": "Integer", "value": true}]`)}}, // C# code doesn't use strict type assertions for JSON-ised params
|
ps: Params{{RawMessage: []byte(`"a"`)}, {RawMessage: []byte(`[{"type": "Integer", "value": true}]`)}}, // C# code doesn't use strict type assertions for JSON-ised params
|
||||||
script: "1111c01f0c01610c146f459162ceeb248b071ec157d9e4f6fd26fdbe5041627d5b52",
|
script: "ERHAHwwBYQwUb0WRYs7rJIsHHsFX2eT2/Sb9vlBBYn1bUg==",
|
||||||
}, {
|
}, {
|
||||||
ps: Params{{RawMessage: []byte(`"a"`)}, {RawMessage: []byte(`[{"type": "Boolean", "value": true}]`)}},
|
ps: Params{{RawMessage: []byte(`"a"`)}, {RawMessage: []byte(`[{"type": "Boolean", "value": true}]`)}},
|
||||||
script: "1111c01f0c01610c146f459162ceeb248b071ec157d9e4f6fd26fdbe5041627d5b52",
|
script: "ERHAHwwBYQwUb0WRYs7rJIsHHsFX2eT2/Sb9vlBBYn1bUg==",
|
||||||
}, {
|
}, {
|
||||||
ps: Params{{RawMessage: []byte(`"a"`)}, {RawMessage: []byte(`[{"type": "Boolean", "value": false}]`)}},
|
ps: Params{{RawMessage: []byte(`"a"`)}, {RawMessage: []byte(`[{"type": "Boolean", "value": false}]`)}},
|
||||||
script: "1011c01f0c01610c146f459162ceeb248b071ec157d9e4f6fd26fdbe5041627d5b52",
|
script: "EBHAHwwBYQwUb0WRYs7rJIsHHsFX2eT2/Sb9vlBBYn1bUg==",
|
||||||
}, {
|
}, {
|
||||||
ps: Params{{RawMessage: []byte(`"a"`)}, {RawMessage: []byte(`[{"type": "Boolean", "value": "blah"}]`)}}, // C# code doesn't use strict type assertions for JSON-ised params
|
ps: Params{{RawMessage: []byte(`"a"`)}, {RawMessage: []byte(`[{"type": "Boolean", "value": "blah"}]`)}}, // C# code doesn't use strict type assertions for JSON-ised params
|
||||||
script: "1111c01f0c01610c146f459162ceeb248b071ec157d9e4f6fd26fdbe5041627d5b52",
|
script: "ERHAHwwBYQwUb0WRYs7rJIsHHsFX2eT2/Sb9vlBBYn1bUg==",
|
||||||
}}
|
}}
|
||||||
for i, ps := range paramScripts {
|
for i, ps := range paramScripts {
|
||||||
method, err := ps.ps[0].GetString()
|
method, err := ps.ps[0].GetString()
|
||||||
|
@ -76,7 +79,7 @@ func TestInvocationScriptCreationGood(t *testing.T) {
|
||||||
}
|
}
|
||||||
script, err := CreateFunctionInvocationScript(contract, method, p)
|
script, err := CreateFunctionInvocationScript(contract, method, p)
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
assert.Equal(t, ps.script, hex.EncodeToString(script), fmt.Sprintf("testcase #%d", i))
|
assert.Equal(t, ps.script, base64.StdEncoding.EncodeToString(script), fmt.Sprintf("testcase #%d", i))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue