github.com/ontio/ontology@v1.14.4/vm/neovm/types/neovm_value.go (about)

     1  /*
     2   * Copyright (C) 2018 The ontology Authors
     3   * This file is part of The ontology library.
     4   *
     5   * The ontology is free software: you can redistribute it and/or modify
     6   * it under the terms of the GNU Lesser General Public License as published by
     7   * the Free Software Foundation, either version 3 of the License, or
     8   * (at your option) any later version.
     9   *
    10   * The ontology is distributed in the hope that it will be useful,
    11   * but WITHOUT ANY WARRANTY; without even the implied warranty of
    12   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    13   * GNU Lesser General Public License for more details.
    14   *
    15   * You should have received a copy of the GNU Lesser General Public License
    16   * along with The ontology.  If not, see <http://www.gnu.org/licenses/>.
    17   */
    18  
    19  package types
    20  
    21  import (
    22  	"bytes"
    23  	"fmt"
    24  	"io"
    25  	"math"
    26  	"math/big"
    27  	"reflect"
    28  	"sort"
    29  
    30  	"github.com/ontio/ontology/common"
    31  	"github.com/ontio/ontology/common/log"
    32  	"github.com/ontio/ontology/vm/crossvm_codec"
    33  	"github.com/ontio/ontology/vm/neovm/constants"
    34  	"github.com/ontio/ontology/vm/neovm/errors"
    35  )
    36  
    37  const (
    38  	bytearrayType byte = 0x00
    39  	boolType      byte = 0x01
    40  	integerType   byte = 0x02
    41  	bigintType    byte = 0x03
    42  	interopType   byte = 0x40
    43  	arrayType     byte = 0x80
    44  	structType    byte = 0x81
    45  	mapType       byte = 0x82
    46  )
    47  
    48  const (
    49  	MAX_COUNT         = 1024
    50  	MAX_NOTIFY_LENGTH = 64 * 1024 //64Kb
    51  )
    52  
    53  type VmValue struct {
    54  	valType   byte
    55  	integer   int64
    56  	bigInt    *big.Int
    57  	byteArray []byte
    58  	structval *StructValue
    59  	array     *ArrayValue
    60  	mapval    *MapValue
    61  	interop   InteropValue
    62  }
    63  
    64  func VmValueFromInt64(val int64) VmValue {
    65  	return VmValue{valType: integerType, integer: val}
    66  }
    67  
    68  func VmValueFromBytes(val []byte) (result VmValue, err error) {
    69  	if len(val) > constants.MAX_BYTEARRAY_SIZE {
    70  		err = errors.ERR_OVER_MAX_ITEM_SIZE
    71  		return
    72  	}
    73  	result.valType = bytearrayType
    74  	result.byteArray = val
    75  	return
    76  }
    77  
    78  func VmValueFromBool(val bool) VmValue {
    79  	if val {
    80  		return VmValue{valType: boolType, integer: 1}
    81  	} else {
    82  		return VmValue{valType: boolType, integer: 0}
    83  	}
    84  }
    85  
    86  func VmValueFromUint64(val uint64) VmValue {
    87  	if val <= math.MaxInt64 {
    88  		return VmValueFromInt64(int64(val))
    89  	}
    90  
    91  	b := big.NewInt(0)
    92  	b.SetUint64(val)
    93  	return VmValue{valType: bigintType, bigInt: b}
    94  }
    95  
    96  func VmValueFromBigInt(val *big.Int) (result VmValue, err error) {
    97  	value, e := IntValFromBigInt(val)
    98  	if e != nil {
    99  		err = e
   100  		return
   101  	}
   102  
   103  	return VmValueFromIntValue(value), nil
   104  }
   105  
   106  func VmValueFromArrayVal(array *ArrayValue) VmValue {
   107  	return VmValue{valType: arrayType, array: array}
   108  }
   109  
   110  func VmValueFromStructVal(val *StructValue) VmValue {
   111  	return VmValue{valType: structType, structval: val}
   112  }
   113  
   114  func VmValueFromInteropValue(val InteropValue) VmValue {
   115  	return VmValue{valType: interopType, interop: val}
   116  }
   117  func VmValueFromMapValue(val *MapValue) VmValue {
   118  	return VmValue{valType: mapType, mapval: val}
   119  }
   120  
   121  func NewMapVmValue() VmValue {
   122  	return VmValue{valType: mapType, mapval: NewMapValue()}
   123  }
   124  
   125  func VmValueFromIntValue(val IntValue) VmValue {
   126  	if val.isbig {
   127  		return VmValue{valType: bigintType, bigInt: val.bigint}
   128  	} else {
   129  		return VmValue{valType: integerType, integer: val.integer}
   130  	}
   131  }
   132  
   133  func (self *VmValue) AsBytes() ([]byte, error) {
   134  	switch self.valType {
   135  	case boolType:
   136  		if self.integer == 0 {
   137  			return []byte{0}, nil
   138  		} else {
   139  			return []byte{1}, nil
   140  		}
   141  	case integerType:
   142  		return common.BigIntToNeoBytes(big.NewInt(self.integer)), nil
   143  	case bigintType:
   144  		return common.BigIntToNeoBytes(self.bigInt), nil
   145  	case bytearrayType:
   146  		return self.byteArray, nil
   147  	case arrayType, mapType, structType, interopType:
   148  		return nil, errors.ERR_BAD_TYPE
   149  	default:
   150  		panic("unreachable!")
   151  	}
   152  }
   153  
   154  func (self *VmValue) BuildParamToNative(sink *common.ZeroCopySink) error {
   155  	b, err := self.CircularRefAndDepthDetection()
   156  	if err != nil {
   157  		return err
   158  	}
   159  	if b {
   160  		return fmt.Errorf("runtime serialize: can not serialize circular reference data")
   161  	}
   162  	return self.buildParamToNative(sink)
   163  }
   164  
   165  func (self *VmValue) buildParamToNative(sink *common.ZeroCopySink) error {
   166  	switch self.valType {
   167  	case bytearrayType:
   168  		sink.WriteVarBytes(self.byteArray)
   169  	case boolType:
   170  		b, err := self.AsBool()
   171  		if err != nil {
   172  			return err
   173  		}
   174  		sink.WriteBool(b)
   175  	case integerType, bigintType:
   176  		bs, err := self.AsBytes()
   177  		if err != nil {
   178  			return err
   179  		}
   180  		sink.WriteVarBytes(bs)
   181  	case arrayType:
   182  		sink.WriteVarBytes(common.BigIntToNeoBytes(big.NewInt(int64(len(self.array.Data)))))
   183  		for _, v := range self.array.Data {
   184  			err := v.BuildParamToNative(sink)
   185  			if err != nil {
   186  				return err
   187  			}
   188  		}
   189  	case structType:
   190  		for _, v := range self.structval.Data {
   191  			err := v.BuildParamToNative(sink)
   192  			if err != nil {
   193  				return err
   194  			}
   195  		}
   196  	case mapType:
   197  		//TODO
   198  		return errors.ERR_BAD_TYPE
   199  	case interopType:
   200  		return errors.ERR_BAD_TYPE
   201  	default:
   202  		panic("unreachable!")
   203  	}
   204  	return nil
   205  }
   206  func (self *VmValue) ConvertNeoVmValueHexString() (interface{}, error) {
   207  	var count int
   208  	var length int
   209  	res, err := self.convertNeoVmValueHexString(&count, &length)
   210  	if err != nil {
   211  		return nil, err
   212  	}
   213  	if length > MAX_NOTIFY_LENGTH {
   214  		return nil, fmt.Errorf("length over max parameters convert length")
   215  	}
   216  	return res, nil
   217  }
   218  
   219  func (self *VmValue) convertNeoVmValueHexString(count *int, length *int) (interface{}, error) {
   220  	if *count > MAX_COUNT {
   221  		return nil, fmt.Errorf("over max parameters convert length")
   222  	}
   223  	if *length > MAX_NOTIFY_LENGTH {
   224  		return nil, fmt.Errorf("length over max parameters convert length")
   225  	}
   226  	switch self.valType {
   227  	case boolType:
   228  		boo, err := self.AsBool()
   229  		if err != nil {
   230  			return nil, err
   231  		}
   232  		*length++
   233  		if boo {
   234  			return common.ToHexString([]byte{1}), nil
   235  		} else {
   236  			return common.ToHexString([]byte{0}), nil
   237  		}
   238  	case bytearrayType:
   239  		*length += len(self.byteArray)
   240  		return common.ToHexString(self.byteArray), nil
   241  	case integerType:
   242  		var bs []byte
   243  		if self.integer == 0 {
   244  			bs = []byte{0}
   245  		} else {
   246  			bs = common.BigIntToNeoBytes(big.NewInt(self.integer))
   247  		}
   248  		*length += len(bs)
   249  		return common.ToHexString(bs), nil
   250  	case bigintType:
   251  		var bs []byte
   252  		if self.bigInt.Sign() == 0 {
   253  			bs = []byte{0}
   254  		} else {
   255  			bs = common.BigIntToNeoBytes(self.bigInt)
   256  		}
   257  		*length += len(bs)
   258  		return common.ToHexString(bs), nil
   259  	case structType:
   260  		var sstr []interface{}
   261  		for i := 0; i < len(self.structval.Data); i++ {
   262  			*count++
   263  			t, err := self.structval.Data[i].convertNeoVmValueHexString(count, length)
   264  			if err != nil {
   265  				return nil, err
   266  			}
   267  			sstr = append(sstr, t)
   268  		}
   269  		return sstr, nil
   270  	case arrayType:
   271  		var sstr []interface{}
   272  		for i := 0; i < len(self.array.Data); i++ {
   273  			*count++
   274  			t, err := self.array.Data[i].convertNeoVmValueHexString(count, length)
   275  			if err != nil {
   276  				return nil, err
   277  			}
   278  			sstr = append(sstr, t)
   279  		}
   280  		return sstr, nil
   281  	case interopType:
   282  		bs := self.interop.Data.ToArray()
   283  		*length += len(bs)
   284  		return common.ToHexString(bs), nil
   285  	default:
   286  		log.Errorf("[ConvertTypes] Invalid Types!, %x", self.valType)
   287  		return nil, fmt.Errorf("[ConvertTypes] Invalid Types!, %x", self.valType)
   288  	}
   289  }
   290  func (self *VmValue) Deserialize(source *common.ZeroCopySource) error {
   291  	return self.deserialize(source, 0)
   292  }
   293  
   294  func (self *VmValue) deserialize(source *common.ZeroCopySource, depth int) error {
   295  	if depth > MAX_COUNT {
   296  		return fmt.Errorf("vmvalue depth over the uplimit")
   297  	}
   298  	t, eof := source.NextByte()
   299  	if eof {
   300  		return io.ErrUnexpectedEOF
   301  	}
   302  	switch t {
   303  	case boolType:
   304  		b, irregular, eof := source.NextBool()
   305  		if eof {
   306  			return io.ErrUnexpectedEOF
   307  		}
   308  		if irregular {
   309  			return common.ErrIrregularData
   310  		}
   311  		*self = VmValueFromBool(b)
   312  	case bytearrayType:
   313  		data, _, irregular, eof := source.NextVarBytes()
   314  		if eof {
   315  			return io.ErrUnexpectedEOF
   316  		}
   317  		if irregular {
   318  			return common.ErrIrregularData
   319  		}
   320  		value, err := VmValueFromBytes(data)
   321  		if err != nil {
   322  			return err
   323  		}
   324  		*self = value
   325  	case integerType:
   326  		data, _, irregular, eof := source.NextVarBytes()
   327  		if eof {
   328  			return io.ErrUnexpectedEOF
   329  		}
   330  		if irregular {
   331  			return common.ErrIrregularData
   332  		}
   333  		value, err := VmValueFromBigInt(common.BigIntFromNeoBytes(data))
   334  		if err != nil {
   335  			return err
   336  		}
   337  		*self = value
   338  	case arrayType:
   339  		l, _, irregular, eof := source.NextVarUint()
   340  		if eof {
   341  			return io.ErrUnexpectedEOF
   342  		}
   343  		if irregular {
   344  			return common.ErrIrregularData
   345  		}
   346  		arr := new(ArrayValue)
   347  		for i := 0; i < int(l); i++ {
   348  			v := VmValue{}
   349  			err := v.deserialize(source, depth+1)
   350  			if err != nil {
   351  				return err
   352  			}
   353  			err = arr.Append(v)
   354  			if err != nil {
   355  				return err
   356  			}
   357  		}
   358  		*self = VmValueFromArrayVal(arr)
   359  	case mapType:
   360  		l, _, irregular, eof := source.NextVarUint()
   361  		if eof {
   362  			return io.ErrUnexpectedEOF
   363  		}
   364  		if irregular {
   365  			return common.ErrIrregularData
   366  		}
   367  		mapValue := NewMapValue()
   368  		for i := 0; i < int(l); i++ {
   369  			keyValue := VmValue{}
   370  			err := keyValue.deserialize(source, depth+1)
   371  			if err != nil {
   372  				return err
   373  			}
   374  			v := VmValue{}
   375  			err = v.deserialize(source, depth+1)
   376  			if err != nil {
   377  				return err
   378  			}
   379  			err = mapValue.Set(keyValue, v)
   380  			if err != nil {
   381  				return err
   382  			}
   383  		}
   384  		*self = VmValueFromMapValue(mapValue)
   385  	case structType:
   386  		l, _, irregular, eof := source.NextVarUint()
   387  		if eof {
   388  			return io.ErrUnexpectedEOF
   389  		}
   390  		if irregular {
   391  			return common.ErrIrregularData
   392  		}
   393  		structValue := NewStructValue()
   394  		for i := 0; i < int(l); i++ {
   395  			v := VmValue{}
   396  			err := v.deserialize(source, depth+1)
   397  			if err != nil {
   398  				return err
   399  			}
   400  			err = structValue.Append(v)
   401  			if err != nil {
   402  				return err
   403  			}
   404  		}
   405  		*self = VmValueFromStructVal(structValue)
   406  	default:
   407  		return errors.ERR_BAD_TYPE
   408  	}
   409  	return nil
   410  }
   411  
   412  func (self *VmValue) Serialize(sink *common.ZeroCopySink) error {
   413  	b, err := self.CircularRefAndDepthDetection()
   414  	if err != nil {
   415  		return err
   416  	}
   417  	if b {
   418  		return fmt.Errorf("runtime serialize: can not serialize circular reference data")
   419  	}
   420  	switch self.valType {
   421  	case boolType:
   422  		sink.WriteByte(boolType)
   423  		boo, err := self.AsBool()
   424  		if err != nil {
   425  			return err
   426  		}
   427  		sink.WriteBool(boo)
   428  	case bytearrayType:
   429  		sink.WriteByte(bytearrayType)
   430  		sink.WriteVarBytes(self.byteArray)
   431  	case bigintType:
   432  		sink.WriteByte(integerType)
   433  		sink.WriteVarBytes(common.BigIntToNeoBytes(self.bigInt))
   434  	case integerType:
   435  		sink.WriteByte(integerType)
   436  		t := big.NewInt(self.integer)
   437  		sink.WriteVarBytes(common.BigIntToNeoBytes(t))
   438  	case arrayType:
   439  		sink.WriteByte(arrayType)
   440  		sink.WriteVarUint(uint64(len(self.array.Data)))
   441  		for i := 0; i < len(self.array.Data); i++ {
   442  			err := self.array.Data[i].Serialize(sink)
   443  			if err != nil {
   444  				return err
   445  			}
   446  
   447  		}
   448  	case mapType:
   449  		sink.WriteByte(mapType)
   450  		sink.WriteVarUint(uint64(len(self.mapval.Data)))
   451  		keys := self.mapval.getMapSortedKey()
   452  		for _, key := range keys {
   453  			val := self.mapval.Data[key]
   454  			keyVal := val[0]
   455  			err = keyVal.Serialize(sink)
   456  			if err != nil {
   457  				return err
   458  			}
   459  			value := val[1]
   460  			err = value.Serialize(sink)
   461  			if err != nil {
   462  				return err
   463  			}
   464  		}
   465  	case structType:
   466  		sink.WriteByte(structType)
   467  		sink.WriteVarUint(uint64(len(self.structval.Data)))
   468  		for _, item := range self.structval.Data {
   469  			err := item.Serialize(sink)
   470  			if err != nil {
   471  				return err
   472  			}
   473  		}
   474  	case interopType:
   475  		return fmt.Errorf("not support type: interopType")
   476  	default:
   477  		panic("unreachable!")
   478  	}
   479  	if sink.Size() > constants.MAX_BYTEARRAY_SIZE {
   480  		return fmt.Errorf("runtime serialize: can not serialize length over the uplimit")
   481  	}
   482  	return nil
   483  }
   484  
   485  func (self *VmValue) CircularRefAndDepthDetection() (bool, error) {
   486  	return self.circularRefAndDepthDetection(make(map[uintptr]bool), 0)
   487  }
   488  
   489  func (self *VmValue) circularRefAndDepthDetection(visited map[uintptr]bool, depth int) (bool, error) {
   490  	if depth > MAX_STRUCT_DEPTH {
   491  		return true, nil
   492  	}
   493  	switch self.valType {
   494  	case arrayType:
   495  		arr, err := self.AsArrayValue()
   496  		if err != nil {
   497  			return true, err
   498  		}
   499  		if len(arr.Data) == 0 {
   500  			return false, nil
   501  		}
   502  		p := reflect.ValueOf(arr.Data).Pointer()
   503  		if visited[p] {
   504  			return true, nil
   505  		}
   506  		visited[p] = true
   507  		for _, v := range arr.Data {
   508  			return v.circularRefAndDepthDetection(visited, depth+1)
   509  		}
   510  		delete(visited, p)
   511  		return false, nil
   512  	case structType:
   513  		s, err := self.AsStructValue()
   514  		if err != nil {
   515  			return true, err
   516  		}
   517  		if len(s.Data) == 0 {
   518  			return false, nil
   519  		}
   520  
   521  		p := reflect.ValueOf(s.Data).Pointer()
   522  		if visited[p] {
   523  			return true, nil
   524  		}
   525  		visited[p] = true
   526  
   527  		for _, v := range s.Data {
   528  			return v.circularRefAndDepthDetection(visited, depth+1)
   529  		}
   530  
   531  		delete(visited, p)
   532  		return false, nil
   533  	case mapType:
   534  		mp, err := self.AsMapValue()
   535  		if err != nil {
   536  			return true, err
   537  		}
   538  		p := reflect.ValueOf(mp.Data).Pointer()
   539  		if visited[p] {
   540  			return true, nil
   541  		}
   542  		visited[p] = true
   543  		for _, v := range mp.Data {
   544  			return v[1].circularRefAndDepthDetection(visited, depth+1)
   545  		}
   546  		delete(visited, p)
   547  		return false, nil
   548  	default:
   549  		return false, nil
   550  	}
   551  }
   552  
   553  func (self *VmValue) AsInt64() (int64, error) {
   554  	val, err := self.AsIntValue()
   555  	if err != nil {
   556  		return 0, err
   557  	}
   558  	if val.isbig {
   559  		if !val.bigint.IsInt64() {
   560  			return 0, errors.ERR_INTEGER_UNDERFLOW
   561  		}
   562  		return val.bigint.Int64(), nil
   563  	}
   564  
   565  	return val.integer, nil
   566  }
   567  
   568  // urgly hack: only used in cmp opcode to lift the 32byte limit of integer
   569  func (self *VmValue) AsBigInt() (*big.Int, error) {
   570  	switch self.valType {
   571  	case integerType, boolType:
   572  		return big.NewInt(self.integer), nil
   573  	case bigintType:
   574  		return self.bigInt, nil
   575  	case bytearrayType:
   576  		value := common.BigIntFromNeoBytes(self.byteArray)
   577  		return value, nil
   578  	case arrayType, mapType, structType, interopType:
   579  		return nil, errors.ERR_BAD_TYPE
   580  	default:
   581  		panic("unreachable!")
   582  	}
   583  }
   584  
   585  func (self *VmValue) AsIntValue() (IntValue, error) {
   586  	switch self.valType {
   587  	case integerType, boolType:
   588  		return IntValFromInt(self.integer), nil
   589  	case bigintType:
   590  		return IntValFromBigInt(self.bigInt)
   591  	case bytearrayType:
   592  		return IntValFromNeoBytes(self.byteArray)
   593  	case arrayType, mapType, structType, interopType:
   594  		return IntValue{}, errors.ERR_BAD_TYPE
   595  	default:
   596  		panic("unreachable!")
   597  	}
   598  }
   599  
   600  func (self *VmValue) AsBool() (bool, error) {
   601  	switch self.valType {
   602  	case integerType, boolType:
   603  		return self.integer != 0, nil
   604  	case bigintType:
   605  		return self.bigInt.Sign() != 0, nil
   606  	case bytearrayType:
   607  		for _, b := range self.byteArray {
   608  			if b != 0 {
   609  				return true, nil
   610  			}
   611  		}
   612  		return false, nil
   613  	case structType, mapType:
   614  		return true, nil
   615  	case arrayType:
   616  		return false, errors.ERR_BAD_TYPE
   617  	case interopType:
   618  		return self.interop != InteropValue{}, nil
   619  	default:
   620  		panic("unreachable!")
   621  	}
   622  }
   623  
   624  func (self *VmValue) AsMapValue() (*MapValue, error) {
   625  	switch self.valType {
   626  	case mapType:
   627  		return self.mapval, nil
   628  	default:
   629  		return nil, errors.ERR_BAD_TYPE
   630  	}
   631  }
   632  
   633  func (self *VmValue) AsStructValue() (*StructValue, error) {
   634  	switch self.valType {
   635  	case structType:
   636  		return self.structval, nil
   637  	default:
   638  		return nil, errors.ERR_BAD_TYPE
   639  	}
   640  }
   641  
   642  func (self *VmValue) AsArrayValue() (*ArrayValue, error) {
   643  	switch self.valType {
   644  	case arrayType:
   645  		return self.array, nil
   646  	default:
   647  		return nil, errors.ERR_BAD_TYPE
   648  	}
   649  }
   650  
   651  func (self *VmValue) AsInteropValue() (InteropValue, error) {
   652  	switch self.valType {
   653  	case interopType:
   654  		return self.interop, nil
   655  	default:
   656  		return InteropValue{}, errors.ERR_BAD_TYPE
   657  	}
   658  }
   659  
   660  func (self *VmValue) Equals(other VmValue) bool {
   661  	v1, e1 := self.AsBytes()
   662  	v2, e2 := other.AsBytes()
   663  	if e1 == nil && e2 == nil { // both are primitive type
   664  		return bytes.Equal(v1, v2)
   665  	}
   666  
   667  	// here more than one are compound type
   668  	if self.valType != other.valType {
   669  		return false
   670  	}
   671  
   672  	switch self.valType {
   673  	case mapType:
   674  		return self.mapval == other.mapval
   675  	case structType:
   676  		// todo: fix inconsistence
   677  		return reflect.DeepEqual(self.structval, other.structval)
   678  	case arrayType:
   679  		return self.array == other.array
   680  	case interopType:
   681  		return self.interop.Equals(other.interop)
   682  	default:
   683  		panic("unreachable!")
   684  	}
   685  }
   686  
   687  func (self *VmValue) GetType() byte {
   688  	switch self.valType {
   689  	case integerType, bigintType:
   690  		return IntegerType
   691  	default:
   692  		return self.valType
   693  	}
   694  }
   695  
   696  func (self *VmValue) GetMapKey() (string, error) {
   697  	val, err := self.AsBytes()
   698  	if err != nil {
   699  		return "", err
   700  	}
   701  	return string(val), nil
   702  }
   703  
   704  //only for debug/testing
   705  func (self *VmValue) Stringify() (string, error) {
   706  	b, err := self.CircularRefAndDepthDetection()
   707  	if err != nil {
   708  		return "", fmt.Errorf("error: %v", err)
   709  	}
   710  	if b {
   711  		return "", fmt.Errorf("error: can not serialize circular reference data")
   712  	}
   713  	return self.stringify(), nil
   714  }
   715  func (self *VmValue) stringify() string {
   716  	switch self.valType {
   717  	case boolType, bytearrayType, bigintType, integerType:
   718  		bs, _ := self.AsBytes()
   719  		if len(bs) == 0 {
   720  			bs = []byte{0}
   721  		}
   722  		return fmt.Sprintf("bytes(hex:%x)", bs)
   723  	case arrayType:
   724  		data := ""
   725  		for _, v := range self.array.Data {
   726  			data += v.stringify() + ", "
   727  		}
   728  		return fmt.Sprintf("array[%d]{%s}", len(self.array.Data), data)
   729  	case mapType:
   730  		keys := self.mapval.getMapSortedKey()
   731  		data := ""
   732  		for _, key := range keys {
   733  			v := self.mapval.Data[key][1]
   734  			data += fmt.Sprintf("%x: %s,", key, v.stringify())
   735  		}
   736  		return fmt.Sprintf("map[%d]{%s}", len(self.mapval.Data), data)
   737  	case interopType:
   738  		ty := reflect.TypeOf(self.interop.Data).String()
   739  		return fmt.Sprintf("interop{type:%s}", ty)
   740  	case structType:
   741  		data := ""
   742  		for _, v := range self.structval.Data {
   743  			data += v.stringify() + ", "
   744  		}
   745  		return fmt.Sprintf("struct[%d]{%s}", len(self.structval.Data), data)
   746  	default:
   747  		panic("unreachable!")
   748  	}
   749  	return ""
   750  }
   751  
   752  //only for debug/testing
   753  func (self *VmValue) Dump() string {
   754  	b, err := self.CircularRefAndDepthDetection()
   755  	if err != nil {
   756  		return fmt.Sprintf("error: %v", err)
   757  	}
   758  	if b {
   759  		return "error: can not serialize circular reference data"
   760  	}
   761  	return self.dump()
   762  }
   763  
   764  func (self *VmValue) dump() string {
   765  	switch self.valType {
   766  	case boolType:
   767  		bs, _ := self.AsBool()
   768  		return fmt.Sprintf("bool(%v)", bs)
   769  	case integerType:
   770  		return fmt.Sprintf("int(%d)", self.integer)
   771  	case bigintType:
   772  		return fmt.Sprintf("bigint(0x%x)", self.bigInt)
   773  	case bytearrayType:
   774  		return fmt.Sprintf("string(\"%s\")", self.byteArray)
   775  	case arrayType:
   776  		data := ""
   777  		for _, v := range self.array.Data {
   778  			data += v.dump() + ", "
   779  		}
   780  		return fmt.Sprintf("array[%d]{%s}", len(self.array.Data), data)
   781  	case mapType:
   782  		var unsortKey []string
   783  		for k := range self.mapval.Data {
   784  			unsortKey = append(unsortKey, k)
   785  		}
   786  		sort.Strings(unsortKey)
   787  		data := ""
   788  		for _, key := range unsortKey {
   789  			v := self.mapval.Data[key][1]
   790  			k := self.mapval.Data[key][0]
   791  			data += fmt.Sprintf("%s: %s,", k.dump(), v.dump())
   792  		}
   793  		return fmt.Sprintf("map[%d]{%s}", len(self.mapval.Data), data)
   794  	case structType:
   795  		data := ""
   796  		for _, v := range self.structval.Data {
   797  			data += v.dump() + ", "
   798  		}
   799  		return fmt.Sprintf("struct[%d]{%s}", len(self.structval.Data), data)
   800  	case interopType:
   801  		return fmt.Sprintf("interop[%x]", self.interop.Data)
   802  	default:
   803  		panic("unreachable!")
   804  	}
   805  	return ""
   806  }
   807  
   808  //encode the neovm return vmval
   809  //transform neovm contract result to encoded byte array
   810  func BuildResultFromNeo(item VmValue, bf *common.ZeroCopySink) error {
   811  	if len(bf.Bytes()) > crossvm_codec.MAX_PARAM_LENGTH {
   812  		return fmt.Errorf("parameter buf is too long")
   813  	}
   814  	switch item.valType {
   815  	case bytearrayType:
   816  		bs := item.byteArray
   817  		crossvm_codec.EncodeBytes(bf, bs)
   818  	case integerType:
   819  		val := common.I128FromInt64(item.integer)
   820  		crossvm_codec.EncodeInt128(bf, val)
   821  	case bigintType:
   822  		val := item.bigInt
   823  		err := crossvm_codec.EncodeBigInt(bf, val)
   824  		if err != nil {
   825  			return err
   826  		}
   827  	case boolType:
   828  		val, err := item.AsBool()
   829  		if err != nil {
   830  			return err
   831  		}
   832  		crossvm_codec.EncodeBool(bf, val)
   833  	case arrayType:
   834  		val := item.array
   835  		if val == nil {
   836  			return fmt.Errorf("get array error")
   837  		}
   838  		bf.WriteByte(crossvm_codec.ListType)
   839  		bf.WriteUint32(uint32(len(val.Data)))
   840  		for _, si := range val.Data {
   841  			err := BuildResultFromNeo(si, bf)
   842  			if err != nil {
   843  				return err
   844  			}
   845  		}
   846  
   847  	default:
   848  		return fmt.Errorf("not a supported return type")
   849  	}
   850  	return nil
   851  }