forked from TrueCloudLab/neoneo-go
smartcontract: implement ContextItem
This commit is contained in:
parent
46db4e9d9d
commit
acea3867b2
2 changed files with 149 additions and 0 deletions
75
pkg/smartcontract/context/item.go
Normal file
75
pkg/smartcontract/context/item.go
Normal file
|
@ -0,0 +1,75 @@
|
||||||
|
package context
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/hex"
|
||||||
|
"encoding/json"
|
||||||
|
|
||||||
|
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||||
|
"github.com/nspcc-dev/neo-go/pkg/smartcontract"
|
||||||
|
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Item represents a transaction context item.
|
||||||
|
type Item struct {
|
||||||
|
Script util.Uint160
|
||||||
|
Parameters []smartcontract.Parameter
|
||||||
|
Signatures map[string][]byte
|
||||||
|
}
|
||||||
|
|
||||||
|
type itemAux struct {
|
||||||
|
Script util.Uint160 `json:"script"`
|
||||||
|
Parameters []smartcontract.Parameter `json:"parameters"`
|
||||||
|
Signatures map[string]string `json:"signatures"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetSignature returns signature for pub if present.
|
||||||
|
func (it *Item) GetSignature(pub *keys.PublicKey) []byte {
|
||||||
|
return it.Signatures[hex.EncodeToString(pub.Bytes())]
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddSignature adds a signature for pub.
|
||||||
|
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: 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
|
||||||
|
}
|
||||||
|
|
||||||
|
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 = ci.Script
|
||||||
|
it.Parameters = ci.Parameters
|
||||||
|
return nil
|
||||||
|
}
|
74
pkg/smartcontract/context/item_test.go
Normal file
74
pkg/smartcontract/context/item_test.go
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
package context
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/hex"
|
||||||
|
"encoding/json"
|
||||||
|
"io"
|
||||||
|
"math/rand"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/nspcc-dev/neo-go/pkg/smartcontract"
|
||||||
|
|
||||||
|
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||||
|
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestContextItem_AddSignature(t *testing.T) {
|
||||||
|
item := &Item{Signatures: make(map[string][]byte)}
|
||||||
|
|
||||||
|
priv1, err := keys.NewPrivateKey()
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
pub1 := priv1.PublicKey()
|
||||||
|
sig1 := []byte{1, 2, 3}
|
||||||
|
item.AddSignature(pub1, sig1)
|
||||||
|
require.Equal(t, sig1, item.GetSignature(pub1))
|
||||||
|
|
||||||
|
priv2, err := keys.NewPrivateKey()
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
pub2 := priv2.PublicKey()
|
||||||
|
sig2 := []byte{5, 6, 7}
|
||||||
|
item.AddSignature(pub2, sig2)
|
||||||
|
require.Equal(t, sig2, item.GetSignature(pub2))
|
||||||
|
require.Equal(t, sig1, item.GetSignature(pub1))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestContextItem_MarshalJSON(t *testing.T) {
|
||||||
|
priv1, err := keys.NewPrivateKey()
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
priv2, err := keys.NewPrivateKey()
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
expected := &Item{
|
||||||
|
Script: util.Uint160{1, 2, 3},
|
||||||
|
Parameters: []smartcontract.Parameter{{
|
||||||
|
Type: smartcontract.SignatureType,
|
||||||
|
Value: getRandomSlice(t, 64),
|
||||||
|
}},
|
||||||
|
Signatures: map[string][]byte{
|
||||||
|
hex.EncodeToString(priv1.PublicKey().Bytes()): getRandomSlice(t, 64),
|
||||||
|
hex.EncodeToString(priv2.PublicKey().Bytes()): getRandomSlice(t, 64),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
data, err := json.Marshal(expected)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
actual := new(Item)
|
||||||
|
require.NoError(t, json.Unmarshal(data, actual))
|
||||||
|
assert.Equal(t, expected, actual)
|
||||||
|
}
|
||||||
|
|
||||||
|
func getRandomSlice(t *testing.T, n int) []byte {
|
||||||
|
src := rand.NewSource(time.Now().UnixNano())
|
||||||
|
r := rand.New(src)
|
||||||
|
data := make([]byte, n)
|
||||||
|
_, err := io.ReadFull(r, data)
|
||||||
|
require.NoError(t, err)
|
||||||
|
return data
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue