diff --git a/pkg/rpc/request/param.go b/pkg/rpc/request/param.go index 4918645bc..f67d2f81c 100644 --- a/pkg/rpc/request/param.go +++ b/pkg/rpc/request/param.go @@ -2,6 +2,7 @@ package request import ( "bytes" + "encoding/base64" "encoding/hex" "encoding/json" "fmt" @@ -185,6 +186,17 @@ func (p *Param) GetBytesHex() ([]byte, error) { return hex.DecodeString(s) } +// GetBytesBase64 returns []byte value of the parameter if +// it is a base64-encoded string. +func (p *Param) GetBytesBase64() ([]byte, error) { + s, err := p.GetString() + if err != nil { + return nil, err + } + + return base64.StdEncoding.DecodeString(s) +} + // GetCosigner returns transaction.Cosigner value of the parameter. func (p Param) GetCosigner() (transaction.Cosigner, error) { c, ok := p.Value.(transaction.Cosigner) diff --git a/pkg/rpc/request/param_test.go b/pkg/rpc/request/param_test.go index 70a40b41f..674262b08 100644 --- a/pkg/rpc/request/param_test.go +++ b/pkg/rpc/request/param_test.go @@ -1,6 +1,7 @@ package request import ( + "encoding/base64" "encoding/hex" "encoding/json" "testing" @@ -242,6 +243,24 @@ func TestParamGetBytesHex(t *testing.T) { require.NotNil(t, err) } +func TestParamGetBytesBase64(t *testing.T) { + in := "Aj4A8DoW6HB84EXrQu6A05JFFUHuUQ3BjhyL77rFTXQm" + inb, err := base64.StdEncoding.DecodeString(in) + require.NoError(t, err) + p := Param{StringT, in} + bh, err := p.GetBytesBase64() + assert.Equal(t, inb, bh) + require.Nil(t, err) + + p = Param{StringT, 42} + _, err = p.GetBytesBase64() + require.NotNil(t, err) + + p = Param{StringT, "@j4A8DoW6HB84EXrQu6A05JFFUHuUQ3BjhyL77rFTXQm"} + _, err = p.GetBytesBase64() + require.NotNil(t, err) +} + func TestParamGetCosigner(t *testing.T) { c := transaction.Cosigner{ Account: util.Uint160{1, 2, 3, 4}, diff --git a/pkg/rpc/request/txBuilder.go b/pkg/rpc/request/txBuilder.go index f8db67de2..c3b76d91e 100644 --- a/pkg/rpc/request/txBuilder.go +++ b/pkg/rpc/request/txBuilder.go @@ -37,7 +37,13 @@ func expandArrayIntoScript(script *io.BinWriter, slice []Param) error { return err } switch fp.Type { - case smartcontract.ByteArrayType, smartcontract.SignatureType: + case smartcontract.ByteArrayType: + str, err := fp.Value.GetBytesBase64() + if err != nil { + return err + } + emit.Bytes(script, str) + case smartcontract.SignatureType: str, err := fp.Value.GetBytesHex() if err != nil { return err diff --git a/pkg/rpc/request/tx_builder_test.go b/pkg/rpc/request/tx_builder_test.go index a132c629f..dd849da0f 100644 --- a/pkg/rpc/request/tx_builder_test.go +++ b/pkg/rpc/request/tx_builder_test.go @@ -30,8 +30,8 @@ func TestInvocationScriptCreationGood(t *testing.T) { ps: Params{{Type: StringT, Value: "a"}, {Type: ArrayT, Value: []Param{}}}, script: "10c00c01610c146f459162ceeb248b071ec157d9e4f6fd26fdbe5041627d5b52", }, { - ps: Params{{Type: StringT, Value: "a"}, {Type: ArrayT, Value: []Param{{Type: FuncParamT, Value: FuncParam{Type: smartcontract.ByteArrayType, Value: Param{Type: StringT, Value: "50befd26fdf6e4d957c11e078b24ebce6291456f"}}}}}}, - script: "0c1450befd26fdf6e4d957c11e078b24ebce6291456f11c00c01610c146f459162ceeb248b071ec157d9e4f6fd26fdbe5041627d5b52", + ps: Params{{Type: StringT, Value: "a"}, {Type: ArrayT, Value: []Param{{Type: FuncParamT, Value: FuncParam{Type: smartcontract.ByteArrayType, Value: Param{Type: StringT, Value: "AwEtR+diEK7HO+Oas9GG4KQP6Nhr+j1Pq/2le6E7iPlq"}}}}}}, + script: "0c2103012d47e76210aec73be39ab3d186e0a40fe8d86bfa3d4fabfda57ba13b88f96a11c00c01610c146f459162ceeb248b071ec157d9e4f6fd26fdbe5041627d5b52", }, { ps: Params{{Type: StringT, Value: "a"}, {Type: ArrayT, Value: []Param{{Type: FuncParamT, Value: FuncParam{Type: smartcontract.SignatureType, Value: Param{Type: StringT, Value: "4edf5005771de04619235d5a4c7a9a11bb78e008541f1da7725f654c33380a3c87e2959a025da706d7255cb3a3fa07ebe9c6559d0d9e6213c68049168eb1056f"}}}}}}, script: "0c404edf5005771de04619235d5a4c7a9a11bb78e008541f1da7725f654c33380a3c87e2959a025da706d7255cb3a3fa07ebe9c6559d0d9e6213c68049168eb1056f11c00c01610c146f459162ceeb248b071ec157d9e4f6fd26fdbe5041627d5b52",