From a871f7506360cf0d602a82885333777d3ed0229b Mon Sep 17 00:00:00 2001 From: Evgenii Stratonikov Date: Wed, 15 Jan 2020 16:36:57 +0300 Subject: [PATCH] wallet: use a script instead a hash NEO wallets (e.g. used in privnet setup) use hex-encoded script inside the wallet, not a script hash. --- pkg/wallet/account.go | 50 +++++++++++++++++++++++++++++++++++--- pkg/wallet/account_test.go | 19 +++++++++++++++ 2 files changed, 66 insertions(+), 3 deletions(-) diff --git a/pkg/wallet/account.go b/pkg/wallet/account.go index c1ddd1317..47ba95cd5 100644 --- a/pkg/wallet/account.go +++ b/pkg/wallet/account.go @@ -1,10 +1,11 @@ package wallet import ( + "encoding/hex" + "encoding/json" "errors" "github.com/CityOfZion/neo-go/pkg/crypto/keys" - "github.com/CityOfZion/neo-go/pkg/util" ) // Account represents a NEO account. It holds the private and public key @@ -43,8 +44,8 @@ type Account struct { // Contract represents a subset of the smartcontract to embed in the // Account so it's NEP-6 compliant. type Contract struct { - // Script hash of the contract deployed on the blockchain. - Script util.Uint160 `json:"script"` + // Script of the contract deployed on the blockchain. + Script []byte `json:"script"` // A list of parameters used deploying this contract. Parameters []interface{} `json:"parameters"` @@ -53,6 +54,49 @@ type Contract struct { Deployed bool `json:"deployed"` } +// contract is an intermediate struct used for json unmarshalling. +type contract struct { + // Script is a hex-encoded script of the contract. + Script string `json:"script"` + + // A list of parameters used deploying this contract. + Parameters []interface{} `json:"parameters"` + + // Indicates whether the contract has been deployed to the blockchain. + Deployed bool `json:"deployed"` +} + +// MarshalJSON implements json.Marshaler interface. +func (c Contract) MarshalJSON() ([]byte, error) { + var cc contract + + cc.Script = hex.EncodeToString(c.Script) + cc.Parameters = c.Parameters + cc.Deployed = c.Deployed + + return json.Marshal(cc) +} + +// UnmarshalJSON implements json.Unmarshaler interface. +func (c *Contract) UnmarshalJSON(data []byte) error { + var cc contract + + if err := json.Unmarshal(data, &cc); err != nil { + return err + } + + script, err := hex.DecodeString(cc.Script) + if err != nil { + return err + } + + c.Script = script + c.Parameters = cc.Parameters + c.Deployed = cc.Deployed + + return nil +} + // NewAccount creates a new Account with a random generated PrivateKey. func NewAccount() (*Account, error) { priv, err := keys.NewPrivateKey() diff --git a/pkg/wallet/account_test.go b/pkg/wallet/account_test.go index da84055f2..e786749cb 100644 --- a/pkg/wallet/account_test.go +++ b/pkg/wallet/account_test.go @@ -2,6 +2,7 @@ package wallet import ( "encoding/hex" + "encoding/json" "testing" "github.com/CityOfZion/neo-go/pkg/internal/keytestcases" @@ -47,6 +48,24 @@ func TestNewFromWif(t *testing.T) { } } +func TestContract_MarshalJSON(t *testing.T) { + var c Contract + + data := []byte(`{"script":"0102","parameters":[1],"deployed":false}`) + require.NoError(t, json.Unmarshal(data, &c)) + require.Equal(t, []byte{1, 2}, c.Script) + + result, err := json.Marshal(c) + require.NoError(t, err) + require.JSONEq(t, string(data), string(result)) + + data = []byte(`1`) + require.Error(t, json.Unmarshal(data, &c)) + + data = []byte(`{"script":"ERROR","parameters":[1],"deployed":false}`) + require.Error(t, json.Unmarshal(data, &c)) +} + func compareFields(t *testing.T, tk keytestcases.Ktype, acc *Account) { if want, have := tk.Address, acc.Address; want != have { t.Fatalf("expected %s got %s", want, have)