diff --git a/pkg/vm/stack_item.go b/pkg/vm/stack_item.go index 6dff26040..26b758e60 100644 --- a/pkg/vm/stack_item.go +++ b/pkg/vm/stack_item.go @@ -193,3 +193,50 @@ func (i *ArrayItem) MarshalJSON() ([]byte, error) { func (i *ArrayItem) String() string { return "Array" } + +// MapItem represents Map object. +type MapItem struct { + value map[interface{}]StackItem +} + +// NewMapItem returns new MapItem object. +func NewMapItem() *MapItem { + return &MapItem{ + value: make(map[interface{}]StackItem), + } +} + +// Value implements StackItem interface. +func (i *MapItem) Value() interface{} { + return i.value +} + +// MarshalJSON implements the json.Marshaler interface. +func (i *MapItem) String() string { + return "Map" +} + +// Has checks if map has specified key. +func (i *MapItem) Has(key StackItem) (ok bool) { + _, ok = i.value[toMapKey(key)] + return +} + +// Add adds key-value pair to the map. +func (i *MapItem) Add(key, value StackItem) { + i.value[toMapKey(key)] = value +} + +// toMapKey converts StackItem so that it can be used as a map key. +func toMapKey(key StackItem) interface{} { + switch t := key.(type) { + case *BoolItem: + return t.value + case *BigIntegerItem: + return t.value.Int64() + case *ByteArrayItem: + return string(t.value) + default: + panic("wrong key type") + } +} diff --git a/pkg/vm/vm.go b/pkg/vm/vm.go index 23760fbb9..6292e07de 100644 --- a/pkg/vm/vm.go +++ b/pkg/vm/vm.go @@ -912,9 +912,12 @@ func (v *VM) execute(ctx *Context, op Instruction) { } v.estack.PushVal(sigok) - case NEWMAP, HASKEY, KEYS, VALUES: + case HASKEY, KEYS, VALUES: panic("unimplemented") + case NEWMAP: + v.estack.Push(&Element{value: NewMapItem()}) + // Cryptographic operations. case SHA1: b := v.estack.Pop().Bytes()