Skip to content

Commit

Permalink
cli: add filebytes parameter type
Browse files Browse the repository at this point in the history
  • Loading branch information
AnnaShaleva committed Feb 18, 2021
1 parent fe918e2 commit db73d6a
Show file tree
Hide file tree
Showing 6 changed files with 55 additions and 18 deletions.
10 changes: 6 additions & 4 deletions cli/smartcontract/smart_contract.go
Original file line number Diff line number Diff line change
Expand Up @@ -205,10 +205,10 @@ func NewCommands() []cli.Command {
Arguments always do have regular Neo smart contract parameter types, either
specified explicitly or being inferred from the value. To specify the type
manually use "type:value" syntax where the type is one of the following:
'signature', 'bool', 'int', 'hash160', 'hash256', 'bytes', 'key' or 'string'.
Array types are also supported: use special space-separated '[' and ']'
symbols around array values to denote array bounds. Nested arrays are also
supported.
'signature', 'bool', 'int', 'hash160', 'hash256', 'bytes', 'filebytes', key'
or 'string'. Array types are also supported: use special space-separated '['
and ']' symbols around array values to denote array bounds. Nested arrays are
also supported.
Given values are type-checked against given types with the following
restrictions applied:
Expand All @@ -222,6 +222,7 @@ func NewCommands() []cli.Command {
* 'hash256' type values should be hex-encoded and have a (decoded)
length of 32 bytes.
* 'bytes' type values are any hex-encoded things.
* 'filebytes' type values are filenames with hex-encoded things inside.
* 'key' type values are hex-encoded marshalled public keys.
* 'string' type values are any valid UTF-8 strings. In the value's part of
the string the colon looses it's special meaning as a separator between
Expand Down Expand Up @@ -250,6 +251,7 @@ func NewCommands() []cli.Command {
* 'bad' is a string with a value of 'bad'
* 'dead' is a byte array with a value of 'dead'
* 'string:dead' is a string with a value of 'dead'
* 'filebytes:my_data.txt' is bytes decoded from a hex-encoding content of my_data.txt
* 'AK2nJJpJr6o664CWJKi1QRXjqeic2zRp8y' is a hash160 with a value
of '23ba2703c53263e8d6e522dc32203339dcd8eee9'
* '\4\2' is an integer with a value of 42
Expand Down
24 changes: 18 additions & 6 deletions pkg/smartcontract/param_type.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"encoding/json"
"errors"
"fmt"
"io/ioutil"
"strconv"
"strings"

Expand Down Expand Up @@ -35,6 +36,9 @@ const (
VoidType ParamType = 0xff
)

// fileBytesParamType is a string representation of `filebytes` parameter type used in cli.
const fileBytesParamType string = "filebytes"

// validParamTypes contains a map of known ParamTypes
var validParamTypes = map[ParamType]bool{
UnknownType: true,
Expand Down Expand Up @@ -162,7 +166,7 @@ func ParseParamType(typ string) (ParamType, error) {
return Hash160Type, nil
case "hash256":
return Hash256Type, nil
case "bytes", "bytearray", "bytestring":
case "bytes", "bytearray", "bytestring", fileBytesParamType:
return ByteArrayType, nil
case "key", "publickey":
return PublicKeyType, nil
Expand All @@ -184,7 +188,7 @@ func ParseParamType(typ string) (ParamType, error) {
}

// adjustValToType is a value type-checker and converter.
func adjustValToType(typ ParamType, val string) (interface{}, error) {
func adjustValToType(typ ParamType, typStr, val string) (interface{}, error) {
switch typ {
case SignatureType:
b, err := hex.DecodeString(val)
Expand Down Expand Up @@ -223,11 +227,19 @@ func adjustValToType(typ ParamType, val string) (interface{}, error) {
}
return u, nil
case ByteArrayType:
b, err := hex.DecodeString(val)
if err != nil {
return nil, err
if typStr == fileBytesParamType {
fileBytes, err := ioutil.ReadFile(val)
if err != nil {
return nil, fmt.Errorf("failed to read '%s' parameter from file '%s': %w", fileBytesParamType, val, err)
}
b := make([]byte, hex.DecodedLen(len(fileBytes)))
_, err = hex.Decode(b, fileBytes)
if err != nil {
return nil, fmt.Errorf("failed to decode '%s' parameter from file '%s': %w", fileBytesParamType, val, err)
}
return b, nil
}
return b, nil
return hex.DecodeString(val)
case PublicKeyType:
pub, err := keys.NewPublicKeyFromString(val)
if err != nil {
Expand Down
32 changes: 26 additions & 6 deletions pkg/smartcontract/param_type_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,11 @@ func TestParseParamType(t *testing.T) {
}, {
in: "qwerty",
err: true,
}}
}, {
in: "filebytes",
out: ByteArrayType,
},
}
for _, inout := range inouts {
out, err := ParseParamType(inout.in)
if inout.err {
Expand Down Expand Up @@ -147,10 +151,11 @@ func TestInferParamType(t *testing.T) {

func TestAdjustValToType(t *testing.T) {
var inouts = []struct {
typ ParamType
val string
out interface{}
err bool
typ ParamType
typStr string
val string
out interface{}
err bool
}{{
typ: SignatureType,
val: "602c79718b16e442de58778e148d0b1084e3b2dffd5de6b7b16cee7969282de7c56f33fc6ecfcd0c225c4ab356fee59390af8560be0e930faebe74a6daff7c9b",
Expand Down Expand Up @@ -296,10 +301,25 @@ func TestAdjustValToType(t *testing.T) {
typ: InteropInterfaceType,
val: "",
err: true,
}, {
typ: ByteArrayType,
typStr: "filebytes",
val: "./testdata/adjustValToType_filebytes_good.txt",
out: []byte{0x01, 0x02, 0x03, 0xef},
}, {
typ: ByteArrayType,
typStr: "filebytes",
val: "./testdata/adjustValToType_filebytes_bad.txt",
err: true,
}, {
typ: ByteArrayType,
typStr: "filebytes",
val: "./testdata/does_not_exists.txt",
err: true,
}}

for _, inout := range inouts {
out, err := adjustValToType(inout.typ, inout.val)
out, err := adjustValToType(inout.typ, inout.typStr, inout.val)
if inout.err {
assert.NotNil(t, err, "should error on '%s/%s' input", inout.typ, inout.val)
} else {
Expand Down
5 changes: 3 additions & 2 deletions pkg/smartcontract/parameter.go
Original file line number Diff line number Diff line change
Expand Up @@ -387,6 +387,7 @@ func NewParameterFromString(in string) (*Parameter, error) {
escaped bool
hadType bool
res = &Parameter{}
typStr string
)
r = strings.NewReader(in)
for char, _, err = r.ReadRune(); err == nil && char != utf8.RuneError; char, _, err = r.ReadRune() {
Expand All @@ -395,7 +396,7 @@ func NewParameterFromString(in string) (*Parameter, error) {
continue
}
if char == ':' && !escaped && !hadType {
typStr := buf.String()
typStr = buf.String()
res.Type, err = ParseParamType(typStr)
if err != nil {
return nil, err
Expand All @@ -422,7 +423,7 @@ func NewParameterFromString(in string) (*Parameter, error) {
if !hadType {
res.Type = inferParamType(val)
}
res.Value, err = adjustValToType(res.Type, val)
res.Value, err = adjustValToType(res.Type, typStr, val)
if err != nil {
return nil, err
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
not-a-hex
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
010203ef

0 comments on commit db73d6a

Please sign in to comment.