From 59b4377f904f9ca6bccf7beae777e026d8313339 Mon Sep 17 00:00:00 2001 From: Roman Khimov Date: Fri, 23 Jul 2021 11:33:51 +0300 Subject: [PATCH 1/4] context: support Neo.Network.P2P.Payloads.Transaction type C# now uses this one, so use it by default, but also accept old one. --- cli/paramcontext/context.go | 2 +- pkg/smartcontract/context/context.go | 2 +- pkg/smartcontract/context/context_test.go | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/cli/paramcontext/context.go b/cli/paramcontext/context.go index c991e2e85..0f354427c 100644 --- a/cli/paramcontext/context.go +++ b/cli/paramcontext/context.go @@ -23,7 +23,7 @@ func InitAndSave(net netmode.Magic, tx *transaction.Transaction, acc *wallet.Acc priv := acc.PrivateKey() pub := priv.PublicKey() sign := priv.SignHashable(uint32(net), tx) - scCtx := context.NewParameterContext("Neo.Core.ContractTransaction", net, tx) + scCtx := context.NewParameterContext("Neo.Network.P2P.Payloads.Transaction", net, tx) h, err := address.StringToUint160(acc.Address) if err != nil { return fmt.Errorf("invalid address: %s", acc.Address) diff --git a/pkg/smartcontract/context/context.go b/pkg/smartcontract/context/context.go index e5c3cafc5..d597e13ec 100644 --- a/pkg/smartcontract/context/context.go +++ b/pkg/smartcontract/context/context.go @@ -188,7 +188,7 @@ func (c *ParameterContext) UnmarshalJSON(data []byte) error { var verif crypto.VerifiableDecodable switch pc.Type { - case "Neo.Core.ContractTransaction": + case "Neo.Core.ContractTransaction", "Neo.Network.P2P.Payloads.Transaction": tx := new(transaction.Transaction) verif = tx default: diff --git a/pkg/smartcontract/context/context_test.go b/pkg/smartcontract/context/context_test.go index fe0603671..d3c62b135 100644 --- a/pkg/smartcontract/context/context_test.go +++ b/pkg/smartcontract/context/context_test.go @@ -77,7 +77,7 @@ func TestParameterContext_AddSignatureSimpleContract(t *testing.T) { func TestParameterContext_AddSignatureMultisig(t *testing.T) { tx := getContractTx() - c := NewParameterContext("Neo.Core.ContractTransaction", netmode.UnitTestNet, tx) + c := NewParameterContext("Neo.Network.P2P.Payloads.Transaction", netmode.UnitTestNet, tx) privs, pubs := getPrivateKeys(t, 4) pubsCopy := keys.PublicKeys(pubs).Copy() script, err := smartcontract.CreateMultiSigRedeemScript(3, pubsCopy) From cbe1eeb08cde008159f7d438f440e9cdbc10768f Mon Sep 17 00:00:00 2001 From: Roman Khimov Date: Fri, 23 Jul 2021 11:46:26 +0300 Subject: [PATCH 2/4] smartcontract: add support for valueless Parameters This is fine: { "type" : "Signature" }, --- pkg/smartcontract/parameter.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/pkg/smartcontract/parameter.go b/pkg/smartcontract/parameter.go index d961b191e..0702e17f8 100644 --- a/pkg/smartcontract/parameter.go +++ b/pkg/smartcontract/parameter.go @@ -109,7 +109,11 @@ func (p *Parameter) UnmarshalJSON(data []byte) (err error) { if err = json.Unmarshal(data, &r); err != nil { return } - switch p.Type = r.Type; r.Type { + p.Type = r.Type + if len(r.Value) == 0 { + return + } + switch r.Type { case BoolType: if err = json.Unmarshal(r.Value, &boolean); err != nil { return From efb67a0ea3838e9fc8de98973910aa04fd70fad9 Mon Sep 17 00:00:00 2001 From: Roman Khimov Date: Fri, 23 Jul 2021 11:57:35 +0300 Subject: [PATCH 3/4] context: scripts and signatures are base64-encoded in C# now So use base64 too and add compatibility test. Unfortunately this breaks support for old (hex-based) files, but those should be completed a long time ago. --- pkg/smartcontract/context/context_test.go | 6 +++ pkg/smartcontract/context/item.go | 58 +---------------------- 2 files changed, 8 insertions(+), 56 deletions(-) diff --git a/pkg/smartcontract/context/context_test.go b/pkg/smartcontract/context/context_test.go index d3c62b135..a4f40cd0e 100644 --- a/pkg/smartcontract/context/context_test.go +++ b/pkg/smartcontract/context/context_test.go @@ -169,6 +169,12 @@ func TestParameterContext_MarshalJSON(t *testing.T) { }) } +func TestSharpJSON(t *testing.T) { + input := []byte(`{"type":"Neo.Network.P2P.Payloads.Transaction","data":"AKTv6hJY8h4AAAAAAKwiUwEAAAAA0lEAAAFBO\u002BhSRSuucNKVX2lk7k5Wdr\u002BkOQEAMR8RwB8MEHNldEV4ZWNGZWVGYWN0b3IMFHvGgcCh9x1UNFe2i7qNX5/dTl7MQWJ9W1I=","items":{"0x39a4bf76564eee64695f95d270ae2b4552e83b41":{"script":"GwwhAwCbdUDhDyVi5f2PrJ6uwlFmpYsm5BI0j/WoaSe/rCKiDCEDAgXpzvrqWh38WAryDI1aokaLsBSPGl5GBfxiLIDmBLoMIQIUuvDO6jpm8X5\u002BHoOeol/YvtbNgua7bmglAYkGX0T/AQwhAzjSoai75eQ8YzNBYTMIaaXgqqUeYTSWGEp8xylL\u002BVafDCEDPY41\u002BM2aM4UigLbZMJPHKS7VzpDZDxSfotpQumFo384MIQI\u002BmzLqiblNBm5kmxJP1Q45bukTaejipq4bEcFw0CIlbQwhA0CNzUFjlvZHg6xYfqHhWTxX2f6ogMimoZIOkqJZR3gGDCEDScfvC0qvGB8KPhNQxSexNsxbQkmMuDq4iAwF7ZUWfhwMIQJWZM7wq8uneHrV\u002BxLzrzHFzcekeQaKoq2O54gEdov/6QwhA1tPm\u002BK4U\u002BButaCcFn4Di5a0gEI1lhUQQjJS8u49u6WDDCEDZQpoRGGmS/Rr7lYdmYGkxXrcbMvTqVErg3AUgLMCGKsMIQJqEKorTXY5xd6vpP8IFGfbELXQBDJ0mipe4dK/7SPhwAwhAn5FmyZLb34yWrSwuw\u002BmQQgftoUX/WE\u002BvXqUy3nTCB5PDCECiMrUQqh3lgx2tPaI9L4w92glbZo9okkrAYC5EkORi08MIQKkDFUnmPeWNglYF\u002ByIkk/Gy3CU5aPLBZqbO8keo78NPQwhAqeDS\u002BmzLimB0VfLW706y0LP0R6lw7ECJNekTpjFkQ8bDCECuixw9ZlvNXpDGYcFhZ\u002BuLP6hPhFyligAdys9WIqdSr0MIQLVeGqSFKij8XV9dZb9EPUkEgXiwNaDYvR2ZXm6xhiSSQwhA9jVjSJXymyxRSK3ZRPUeD99SBgBaViTeUwhhlFcbedvDCEC23nmnFGK6SVOMUtvX0tj6RTN1LJXTcL5I2wBwfwdiXMMIQLsFD8AuIUkyvNqASHC3gnu8FGd2\u002BHHEKAPDiZjIB7kwAAVQZ7Q3Do=","parameters":[{"type":"Signature"},{"type":"Signature"},{"type":"Signature"},{"type":"Signature"},{"type":"Signature"},{"type":"Signature"},{"type":"Signature"},{"type":"Signature"},{"type":"Signature"},{"type":"Signature"},{"type":"Signature"}],"signatures":{"03650a684461a64bf46bee561d9981a4c57adc6ccbd3a9512b83701480b30218ab":"QtjYFNpGOOnij\u002BLwNZLOO3fHNoVQas\u002B4\u002BAo6SdvEeP3C12ATXzgPjAZrd5mCDc3KYkce0wwveEuuoYA8mhraUA==","0288cad442a877960c76b4f688f4be30f768256d9a3da2492b0180b91243918b4f":"RmuTXfPokXWEL9RIM9DqUUsOH8iRMfrKTp6LdhdJ0KBW6rNSEuxxNOpSUMBEW1EE2CNh1c\u002BmElj2Ny3o89SzGQ==","035b4f9be2b853e06eb5a09c167e038b96b4804235961510423252f2ee3dbba583":"1VYiT\u002BPe/7syYDSOWaJ1jPyZ6JDPrdU9toDu0Cg9pRQAJW1KLSexiosLA73k7lQeVbq4YuNlWnY7U8CYIQ/ilA==","02a40c552798f79636095817ec88924fc6cb7094e5a3cb059a9b3bc91ea3bf0d3d":"/mXUPXp/tI6Y7LhudKzBE8K2soHcPgrr48YLrwgbTI4qypYpOzh\u002BNj03pkAvk8\u002B68kuefevNQb/pjmPRvs80DA=="}}},"network":877933390}`) + pc := ParameterContext{} + require.NoError(t, json.Unmarshal(input, &pc)) +} + func getPrivateKeys(t *testing.T, n int) ([]*keys.PrivateKey, []*keys.PublicKey) { privs := make([]*keys.PrivateKey, n) pubs := make([]*keys.PublicKey, n) diff --git a/pkg/smartcontract/context/item.go b/pkg/smartcontract/context/item.go index 2b8a3dc57..b648b04f2 100644 --- a/pkg/smartcontract/context/item.go +++ b/pkg/smartcontract/context/item.go @@ -1,9 +1,7 @@ package context import ( - "encoding/base64" "encoding/hex" - "encoding/json" "github.com/nspcc-dev/neo-go/pkg/crypto/keys" "github.com/nspcc-dev/neo-go/pkg/smartcontract" @@ -11,15 +9,9 @@ import ( // Item represents a transaction context item. type Item struct { - Script []byte - Parameters []smartcontract.Parameter - Signatures map[string][]byte -} - -type itemAux struct { - Script string `json:"script"` + Script []byte `json:"script"` Parameters []smartcontract.Parameter `json:"parameters"` - Signatures map[string]string `json:"signatures"` + Signatures map[string][]byte `json:"signatures"` } // GetSignature returns signature for pub if present. @@ -32,49 +24,3 @@ func (it *Item) AddSignature(pub *keys.PublicKey, sig []byte) { pubHex := hex.EncodeToString(pub.Bytes()) it.Signatures[pubHex] = sig } - -// MarshalJSON implements json.Marshaler interface. -func (it Item) MarshalJSON() ([]byte, error) { - ci := itemAux{ - Script: base64.StdEncoding.EncodeToString(it.Script), - Parameters: it.Parameters, - Signatures: make(map[string]string, len(it.Signatures)), - } - - for key, sig := range it.Signatures { - ci.Signatures[key] = hex.EncodeToString(sig) - } - - return json.Marshal(ci) -} - -// UnmarshalJSON implements json.Unmarshaler interface. -func (it *Item) UnmarshalJSON(data []byte) error { - ci := new(itemAux) - if err := json.Unmarshal(data, ci); err != nil { - return err - } - - script, err := base64.StdEncoding.DecodeString(ci.Script) - if err != nil { - return err - } - - sigs := make(map[string][]byte, len(ci.Signatures)) - for keyHex, sigHex := range ci.Signatures { - _, err := keys.NewPublicKeyFromString(keyHex) - if err != nil { - return err - } - sig, err := hex.DecodeString(sigHex) - if err != nil { - return err - } - sigs[keyHex] = sig - } - - it.Signatures = sigs - it.Script = script - it.Parameters = ci.Parameters - return nil -} From 6103da8d10fab2146443ab928f1d32cc9dcbaee2 Mon Sep 17 00:00:00 2001 From: Roman Khimov Date: Fri, 23 Jul 2021 12:41:09 +0300 Subject: [PATCH 4/4] context: read item key in LE Hi, neo-project/neo#938. --- pkg/smartcontract/context/context.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/smartcontract/context/context.go b/pkg/smartcontract/context/context.go index d597e13ec..fea22c495 100644 --- a/pkg/smartcontract/context/context.go +++ b/pkg/smartcontract/context/context.go @@ -168,7 +168,7 @@ func (c ParameterContext) MarshalJSON() ([]byte, error) { if err != nil { return nil, err } - items["0x"+u.StringBE()] = data + items["0x"+u.StringLE()] = data } pc := ¶mContext{ Type: c.Type, @@ -200,7 +200,7 @@ func (c *ParameterContext) UnmarshalJSON(data []byte) error { } items := make(map[util.Uint160]*Item, len(pc.Items)) for h := range pc.Items { - u, err := util.Uint160DecodeStringBE(strings.TrimPrefix(h, "0x")) + u, err := util.Uint160DecodeStringLE(strings.TrimPrefix(h, "0x")) if err != nil { return err }