github.com/n1ghtfa1l/go-vnt@v0.6.4-alpha.6/core/wavm/env_funcs.go (about)

     1  // Copyright 2019 The go-vnt Authors
     2  // This file is part of the go-vnt library.
     3  //
     4  // The go-vnt library is free software: you can redistribute it and/or modify
     5  // it under the terms of the GNU Lesser General Public License as published by
     6  // the Free Software Foundation, either version 3 of the License, or
     7  // (at your option) any later version.
     8  //
     9  // The go-vnt library is distributed in the hope that it will be useful,
    10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    12  // GNU Lesser General Public License for more details.
    13  //
    14  // You should have received a copy of the GNU Lesser General Public License
    15  // along with the go-vnt library. If not, see <http://www.gnu.org/licenses/>.
    16  
    17  package wavm
    18  
    19  import (
    20  	"bytes"
    21  	"encoding/binary"
    22  	"encoding/hex"
    23  	"errors"
    24  	"fmt"
    25  	"math/big"
    26  	"reflect"
    27  	"strconv"
    28  
    29  	"github.com/vntchain/go-vnt/common/math"
    30  
    31  	"github.com/vntchain/go-vnt/accounts/abi"
    32  	"github.com/vntchain/go-vnt/common"
    33  	mat "github.com/vntchain/go-vnt/common/math"
    34  	"github.com/vntchain/go-vnt/core/types"
    35  	errormsg "github.com/vntchain/go-vnt/core/vm"
    36  	"github.com/vntchain/go-vnt/core/wavm/storage"
    37  	"github.com/vntchain/go-vnt/core/wavm/utils"
    38  	"github.com/vntchain/go-vnt/crypto"
    39  	"github.com/vntchain/go-vnt/log"
    40  	"github.com/vntchain/go-vnt/params"
    41  	"github.com/vntchain/vnt-wasm/exec"
    42  	"github.com/vntchain/vnt-wasm/wasm"
    43  )
    44  
    45  var (
    46  	errExceededArray            = "array length exceeded"
    47  	errUnsupportType            = "unsupported type \"%s\""
    48  	errNoEvent                  = "event execution failed: there is no event '%s' in abi"
    49  	errEventArgsMismatch        = "event execution failed: expected event args number %d in abi, get args number %d"
    50  	errNoContractCall           = "contractCall execution failed: can not find call '%s' in abi"
    51  	errContractCallArgsMismatch = "contractCall execution failed: expected call args number %d in abi, get args number %d"
    52  	errContractCallResult       = "failed to get result in contract call"
    53  )
    54  
    55  var endianess = binary.LittleEndian
    56  
    57  type EnvFunctions struct {
    58  	ctx       *ChainContext
    59  	funcTable map[string]wasm.Function
    60  }
    61  
    62  //InitFuncTable init event and contract_call function
    63  func (ef *EnvFunctions) InitFuncTable(context *ChainContext) {
    64  	ef.ctx = context
    65  	ef.funcTable = ef.getFuncTable()
    66  
    67  	// process events
    68  	if ef.ctx == nil {
    69  		return
    70  	}
    71  	for _, event := range ef.ctx.Abi.Events {
    72  		paramTypes := make([]wasm.ValueType, len(event.Inputs))
    73  		for index, input := range event.Inputs {
    74  			switch input.Type.T {
    75  			case abi.IntTy, abi.UintTy:
    76  				if input.Type.Size == 64 {
    77  					paramTypes[index] = wasm.ValueTypeI64
    78  				} else if input.Type.Size == 32 || input.Type.Size == 256 {
    79  					paramTypes[index] = wasm.ValueTypeI32
    80  				} else {
    81  					err := fmt.Errorf(errUnsupportType, input.Type.String())
    82  					panic(err)
    83  				}
    84  			case abi.AddressTy, abi.StringTy, abi.BoolTy:
    85  				paramTypes[index] = wasm.ValueTypeI32
    86  			default:
    87  				err := fmt.Errorf(errUnsupportType, input.Type.String())
    88  				panic(err)
    89  			}
    90  		}
    91  		//ef.funcTable[event.Name] = reflect.ValueOf(ef.getEvent(len(event.Inputs), event.Name))
    92  		ef.funcTable[event.Name] = wasm.Function{
    93  			Host: reflect.ValueOf(ef.getEvent(event.Name)),
    94  			Sig: &wasm.FunctionSig{
    95  				ParamTypes:  paramTypes,
    96  				ReturnTypes: []wasm.ValueType{},
    97  			},
    98  			Body: &wasm.FunctionBody{
    99  				Code: []byte{},
   100  			},
   101  		}
   102  
   103  	}
   104  
   105  	// process contract calls
   106  	for _, call := range ef.ctx.Abi.Calls {
   107  		paramTypes := make([]wasm.ValueType, len(call.Inputs)+1)
   108  		paramTypes[0] = wasm.ValueTypeI32
   109  		for index, input := range call.Inputs {
   110  			idx := index + 1
   111  			switch input.Type.T {
   112  			case abi.IntTy, abi.UintTy:
   113  				if input.Type.Size == 64 {
   114  					paramTypes[idx] = wasm.ValueTypeI64
   115  				} else if input.Type.Size == 32 || input.Type.Size == 256 {
   116  					paramTypes[idx] = wasm.ValueTypeI32
   117  				} else {
   118  					err := fmt.Errorf(errUnsupportType, input.Type.String())
   119  					panic(err)
   120  				}
   121  			case abi.AddressTy, abi.StringTy, abi.BoolTy:
   122  				paramTypes[idx] = wasm.ValueTypeI32
   123  			default:
   124  				err := fmt.Errorf(errUnsupportType, input.Type.String())
   125  				panic(err)
   126  			}
   127  
   128  		}
   129  		returnTypes := make([]wasm.ValueType, len(call.Outputs))
   130  		for index, output := range call.Outputs {
   131  			switch output.Type.T {
   132  			case abi.IntTy, abi.UintTy:
   133  				if output.Type.Size == 64 {
   134  					returnTypes[index] = wasm.ValueTypeI64
   135  				} else if output.Type.Size == 32 || output.Type.Size == 256 {
   136  					returnTypes[index] = wasm.ValueTypeI32
   137  				} else {
   138  					err := fmt.Errorf(errUnsupportType, output.Type.String())
   139  					panic(err)
   140  				}
   141  			case abi.AddressTy, abi.StringTy, abi.BoolTy:
   142  				returnTypes[index] = wasm.ValueTypeI32
   143  			default:
   144  				err := fmt.Errorf(errUnsupportType, output.Type.String())
   145  				panic(err)
   146  			}
   147  		}
   148  		ef.funcTable[call.Name] = wasm.Function{
   149  			Host: reflect.ValueOf(ef.getContractCall(call.Name)),
   150  			Sig: &wasm.FunctionSig{
   151  				ParamTypes:  paramTypes,
   152  				ReturnTypes: returnTypes,
   153  			},
   154  			Body: &wasm.FunctionBody{
   155  				Code: []byte{},
   156  			},
   157  		}
   158  	}
   159  }
   160  
   161  //GetFuncTable get the env function table
   162  func (ef *EnvFunctions) GetFuncTable() map[string]wasm.Function {
   163  	return ef.funcTable
   164  }
   165  
   166  //GetBalanceFromAddress get balance from address
   167  func (ef *EnvFunctions) GetBalanceFromAddress(proc *exec.WavmProcess, locIndex uint64) uint64 {
   168  	ef.ctx.GasCounter.GasGetBalanceFromAddress()
   169  	ctx := ef.ctx
   170  	addr := common.BytesToAddress(proc.ReadAt(locIndex))
   171  	balance := ctx.StateDB.GetBalance(addr)
   172  	return ef.returnU256(proc, balance)
   173  }
   174  
   175  //GetBlockNumber get the block number
   176  func (ef *EnvFunctions) GetBlockNumber(proc *exec.WavmProcess) uint64 {
   177  	ef.ctx.GasCounter.GasGetBlockNumber()
   178  	return ef.ctx.BlockNumber.Uint64()
   179  }
   180  
   181  //GetGas get the rest gas
   182  func (ef *EnvFunctions) GetGas(proc *exec.WavmProcess) uint64 {
   183  	ef.ctx.GasCounter.GasGetGas()
   184  	return ef.ctx.Contract.Gas
   185  }
   186  
   187  //GetBlockHash get the block hash
   188  func (ef *EnvFunctions) GetBlockHash(proc *exec.WavmProcess, blockNum uint64) uint64 {
   189  	ctx := ef.ctx
   190  	ctx.GasCounter.GasGetBlockHash()
   191  	num := new(big.Int).SetUint64(blockNum)
   192  	bigval := new(big.Int)
   193  	n := bigval.Sub(ctx.BlockNumber, common.Big257)
   194  	if num.Cmp(n) > 0 && num.Cmp(ctx.BlockNumber) < 0 {
   195  		bhash := ctx.GetHash(num.Uint64())
   196  		return ef.returnHash(proc, []byte(bhash.Hex()))
   197  	} else {
   198  		return ef.returnHash(proc, []byte(common.Hash{}.Hex()))
   199  	}
   200  }
   201  
   202  //GetBlockProduser get the block produser address
   203  func (ef *EnvFunctions) GetBlockProduser(proc *exec.WavmProcess) uint64 {
   204  	ctx := ef.ctx
   205  	ctx.GasCounter.GasGetBlockProduser()
   206  	coinbase := ctx.Coinbase.Bytes()
   207  	return ef.returnAddress(proc, coinbase)
   208  }
   209  
   210  //GetTimestamp get the block timestamp
   211  func (ef *EnvFunctions) GetTimestamp(proc *exec.WavmProcess) uint64 {
   212  	ef.ctx.GasCounter.GasGetTimestamp()
   213  	return ef.ctx.Time.Uint64()
   214  }
   215  
   216  //GetOrigin get tx origin
   217  func (ef *EnvFunctions) GetOrigin(proc *exec.WavmProcess) uint64 {
   218  	ctx := ef.ctx
   219  	ctx.GasCounter.GasGetOrigin()
   220  	origin := ctx.Origin.Bytes()
   221  	return ef.returnAddress(proc, origin)
   222  }
   223  
   224  //GetSender get tx sender
   225  func (ef *EnvFunctions) GetSender(proc *exec.WavmProcess) uint64 {
   226  	ctx := ef.ctx
   227  	ctx.GasCounter.GasGetSender()
   228  	sender := ctx.Contract.CallerAddress.Bytes()
   229  	return ef.returnAddress(proc, sender)
   230  }
   231  
   232  //GetGasLimit get the block gaslimit
   233  func (ef *EnvFunctions) GetGasLimit(proc *exec.WavmProcess) uint64 {
   234  	ctx := ef.ctx
   235  	ctx.GasCounter.GasGetGasLimit()
   236  	return ctx.GasLimit
   237  }
   238  
   239  //GetValue get tranfer vnt amount of a tx
   240  func (ef *EnvFunctions) GetValue(proc *exec.WavmProcess) uint64 {
   241  	ctx := ef.ctx
   242  	ctx.GasCounter.GasGetValue()
   243  	val := ctx.Contract.Value()
   244  	return ef.returnU256(proc, val)
   245  }
   246  
   247  //SHA3
   248  func (ef *EnvFunctions) SHA3(proc *exec.WavmProcess, dataIdx uint64) uint64 {
   249  	data := proc.ReadAt(dataIdx)
   250  	ef.ctx.GasCounter.GasSHA3(uint64(len(data)))
   251  	hash := []byte(crypto.Keccak256Hash(data).Hex())
   252  	return uint64(proc.SetBytes(hash))
   253  }
   254  
   255  //Ecrecover
   256  func (ef *EnvFunctions) Ecrecover(proc *exec.WavmProcess, hashptr uint64, sigv uint64, sigr uint64, sigs uint64) uint64 {
   257  	ef.ctx.GasCounter.GasEcrecover()
   258  	hashBytes := proc.ReadAt(hashptr)
   259  	hash := common.HexToHash(string(hashBytes))
   260  
   261  	r := new(big.Int).SetBytes(common.FromHex(string(proc.ReadAt(sigr))))
   262  	s := new(big.Int).SetBytes(common.FromHex(string(proc.ReadAt(sigs))))
   263  	v := new(big.Int).SetBytes(common.FromHex(string(proc.ReadAt(sigv))))
   264  	v = v.Sub(v, new(big.Int).SetUint64(27))
   265  	if v.Cmp(new(big.Int).SetUint64(0)) != 0 && v.Cmp(new(big.Int).SetUint64(1)) != 0 {
   266  		return ef.returnAddress(proc, []byte(""))
   267  	}
   268  	// tighter sig s values input homestead only apply to tx sigs
   269  	sigV := byte(1)
   270  	if len(v.Bytes()) == 0 {
   271  		sigV = byte(0)
   272  	}
   273  
   274  	if !crypto.ValidateSignatureValues(sigV, r, s, false) {
   275  		return ef.returnAddress(proc, []byte(""))
   276  	}
   277  	// v needs to be at the end for libsecp256k1
   278  	pubKey, err := crypto.Ecrecover(hash.Bytes(), append(append(r.Bytes(), s.Bytes()...), sigV))
   279  	// make sure the public key is a valid one
   280  	if err != nil {
   281  		return ef.returnAddress(proc, []byte(""))
   282  	}
   283  
   284  	// // the first byte of pubkey is bitcoin heritage
   285  	addr := common.LeftPadBytes(crypto.Keccak256(pubKey[1:])[12:], 32)
   286  	return ef.returnAddress(proc, addr)
   287  }
   288  
   289  //GetContractAddress get contract address
   290  func (ef *EnvFunctions) GetContractAddress(proc *exec.WavmProcess) uint64 {
   291  	ctx := ef.ctx
   292  	ctx.GasCounter.GasGetContractAddress()
   293  	addr := ctx.Contract.Address().Bytes()
   294  	return ef.returnAddress(proc, addr)
   295  }
   296  
   297  func (ef *EnvFunctions) Assert(proc *exec.WavmProcess, condition uint64, msgIdx uint64) {
   298  	ef.ctx.GasCounter.GasAssert()
   299  	msg := proc.ReadAt(msgIdx)
   300  	if condition != 1 {
   301  		err := fmt.Sprintf("%s: %s", errormsg.ErrExecutionAssert, string(msg))
   302  		log.Error(err)
   303  		panic(err)
   304  	}
   305  }
   306  
   307  func (ef *EnvFunctions) SendFromContract(proc *exec.WavmProcess, addrIdx uint64, amountIdx uint64) {
   308  	ef.forbiddenMutable(proc)
   309  	ef.ctx.GasCounter.GasSendFromContract()
   310  	addr := common.BytesToAddress(proc.ReadAt(addrIdx))
   311  	amount := utils.GetU256(proc.ReadAt(amountIdx))
   312  	if ef.ctx.CanTransfer(ef.ctx.StateDB, ef.ctx.Contract.Address(), amount) {
   313  		_, _, err := ef.ctx.Wavm.Call(ef.ctx.Contract, addr, nil, params.CallStipend, amount)
   314  		// ef.ctx.GasCounter.Charge(returnGas)
   315  		if err != nil {
   316  			panic(errormsg.ErrExecutionReverted)
   317  		}
   318  	} else {
   319  		panic(errormsg.ErrExecutionReverted)
   320  	}
   321  }
   322  
   323  func (ef *EnvFunctions) TransferFromContract(proc *exec.WavmProcess, addrIdx uint64, amountIdx uint64) uint64 {
   324  	ef.forbiddenMutable(proc)
   325  	ef.ctx.GasCounter.GasSendFromContract()
   326  	addr := common.BytesToAddress(proc.ReadAt(addrIdx))
   327  	amount := utils.GetU256(proc.ReadAt(amountIdx))
   328  	if ef.ctx.CanTransfer(ef.ctx.StateDB, ef.ctx.Contract.Address(), amount) {
   329  		_, _, err := ef.ctx.Wavm.Call(ef.ctx.Contract, addr, nil, params.CallStipend, amount)
   330  		// ef.ctx.GasCounter.Charge(returnGas)
   331  		if err != nil {
   332  			return 0
   333  		}
   334  		return 1
   335  	}
   336  	return 0
   337  }
   338  
   339  func (ef *EnvFunctions) fromI64(proc *exec.WavmProcess, value uint64) uint64 {
   340  	ef.ctx.GasCounter.GasFromI64()
   341  	amount := int(value)
   342  	str := strconv.Itoa(amount)
   343  	return uint64(proc.SetBytes([]byte(str)))
   344  }
   345  
   346  func (ef *EnvFunctions) fromU64(proc *exec.WavmProcess, amount uint64) uint64 {
   347  	ef.ctx.GasCounter.GasFromU64()
   348  	str := strconv.FormatUint(amount, 10)
   349  	return uint64(proc.SetBytes([]byte(str)))
   350  }
   351  
   352  func (ef *EnvFunctions) toI64(proc *exec.WavmProcess, strIdx uint64) uint64 {
   353  	ef.ctx.GasCounter.GasToI64()
   354  	b := proc.ReadAt(strIdx)
   355  	amount, err := strconv.Atoi(string(b))
   356  	if err != nil {
   357  		return 0
   358  	} else {
   359  		return uint64(amount)
   360  	}
   361  }
   362  
   363  func (ef *EnvFunctions) toU64(proc *exec.WavmProcess, strIdx uint64) uint64 {
   364  	ef.ctx.GasCounter.GasToU64()
   365  	b := proc.ReadAt(strIdx)
   366  	amount, err := strconv.ParseUint(string(b), 10, 64)
   367  	if err != nil {
   368  		return 0
   369  	} else {
   370  		return amount
   371  	}
   372  }
   373  
   374  func (ef *EnvFunctions) Concat(proc *exec.WavmProcess, str1Idx uint64, str2Idx uint64) uint64 {
   375  	str1 := proc.ReadAt(str1Idx)
   376  	str2 := proc.ReadAt(str2Idx)
   377  	ef.ctx.GasCounter.GasConcat(uint64(len(str1) + len(str2)))
   378  	res := append(str1, str2...)
   379  	return uint64(proc.SetBytes(res))
   380  }
   381  
   382  func (ef *EnvFunctions) Equal(proc *exec.WavmProcess, str1Idx uint64, str2Idx uint64) uint64 {
   383  	ef.ctx.GasCounter.GasEqual()
   384  	str1 := proc.ReadAt(str1Idx)
   385  	str2 := proc.ReadAt(str2Idx)
   386  	res := bytes.Equal(str1, str2)
   387  	if res {
   388  		return 1
   389  	} else {
   390  		return 0
   391  	}
   392  }
   393  
   394  func (ef *EnvFunctions) getEvent(funcName string) interface{} {
   395  	fnDef := func(proc *exec.WavmProcess, vars ...uint64) {
   396  		ef.forbiddenMutable(proc)
   397  		Abi := ef.ctx.Abi
   398  
   399  		var event abi.Event
   400  		var ok bool
   401  		if event, ok = Abi.Events[funcName]; !ok {
   402  			panic(fmt.Sprintf(errNoEvent, funcName))
   403  		}
   404  
   405  		abiParamLen := len(event.Inputs)
   406  		paramLen := len(vars)
   407  
   408  		if abiParamLen != paramLen {
   409  			panic(fmt.Sprintf(errEventArgsMismatch, abiParamLen, paramLen))
   410  		}
   411  
   412  		topics := make([]common.Hash, 0)
   413  		data := make([]byte, 0)
   414  
   415  		topics = append(topics, event.Id())
   416  
   417  		strStartIndex := make([]int, 0)
   418  		strData := make([][]byte, 0)
   419  
   420  		for i := 0; i < paramLen; i++ {
   421  			input := event.Inputs[i]
   422  			indexed := input.Indexed
   423  			paramType := input.Type.T
   424  			param := vars[i]
   425  			var value []byte
   426  			switch paramType {
   427  			case abi.AddressTy, abi.StringTy:
   428  				value = proc.ReadAt(param)
   429  			case abi.UintTy, abi.IntTy:
   430  				if input.Type.Kind == reflect.Ptr {
   431  					mem := proc.ReadAt(param)
   432  					bigint := utils.GetU256(mem)
   433  					value = abi.U256(bigint)
   434  				} else if paramType == abi.UintTy {
   435  					value = abi.U256(new(big.Int).SetUint64(param))
   436  				} else {
   437  					if input.Type.Size == 32 {
   438  						value = abi.U256(big.NewInt(int64(int32(param))))
   439  					} else {
   440  						value = abi.U256(big.NewInt(int64(param)))
   441  					}
   442  				}
   443  			case abi.BoolTy:
   444  				if param == 1 {
   445  					value = mat.PaddedBigBytes(common.Big1, 32)
   446  				}
   447  				value = mat.PaddedBigBytes(common.Big0, 32)
   448  			}
   449  
   450  			if indexed {
   451  				if paramType == abi.StringTy {
   452  					value = crypto.Keccak256(value)
   453  				}
   454  				topic := common.BytesToHash(value)
   455  				topics = append(topics, topic)
   456  			} else {
   457  				if paramType == abi.StringTy {
   458  					strStartIndex = append(strStartIndex, len(data))
   459  					data = append(data, make([]byte, 32)...)
   460  					strData = append(strData, value)
   461  				} else {
   462  					data = append(data, common.LeftPadBytes(value, 32)...)
   463  				}
   464  			}
   465  		}
   466  
   467  		// append the string data at the end of the data, and
   468  		// update the start position of string data
   469  		if len(strStartIndex) > 0 {
   470  			for i := range strStartIndex {
   471  				value := strData[i]
   472  				startPos := abi.U256(new(big.Int).SetUint64(uint64(len(data))))
   473  				copy(data[strStartIndex[i]:], startPos)
   474  
   475  				size := abi.U256(new(big.Int).SetUint64(uint64(len(value))))
   476  				data = append(data, size...)
   477  				data = append(data, common.RightPadBytes(value, (len(value)+31)/32*32)...)
   478  			}
   479  		}
   480  
   481  		log.Debug("Will add event log: ", "topics", topics, "data", data, "len", len(data))
   482  		ef.ctx.StateDB.AddLog(&types.Log{
   483  			Address:     ef.ctx.Contract.Address(),
   484  			Topics:      topics,
   485  			Data:        data,
   486  			BlockNumber: ef.ctx.BlockNumber.Uint64(),
   487  		})
   488  		ef.ctx.GasCounter.GasLog(uint64(len(data)), uint64(len(topics)))
   489  		log.Debug("Added event log.")
   490  	}
   491  
   492  	return fnDef
   493  }
   494  
   495  //todo 如果一个unmutable的方法跨合约调用了一个mutable的方法 则会报错
   496  func (ef *EnvFunctions) getContractCall(funcName string) interface{} {
   497  	Abi := ef.ctx.Abi
   498  
   499  	var dc abi.Method
   500  	var ok bool
   501  	if dc, ok = Abi.Calls[funcName]; !ok {
   502  		panic(fmt.Sprintf(errNoContractCall, funcName))
   503  	}
   504  
   505  	fnDef := func(proc *exec.WavmProcess, vars ...uint64) interface{} {
   506  		// ef.forbiddenMutable(proc)
   507  		abiParamLen := len(dc.Inputs)
   508  		paramLen := len(vars)
   509  		if abiParamLen+1 != paramLen {
   510  			panic(fmt.Sprintf(errContractCallArgsMismatch, abiParamLen+1, paramLen))
   511  		}
   512  
   513  		args := []interface{}{}
   514  		for i := 1; i < paramLen; i++ {
   515  			input := dc.Inputs[i-1]
   516  			paramType := input.Type.T
   517  			param := vars[i]
   518  			var value []byte
   519  			switch paramType {
   520  			case abi.AddressTy:
   521  				value = proc.ReadAt(param)
   522  				addr := common.BytesToAddress(value)
   523  				args = append(args, addr)
   524  			case abi.StringTy:
   525  				value = proc.ReadAt(param)
   526  				args = append(args, string(value))
   527  			case abi.IntTy:
   528  				if input.Type.Size == 32 {
   529  					args = append(args, int32(param))
   530  				} else if input.Type.Size == 64 {
   531  					args = append(args, int64(param))
   532  				} else {
   533  					err := fmt.Errorf(errUnsupportType, input.Type.String())
   534  					panic(err)
   535  				}
   536  			case abi.UintTy:
   537  				if input.Type.Size == 32 {
   538  					args = append(args, uint32(param))
   539  				} else if input.Type.Size == 64 {
   540  					args = append(args, uint64(param))
   541  				} else if input.Type.Size == 256 {
   542  					mem := proc.ReadAt(param)
   543  					bigint := utils.GetU256(mem)
   544  					args = append(args, bigint)
   545  				} else {
   546  					err := fmt.Errorf(errUnsupportType, input.Type.String())
   547  					panic(err)
   548  				}
   549  			case abi.BoolTy:
   550  				arg := false
   551  				if param == 1 {
   552  					arg = true
   553  				}
   554  				args = append(args, arg)
   555  			default:
   556  				err := fmt.Errorf(errUnsupportType, input.Type.String())
   557  				panic(err)
   558  			}
   559  		}
   560  		var res []byte
   561  		var err error
   562  		if len(args) == 0 {
   563  			res, err = Abi.Pack(funcName)
   564  			if err != nil {
   565  				panic(err.Error())
   566  			}
   567  		} else {
   568  			res, err = Abi.Pack(funcName, args...)
   569  			if err != nil {
   570  				panic(err.Error())
   571  			}
   572  		}
   573  		toAddr := common.BytesToAddress(proc.ReadAt(uint64(endianess.Uint32(proc.GetData()[vars[0]:]))))
   574  		amount := readU256FromMemory(proc, uint64(endianess.Uint32(proc.GetData()[vars[0]+4:])))
   575  		gascost := endianess.Uint64(proc.GetData()[vars[0]+8:])
   576  		// Get arguments from the memory.
   577  		// ef.ctx.GetWavm().GetCallGasTemp
   578  		//todo
   579  		var gaslimit *big.Int
   580  		gaslimit = new(big.Int).SetUint64(gascost)
   581  		gas := ef.ctx.GasCounter.GasCall(toAddr, amount, gaslimit, ef.ctx.BlockNumber, ef.ctx.Wavm.GetChainConfig(), ef.ctx.StateDB)
   582  		ef.ctx.Wavm.SetCallGasTemp(gas)
   583  		//免费提供额外的gas
   584  		if amount.Sign() != 0 {
   585  			gas += params.CallStipend
   586  		}
   587  		ret, returnGas, err := ef.ctx.Wavm.Call(ef.ctx.Contract, toAddr, res, gas, amount)
   588  		failError := errors.New(errContractCallResult)
   589  		if err != nil {
   590  			e := fmt.Errorf("%s Reason : %s", failError, err)
   591  			panic(e)
   592  		} else {
   593  			ef.ctx.Contract.Gas += returnGas
   594  			if len(dc.Outputs) == 0 {
   595  				return nil
   596  			} else {
   597  				t := dc.Outputs[0].Type
   598  				switch t.T {
   599  				case abi.StringTy:
   600  					var unpackres string
   601  					if err := Abi.Unpack(&unpackres, funcName, ret); err != nil {
   602  						panic(failError)
   603  					} else {
   604  						return uint32(proc.SetBytes([]byte(unpackres)))
   605  					}
   606  				case abi.AddressTy:
   607  					var unpackres common.Address
   608  					if err := Abi.Unpack(&unpackres, funcName, ret); err != nil {
   609  						panic(failError)
   610  					} else {
   611  						return uint32(proc.SetBytes(unpackres.Bytes()))
   612  					}
   613  				case abi.UintTy:
   614  					if t.Size == 32 {
   615  						var unpackres uint32
   616  						if err := Abi.Unpack(&unpackres, funcName, ret); err != nil {
   617  							panic(failError)
   618  						} else {
   619  							return uint32(unpackres)
   620  						}
   621  					} else if t.Size == 64 {
   622  						var unpackres uint64
   623  						if err := Abi.Unpack(&unpackres, funcName, ret); err != nil {
   624  							panic(failError)
   625  						} else {
   626  							return uint64(unpackres)
   627  						}
   628  					} else if t.Size == 256 {
   629  						var unpackres *big.Int
   630  						if err := Abi.Unpack(&unpackres, funcName, ret); err != nil {
   631  							panic(failError)
   632  						} else {
   633  							return uint32(proc.SetBytes([]byte(unpackres.String())))
   634  						}
   635  					} else {
   636  						err := fmt.Errorf(errUnsupportType, t.String())
   637  						panic(err)
   638  					}
   639  				case abi.IntTy:
   640  					if t.Size == 32 {
   641  						var unpackres int32
   642  						if err := Abi.Unpack(&unpackres, funcName, ret); err != nil {
   643  							panic(failError)
   644  						} else {
   645  							return int32(unpackres)
   646  						}
   647  					} else if t.Size == 64 {
   648  						var unpackres int64
   649  						if err := Abi.Unpack(&unpackres, funcName, ret); err != nil {
   650  							panic(failError)
   651  						} else {
   652  							return int64(unpackres)
   653  						}
   654  					} else {
   655  						err := fmt.Errorf(errUnsupportType, t.String())
   656  						panic(err)
   657  					}
   658  				case abi.BoolTy:
   659  					var unpackres bool
   660  					if err := Abi.Unpack(&unpackres, funcName, ret); err != nil {
   661  						panic(failError)
   662  					} else {
   663  						if unpackres == true {
   664  							return int32(1)
   665  						} else {
   666  							return int32(0)
   667  						}
   668  					}
   669  				default:
   670  					err := fmt.Errorf(errUnsupportType, t.String())
   671  					panic(err)
   672  				}
   673  			}
   674  		}
   675  	}
   676  
   677  	funcVoid := func(proc *exec.WavmProcess, vars ...uint64) {
   678  		fnDef(proc, vars...)
   679  	}
   680  
   681  	funcUint64 := func(proc *exec.WavmProcess, vars ...uint64) uint64 {
   682  		return fnDef(proc, vars...).(uint64)
   683  	}
   684  
   685  	funcUint32 := func(proc *exec.WavmProcess, vars ...uint64) uint32 {
   686  		return fnDef(proc, vars...).(uint32)
   687  	}
   688  
   689  	funcInt64 := func(proc *exec.WavmProcess, vars ...uint64) int64 {
   690  		return fnDef(proc, vars...).(int64)
   691  	}
   692  
   693  	funcInt32 := func(proc *exec.WavmProcess, vars ...uint64) int32 {
   694  		return fnDef(proc, vars...).(int32)
   695  	}
   696  
   697  	if len(dc.Outputs) == 0 {
   698  		return funcVoid
   699  	}
   700  	t := dc.Outputs[0].Type
   701  	switch t.T {
   702  	case abi.UintTy:
   703  		if t.Size == 32 {
   704  			return funcUint32
   705  		} else if t.Size == 64 {
   706  			return funcUint64
   707  		} else if t.Size == 256 {
   708  			return funcUint32
   709  		} else {
   710  			return nil
   711  		}
   712  	case abi.IntTy:
   713  		if t.Size == 32 {
   714  			return funcInt32
   715  		} else if t.Size == 64 {
   716  			return funcInt64
   717  		} else {
   718  			return nil
   719  		}
   720  	case abi.StringTy, abi.AddressTy:
   721  		return funcUint32
   722  	case abi.BoolTy:
   723  		return funcInt32
   724  	default:
   725  		return nil
   726  	}
   727  
   728  	//return makeFunc(fnDef)
   729  }
   730  
   731  // End the line
   732  func (ef *EnvFunctions) printLine(msg string) error {
   733  	funcName := ef.ctx.Wavm.Wavm.GetFuncName()
   734  	log.Info("Contract Debug >>>>", "func", funcName, "message", msg)
   735  	if ef.ctx.Wavm.wavmConfig.Debug == true && ef.ctx.Wavm.wavmConfig.Tracer != nil {
   736  		ef.ctx.Wavm.wavmConfig.Tracer.CaptureLog(nil, msg)
   737  	}
   738  	return nil
   739  }
   740  
   741  func (ef *EnvFunctions) getPrintRemark(proc *exec.WavmProcess, remarkIdx uint64) string {
   742  	strValue := proc.ReadAt(remarkIdx)
   743  	return string(strValue)
   744  }
   745  
   746  // Print an Address
   747  func (ef *EnvFunctions) PrintAddress(proc *exec.WavmProcess, remarkIdx uint64, strIdx uint64) {
   748  	if !ef.ctx.Wavm.wavmConfig.Debug {
   749  		return
   750  	}
   751  	ef.ctx.GasCounter.GasCostZero()
   752  	addrValue := proc.ReadAt(strIdx)
   753  	msg := fmt.Sprint(ef.getPrintRemark(proc, remarkIdx), common.BytesToAddress(addrValue).String())
   754  	ef.printLine(msg)
   755  }
   756  
   757  // Print a string
   758  func (ef *EnvFunctions) PrintStr(proc *exec.WavmProcess, remarkIdx uint64, strIdx uint64) {
   759  	if !ef.ctx.Wavm.wavmConfig.Debug {
   760  		return
   761  	}
   762  	ef.ctx.GasCounter.GasCostZero()
   763  	strValue := proc.ReadAt(strIdx)
   764  	msg := fmt.Sprint(ef.getPrintRemark(proc, remarkIdx), string(strValue))
   765  	ef.printLine(msg)
   766  }
   767  
   768  // Print a string
   769  func (ef *EnvFunctions) PrintQStr(proc *exec.WavmProcess, remarkIdx uint64, strIdx uint64) {
   770  	if !ef.ctx.Wavm.wavmConfig.Debug {
   771  		return
   772  	}
   773  	ef.ctx.GasCounter.GasCostZero()
   774  	size := endianess.Uint32(proc.GetData()[strIdx : strIdx+4])
   775  	offset := endianess.Uint32(proc.GetData()[strIdx+4 : strIdx+8])
   776  	strValue := proc.GetData()[offset : offset+size]
   777  	length := len(proc.GetData())
   778  	if length > 128 {
   779  		length = 128
   780  	}
   781  	// msg := fmt.Sprint(ef.GetPrintRemark(proc, remarkIdx), string(strValue))
   782  	msg := fmt.Sprint(ef.getPrintRemark(proc, remarkIdx), hex.EncodeToString(strValue))
   783  	ef.printLine(msg)
   784  }
   785  
   786  // Print a uint64
   787  func (ef *EnvFunctions) PrintUint64T(proc *exec.WavmProcess, remarkIdx uint64, intValue uint64) {
   788  	if !ef.ctx.Wavm.wavmConfig.Debug {
   789  		return
   790  	}
   791  	ef.ctx.GasCounter.GasCostZero()
   792  	msg := fmt.Sprint(ef.getPrintRemark(proc, remarkIdx), intValue)
   793  	ef.printLine(msg)
   794  }
   795  
   796  // Print a uint32
   797  func (ef *EnvFunctions) PrintUint32T(proc *exec.WavmProcess, remarkIdx uint64, intValue uint64) {
   798  	if !ef.ctx.Wavm.wavmConfig.Debug {
   799  		return
   800  	}
   801  	ef.ctx.GasCounter.GasCostZero()
   802  	msg := fmt.Sprint(ef.getPrintRemark(proc, remarkIdx), uint32(intValue))
   803  	ef.printLine(msg)
   804  }
   805  
   806  //PrintInt64T  Print a int64
   807  func (ef *EnvFunctions) PrintInt64T(proc *exec.WavmProcess, remarkIdx uint64, intValue uint64) {
   808  	if !ef.ctx.Wavm.wavmConfig.Debug {
   809  		return
   810  	}
   811  	ef.ctx.GasCounter.GasCostZero()
   812  	msg := fmt.Sprint(ef.getPrintRemark(proc, remarkIdx), int64(intValue))
   813  	ef.printLine(msg)
   814  }
   815  
   816  //PrintInt32T Print a int32
   817  func (ef *EnvFunctions) PrintInt32T(proc *exec.WavmProcess, remarkIdx uint64, intValue uint64) {
   818  	if !ef.ctx.Wavm.wavmConfig.Debug {
   819  		return
   820  	}
   821  	ef.ctx.GasCounter.GasCostZero()
   822  	msg := fmt.Sprint(ef.getPrintRemark(proc, remarkIdx), int32(intValue))
   823  	ef.printLine(msg)
   824  }
   825  
   826  //PrintUint256T Print a uint256
   827  func (ef *EnvFunctions) PrintUint256T(proc *exec.WavmProcess, remarkIdx uint64, idx uint64) {
   828  	if !ef.ctx.Wavm.wavmConfig.Debug {
   829  		return
   830  	}
   831  	ef.ctx.GasCounter.GasCostZero()
   832  	u256 := readU256FromMemory(proc, idx)
   833  	msg := fmt.Sprint(ef.getPrintRemark(proc, remarkIdx), u256.String())
   834  	ef.printLine(msg)
   835  }
   836  
   837  func (ef *EnvFunctions) AddressFrom(proc *exec.WavmProcess, idx uint64) uint64 {
   838  	ctx := ef.ctx
   839  	ctx.GasCounter.GasQuickStep()
   840  	addrStr := string(proc.ReadAt(idx))
   841  	address := common.HexToAddress(addrStr).Bytes()
   842  	return ef.returnAddress(proc, address)
   843  }
   844  
   845  func (ef *EnvFunctions) AddressToString(proc *exec.WavmProcess, idx uint64) uint64 {
   846  	ctx := ef.ctx
   847  	ctx.GasCounter.GasQuickStep()
   848  	addrBytes := proc.ReadAt(idx)
   849  	address := common.BytesToAddress(addrBytes)
   850  	return uint64(proc.SetBytes([]byte(address.Hex())))
   851  }
   852  
   853  func (ef *EnvFunctions) U256From(proc *exec.WavmProcess, idx uint64) uint64 {
   854  	ctx := ef.ctx
   855  	ctx.GasCounter.GasQuickStep()
   856  	u256Str := string(proc.ReadAt(idx))
   857  	bigint, success := new(big.Int).SetString(u256Str, 10)
   858  	if success != true {
   859  		panic(fmt.Sprintf("Can't Convert strin %s to uint256", u256Str))
   860  	}
   861  	return ef.returnU256(proc, bigint)
   862  }
   863  
   864  func (ef *EnvFunctions) U256ToString(proc *exec.WavmProcess, idx uint64) uint64 {
   865  	ctx := ef.ctx
   866  	ctx.GasCounter.GasQuickStep()
   867  	u256Bytes := proc.ReadAt(idx)
   868  	return uint64(proc.SetBytes(u256Bytes))
   869  }
   870  
   871  // // Open for unit testing
   872  // func (ef *EnvFunctions) TestWritePerType(proc *exec.WavmProcess, typ abi.Type, validx uint64, loc common.Hash) {
   873  // 	ef.writePerType(proc, typ, validx, loc)
   874  // }
   875  
   876  // func (ef *EnvFunctions) TestReadPerType(proc *exec.WavmProcess, typ abi.Type, val []byte, loc common.Hash) uint64 {
   877  // 	return ef.readPerType(proc, typ, val, loc)
   878  // }
   879  
   880  func (ef *EnvFunctions) AddKeyInfo(proc *exec.WavmProcess, valAddr, valType, keyAddr, keyType, isArrayIndex uint64) {
   881  	isArr := false
   882  	if isArrayIndex > 0 {
   883  		isArr = true
   884  	}
   885  	key := storage.StorageKey{
   886  		KeyAddress:   keyAddr,
   887  		KeyType:      int32(keyType),
   888  		IsArrayIndex: isArr,
   889  	}
   890  
   891  	val := storage.StorageValue{
   892  		ValueAddress: valAddr,
   893  		ValueType:    int32(valType),
   894  	}
   895  	storageMap := ef.ctx.StorageMapping
   896  	keySym := fmt.Sprintf("%d%d%t", key.KeyAddress, key.KeyType, key.IsArrayIndex)
   897  	if _, ok := storageMap[valAddr]; ok {
   898  		temp := storageMap[valAddr]
   899  		if _, ok := temp.StorageKeyMap[keySym]; !ok {
   900  			temp.StorageKey = append(temp.StorageKey, key)
   901  			temp.StorageKeyMap[keySym] = true
   902  			storageMap[valAddr] = temp
   903  		}
   904  	} else {
   905  		temp := storage.StorageMapping{
   906  			StorageValue:  val,
   907  			StorageKey:    []storage.StorageKey{key},
   908  			StorageKeyMap: map[string]bool{keySym: true},
   909  		}
   910  		storageMap[valAddr] = temp
   911  	}
   912  }
   913  
   914  func callStateDb(ef *EnvFunctions, proc *exec.WavmProcess, valAddr uint64, stateDbOp func(val storage.StorageMapping, keyHash common.Hash)) {
   915  	keyHash := common.BytesToHash(nil)
   916  	storageMap := ef.ctx.StorageMapping
   917  	if val, ok := storageMap[valAddr]; ok {
   918  		for _, v := range val.StorageKey {
   919  			var lengthKeyHash common.Hash
   920  			if v.IsArrayIndex {
   921  				lengthKeyHash = keyHash
   922  			} else {
   923  			}
   924  			keyMem := getMemory(proc, v.KeyAddress, v.KeyType, v.IsArrayIndex, getArrayLength(ef, lengthKeyHash))
   925  			if (keyHash == common.Hash{}) {
   926  				keyHash = utils.MapLocation(keyMem, nil)
   927  			} else {
   928  				keyHash = utils.MapLocation(keyHash.Bytes(), keyMem)
   929  			}
   930  		}
   931  		stateDbOp(val, keyHash)
   932  	}
   933  }
   934  
   935  func getArrayLength(ef *EnvFunctions, lengthKeyHash common.Hash) uint64 {
   936  	length := ef.ctx.StateDB.GetState(ef.ctx.Contract.Address(), lengthKeyHash).Bytes()
   937  	return endianess.Uint64(length[len(length)-8:])
   938  }
   939  
   940  func inBounds(memoryData []byte, end uint64) {
   941  	if len(memoryData) < int(end) {
   942  		panic("error:out of memory bound")
   943  	}
   944  }
   945  
   946  func getMemory(proc *exec.WavmProcess, addr uint64, addrType int32, isArrayIndex bool, length uint64) []byte {
   947  	var mem []byte
   948  	memoryData := proc.GetData()
   949  	switch addrType {
   950  	case abi.TY_INT32:
   951  		inBounds(memoryData, addr+4)
   952  		mem = memoryData[addr : addr+4]
   953  	case abi.TY_INT64:
   954  		inBounds(memoryData, addr+8)
   955  		mem = memoryData[addr : addr+8]
   956  	case abi.TY_UINT32:
   957  		inBounds(memoryData, addr+4)
   958  		mem = memoryData[addr : addr+4]
   959  	case abi.TY_UINT64:
   960  		inBounds(memoryData, addr+8)
   961  		mem = memoryData[addr : addr+8]
   962  		if isArrayIndex {
   963  			index := endianess.Uint64(mem)
   964  			if index+1 > length {
   965  				panic(errExceededArray)
   966  			}
   967  		}
   968  	case abi.TY_UINT256:
   969  		inBounds(memoryData, addr+4)
   970  		ptr := endianess.Uint32(memoryData[addr : addr+4])
   971  		mem = []byte(readU256FromMemory(proc, uint64(ptr)).String())
   972  		// mem = readU256FromMemory(proc, uint64(ptr)).Bytes()
   973  	case abi.TY_STRING:
   974  		inBounds(memoryData, addr+4)
   975  		ptr := endianess.Uint32(memoryData[addr : addr+4])
   976  		mem = proc.ReadAt(uint64(ptr))
   977  	case abi.TY_ADDRESS:
   978  		inBounds(memoryData, addr+4)
   979  		ptr := endianess.Uint32(memoryData[addr : addr+4])
   980  		mem = proc.ReadAt(uint64(ptr))
   981  	case abi.TY_BOOL:
   982  		inBounds(memoryData, addr+4)
   983  		mem = memoryData[addr : addr+4]
   984  	case abi.TY_POINTER:
   985  		mem = make([]byte, 8)
   986  		binary.BigEndian.PutUint64(mem, addr)
   987  	}
   988  	return mem
   989  }
   990  func (ef *EnvFunctions) WriteWithPointer(proc *exec.WavmProcess, offsetAddr, baseAddr uint64) {
   991  	valAddr := offsetAddr + baseAddr
   992  	storageMap := ef.ctx.StorageMapping
   993  	if _, ok := storageMap[valAddr]; ok {
   994  		ef.forbiddenMutable(proc)
   995  	}
   996  	op := func(val storage.StorageMapping, keyHash common.Hash) {
   997  
   998  		valMem := getMemory(proc, val.StorageValue.ValueAddress, val.StorageValue.ValueType, false, 0)
   999  		statedb := ef.ctx.StateDB
  1000  		contractAddr := ef.ctx.Contract.Address()
  1001  		if val.StorageValue.ValueType == abi.TY_STRING {
  1002  			beforeN := statedb.GetState(contractAddr, keyHash).Big().Int64()
  1003  			n, s := utils.Split(valMem)
  1004  			ef.ctx.GasCounter.GasStore(statedb, contractAddr, keyHash, common.BigToHash(new(big.Int).SetInt64(int64(n))))
  1005  			statedb.SetState(contractAddr, keyHash, common.BigToHash(new(big.Int).SetInt64(int64(n))))
  1006  			for i := 1; i <= n; i++ {
  1007  				loc0 := new(big.Int).Add(keyHash.Big(), new(big.Int).SetInt64(int64(i)))
  1008  				ef.ctx.GasCounter.GasStore(statedb, contractAddr, common.BigToHash(loc0), common.BytesToHash(s[i-1]))
  1009  				statedb.SetState(contractAddr, common.BigToHash(loc0), common.BytesToHash(s[i-1]))
  1010  			}
  1011  			for i := n + 1; i <= int(beforeN); i++ {
  1012  				loc0 := new(big.Int).Add(keyHash.Big(), new(big.Int).SetInt64(int64(i)))
  1013  				empty := common.Hash{}
  1014  				ef.ctx.GasCounter.GasStore(statedb, contractAddr, common.BigToHash(loc0), empty)
  1015  				statedb.SetState(contractAddr, common.BigToHash(loc0), empty)
  1016  			}
  1017  		} else if val.StorageValue.ValueType == abi.TY_UINT256 {
  1018  			bigint := utils.GetU256(valMem)
  1019  			ef.ctx.GasCounter.GasStore(statedb, contractAddr, keyHash, common.BytesToHash(valMem))
  1020  			statedb.SetState(contractAddr, keyHash, common.BigToHash(bigint))
  1021  		} else {
  1022  			ef.ctx.GasCounter.GasStore(statedb, contractAddr, keyHash, common.BytesToHash(valMem))
  1023  			statedb.SetState(contractAddr, keyHash, common.BytesToHash(valMem))
  1024  		}
  1025  	}
  1026  	callStateDb(ef, proc, valAddr, op)
  1027  }
  1028  
  1029  func (ef *EnvFunctions) ReadWithPointer(proc *exec.WavmProcess, offsetAddr, baseAddr uint64) {
  1030  	valAddr := offsetAddr + baseAddr
  1031  	op := func(val storage.StorageMapping, keyHash common.Hash) {
  1032  		stateVal := []byte{}
  1033  		statedb := ef.ctx.StateDB
  1034  		contractAddr := ef.ctx.Contract.Address()
  1035  		if val.StorageValue.ValueType == abi.TY_STRING {
  1036  			n := statedb.GetState(contractAddr, keyHash).Big().Int64()
  1037  			ef.ctx.GasCounter.GasLoad()
  1038  			for i := 1; i <= int(n); i++ {
  1039  				loc0 := new(big.Int).Add(keyHash.Big(), new(big.Int).SetInt64(int64(i)))
  1040  				val0 := statedb.GetState(contractAddr, common.BigToHash(loc0)).Big().Bytes()
  1041  				stateVal = append(stateVal, val0...)
  1042  				ef.ctx.GasCounter.GasLoad()
  1043  			}
  1044  
  1045  		} else if val.StorageValue.ValueType == abi.TY_UINT256 {
  1046  			stateVal = []byte(statedb.GetState(contractAddr, keyHash).Big().String())
  1047  			ef.ctx.GasCounter.GasLoad()
  1048  		} else {
  1049  			stateVal = statedb.GetState(contractAddr, keyHash).Bytes()
  1050  			ef.ctx.GasCounter.GasLoad()
  1051  		}
  1052  		memoryData := proc.GetData()
  1053  		switch val.StorageValue.ValueType {
  1054  		case abi.TY_STRING:
  1055  			offset := proc.SetBytes(stateVal)
  1056  			endianess.PutUint32(memoryData[valAddr:], uint32(offset))
  1057  		case abi.TY_ADDRESS:
  1058  			offset := proc.SetBytes(stateVal[12:32])
  1059  			endianess.PutUint32(memoryData[valAddr:], uint32(offset))
  1060  		case abi.TY_UINT256:
  1061  			offset := proc.SetBytes(stateVal)
  1062  			endianess.PutUint32(memoryData[valAddr:], uint32(offset))
  1063  		case abi.TY_INT32, abi.TY_UINT32, abi.TY_BOOL:
  1064  			res := endianess.Uint32(stateVal[len(stateVal)-4:])
  1065  			endianess.PutUint32(memoryData[valAddr:], res)
  1066  		case abi.TY_INT64, abi.TY_UINT64:
  1067  			res := endianess.Uint64(stateVal[len(stateVal)-8:])
  1068  			endianess.PutUint64(memoryData[valAddr:], res)
  1069  		}
  1070  
  1071  	}
  1072  	callStateDb(ef, proc, valAddr, op)
  1073  }
  1074  
  1075  func (ef *EnvFunctions) InitializeVariables(proc *exec.WavmProcess) {
  1076  	// 普通类型初始化,忽略mapping和array
  1077  	//need to ignore array type because array init need array length
  1078  	storageMap := ef.ctx.StorageMapping
  1079  	for k, v := range storageMap {
  1080  		containArray := false
  1081  		for _, storageKey := range v.StorageKey {
  1082  			if storageKey.IsArrayIndex == true {
  1083  				containArray = true
  1084  				break
  1085  			}
  1086  		}
  1087  		if containArray == false {
  1088  			ef.WriteWithPointer(proc, k, 0)
  1089  		}
  1090  	}
  1091  }
  1092  
  1093  func readU256FromMemory(proc *exec.WavmProcess, offset uint64) *big.Int {
  1094  	mem := proc.ReadAt(offset)
  1095  	return utils.GetU256(mem)
  1096  }
  1097  
  1098  func (ef *EnvFunctions) U256FromU64(proc *exec.WavmProcess, x uint64) uint64 {
  1099  	bigint := new(big.Int)
  1100  	bigint.SetUint64(x)
  1101  	ef.ctx.GasCounter.GasFastestStep()
  1102  	return ef.returnU256(proc, bigint)
  1103  }
  1104  func (ef *EnvFunctions) U256FromI64(proc *exec.WavmProcess, x uint64) uint64 {
  1105  	bigint := new(big.Int)
  1106  	bigint.SetInt64(int64(x))
  1107  	ef.ctx.GasCounter.GasFastestStep()
  1108  	return ef.returnU256(proc, bigint)
  1109  }
  1110  
  1111  func (ef *EnvFunctions) U256Add(proc *exec.WavmProcess, x, y uint64) uint64 {
  1112  	bigx := readU256FromMemory(proc, x)
  1113  	bigy := readU256FromMemory(proc, y)
  1114  	res := math.U256(bigy.Add(bigx, bigy))
  1115  	ef.ctx.GasCounter.GasFastestStep()
  1116  	return ef.returnU256(proc, res)
  1117  }
  1118  
  1119  func (ef *EnvFunctions) U256Sub(proc *exec.WavmProcess, x, y uint64) uint64 {
  1120  	bigx := readU256FromMemory(proc, x)
  1121  	bigy := readU256FromMemory(proc, y)
  1122  	res := math.U256(bigy.Sub(bigx, bigy))
  1123  	ef.ctx.GasCounter.GasFastestStep()
  1124  	return ef.returnU256(proc, res)
  1125  }
  1126  
  1127  func (ef *EnvFunctions) U256Mul(proc *exec.WavmProcess, x, y uint64) uint64 {
  1128  	bigx := readU256FromMemory(proc, x)
  1129  	bigy := readU256FromMemory(proc, y)
  1130  	res := math.U256(bigy.Mul(bigx, bigy))
  1131  	ef.ctx.GasCounter.GasFastestStep()
  1132  	return ef.returnU256(proc, res)
  1133  }
  1134  
  1135  func (ef *EnvFunctions) U256Div(proc *exec.WavmProcess, x, y uint64) uint64 {
  1136  	bigx := readU256FromMemory(proc, x)
  1137  	bigy := readU256FromMemory(proc, y)
  1138  	res := new(big.Int)
  1139  	if bigy.Sign() != 0 {
  1140  		res = math.U256(bigy.Div(bigx, bigy))
  1141  	} else {
  1142  		res = bigy.SetUint64(0)
  1143  	}
  1144  	ef.ctx.GasCounter.GasFastestStep()
  1145  	return ef.returnU256(proc, res)
  1146  }
  1147  
  1148  func (ef *EnvFunctions) U256Mod(proc *exec.WavmProcess, x, y uint64) uint64 {
  1149  	bigx := readU256FromMemory(proc, x)
  1150  	bigy := readU256FromMemory(proc, y)
  1151  	res := new(big.Int)
  1152  	if bigy.Sign() != 0 {
  1153  		res = math.U256(bigy.Mod(bigx, bigy))
  1154  	} else {
  1155  		res = bigy.SetUint64(0)
  1156  	}
  1157  	ef.ctx.GasCounter.GasFastestStep()
  1158  	return ef.returnU256(proc, res)
  1159  }
  1160  
  1161  func (ef *EnvFunctions) U256Pow(proc *exec.WavmProcess, base, exponent uint64) uint64 {
  1162  	b := readU256FromMemory(proc, base)
  1163  	e := readU256FromMemory(proc, exponent)
  1164  	res := math.Exp(b, e)
  1165  	ef.ctx.GasCounter.GasPow(e)
  1166  	return ef.returnU256(proc, res)
  1167  }
  1168  
  1169  func (ef *EnvFunctions) U256Cmp(proc *exec.WavmProcess, x, y uint64) uint64 {
  1170  	bigx := readU256FromMemory(proc, x)
  1171  	bigy := readU256FromMemory(proc, y)
  1172  	res := bigx.Cmp(bigy)
  1173  	ef.ctx.GasCounter.GasFastestStep()
  1174  	return uint64(res)
  1175  }
  1176  
  1177  func (ef *EnvFunctions) U256Shl(proc *exec.WavmProcess, value, shift uint64) uint64 {
  1178  	bigShift := readU256FromMemory(proc, shift)
  1179  	bigValue := readU256FromMemory(proc, value)
  1180  	ef.ctx.GasCounter.GasFastestStep()
  1181  	if bigShift.Cmp(common.Big256) >= 0 {
  1182  		res := new(big.Int).SetUint64(0)
  1183  		return ef.returnU256(proc, res)
  1184  	}
  1185  	n := uint(bigShift.Uint64())
  1186  	res := math.U256(bigValue.Lsh(bigValue, n))
  1187  	return ef.returnU256(proc, res)
  1188  }
  1189  
  1190  func (ef *EnvFunctions) U256Shr(proc *exec.WavmProcess, value, shift uint64) uint64 {
  1191  	bigShift := readU256FromMemory(proc, shift)
  1192  	bigValue := readU256FromMemory(proc, value)
  1193  	ef.ctx.GasCounter.GasFastestStep()
  1194  	if bigShift.Cmp(common.Big256) >= 0 {
  1195  		res := new(big.Int).SetUint64(0)
  1196  		return ef.returnU256(proc, res)
  1197  	}
  1198  	n := uint(bigShift.Uint64())
  1199  	res := math.U256(bigValue.Rsh(bigValue, n))
  1200  	return ef.returnU256(proc, res)
  1201  }
  1202  
  1203  func (ef *EnvFunctions) U256And(proc *exec.WavmProcess, x, y uint64) uint64 {
  1204  	bigx := readU256FromMemory(proc, x)
  1205  	bigy := readU256FromMemory(proc, y)
  1206  	res := bigx.And(bigx, bigy)
  1207  	ef.ctx.GasCounter.GasFastestStep()
  1208  	return ef.returnU256(proc, res)
  1209  }
  1210  
  1211  func (ef *EnvFunctions) U256Or(proc *exec.WavmProcess, x, y uint64) uint64 {
  1212  	bigx := readU256FromMemory(proc, x)
  1213  	bigy := readU256FromMemory(proc, y)
  1214  	res := bigx.Or(bigx, bigy)
  1215  	ef.ctx.GasCounter.GasFastestStep()
  1216  	return ef.returnU256(proc, res)
  1217  }
  1218  
  1219  func (ef *EnvFunctions) U256Xor(proc *exec.WavmProcess, x, y uint64) uint64 {
  1220  	bigx := readU256FromMemory(proc, x)
  1221  	bigy := readU256FromMemory(proc, y)
  1222  	res := bigx.Xor(bigx, bigy)
  1223  	ef.ctx.GasCounter.GasFastestStep()
  1224  	return ef.returnU256(proc, res)
  1225  }
  1226  
  1227  func (ef *EnvFunctions) Pow(proc *exec.WavmProcess, base, exponent uint64) uint64 {
  1228  	b := new(big.Int)
  1229  	b.SetUint64(base)
  1230  	e := new(big.Int)
  1231  	e.SetUint64(exponent)
  1232  	res := math.Exp(b, e)
  1233  	ef.ctx.GasCounter.GasPow(e)
  1234  	return res.Uint64()
  1235  }
  1236  
  1237  func (ef *EnvFunctions) AddGas(proc *exec.WavmProcess, cost uint64) {
  1238  	ef.ctx.GasCounter.AdjustedCharge(cost)
  1239  }
  1240  
  1241  //todo 考虑revert的完整实现 contractcall里需要用到revert
  1242  func (ef *EnvFunctions) Revert(proc *exec.WavmProcess, msgIdx uint64) {
  1243  	ctx := ef.ctx
  1244  	ctx.GasCounter.GasRevert()
  1245  	msg := proc.ReadAt(msgIdx)
  1246  	ctx.GasCounter.GasMemoryCost(uint64(len(msg)))
  1247  	log.Info("Contract Revert >>>>", "message", string(msg))
  1248  	panic(errormsg.ErrExecutionReverted)
  1249  }
  1250  
  1251  func (ef *EnvFunctions) returnPointer(proc *exec.WavmProcess, input []byte) uint64 {
  1252  	ctx := ef.ctx
  1253  	ctx.GasCounter.GasReturnPointer(uint64(len(input)))
  1254  	return uint64(proc.SetBytes(input))
  1255  }
  1256  
  1257  func (ef *EnvFunctions) returnAddress(proc *exec.WavmProcess, input []byte) uint64 {
  1258  	ctx := ef.ctx
  1259  	ctx.GasCounter.GasReturnAddress()
  1260  	return uint64(proc.SetBytes(common.BytesToAddress(input).Bytes()))
  1261  }
  1262  
  1263  func (ef *EnvFunctions) returnU256(proc *exec.WavmProcess, bigint *big.Int) uint64 {
  1264  	ctx := ef.ctx
  1265  	ctx.GasCounter.GasReturnU256()
  1266  	return uint64(proc.SetBytes([]byte(bigint.String())))
  1267  }
  1268  
  1269  func (ef *EnvFunctions) returnHash(proc *exec.WavmProcess, hash []byte) uint64 {
  1270  	ctx := ef.ctx
  1271  	ctx.GasCounter.GasReturnHash()
  1272  	return uint64(proc.SetBytes(hash))
  1273  }
  1274  
  1275  //Sender for qlang
  1276  func (ef *EnvFunctions) Sender(proc *exec.WavmProcess, ptr uint64) {
  1277  	ctx := ef.ctx
  1278  	ctx.GasCounter.GasGetSender()
  1279  	sender := ctx.Contract.CallerAddress.Bytes()
  1280  	proc.WriteAt(sender, int64(ptr))
  1281  }
  1282  
  1283  //Load for qlang
  1284  func (ef *EnvFunctions) Load(proc *exec.WavmProcess, keyptr uint64, dataptr uint64) uint64 {
  1285  	keyData := ef.getQString(proc, keyptr)
  1286  	keyHash := common.BytesToHash(keyData)
  1287  	statedb := ef.ctx.StateDB
  1288  	contractAddr := ef.ctx.Contract.Address()
  1289  	n := statedb.GetState(contractAddr, keyHash).Big().Int64()
  1290  	stateVal := []byte{}
  1291  	for i := 1; i <= int(n); i++ {
  1292  		loc0 := new(big.Int).Add(keyHash.Big(), new(big.Int).SetInt64(int64(i)))
  1293  		val0 := statedb.GetState(contractAddr, common.BigToHash(loc0)).Big().Bytes()
  1294  		stateVal = append(stateVal, val0...)
  1295  		ef.ctx.GasCounter.GasLoad()
  1296  	}
  1297  	proc.WriteAt(stateVal, int64(dataptr))
  1298  	return uint64(len(stateVal))
  1299  }
  1300  
  1301  //Store for qlang
  1302  func (ef *EnvFunctions) Store(proc *exec.WavmProcess, keyptr uint64, dataptr uint64) {
  1303  	keyData := ef.getQString(proc, keyptr)
  1304  	keyHash := common.BytesToHash(keyData)
  1305  	valueData := ef.getQString(proc, dataptr)
  1306  	statedb := ef.ctx.StateDB
  1307  	contractAddr := ef.ctx.Contract.Address()
  1308  	beforeN := statedb.GetState(contractAddr, keyHash).Big().Int64()
  1309  	n, s := utils.Split(valueData)
  1310  	ef.ctx.GasCounter.GasStore(statedb, contractAddr, keyHash, common.BigToHash(new(big.Int).SetInt64(int64(n))))
  1311  	statedb.SetState(contractAddr, keyHash, common.BigToHash(new(big.Int).SetInt64(int64(n))))
  1312  	for i := 1; i <= n; i++ {
  1313  		loc0 := new(big.Int).Add(keyHash.Big(), new(big.Int).SetInt64(int64(i)))
  1314  		ef.ctx.GasCounter.GasStore(statedb, contractAddr, common.BigToHash(loc0), common.BytesToHash(s[i-1]))
  1315  		statedb.SetState(contractAddr, common.BigToHash(loc0), common.BytesToHash(s[i-1]))
  1316  	}
  1317  	for i := n + 1; i <= int(beforeN); i++ {
  1318  		loc0 := new(big.Int).Add(keyHash.Big(), new(big.Int).SetInt64(int64(i)))
  1319  		empty := common.Hash{}
  1320  		ef.ctx.GasCounter.GasStore(statedb, contractAddr, common.BigToHash(loc0), empty)
  1321  		statedb.SetState(contractAddr, common.BigToHash(loc0), empty)
  1322  	}
  1323  }
  1324  
  1325  func (ef *EnvFunctions) getQString(proc *exec.WavmProcess, strPtr uint64) []byte {
  1326  	size := endianess.Uint32(proc.GetData()[strPtr : strPtr+4])
  1327  	offset := endianess.Uint32(proc.GetData()[strPtr+4 : strPtr+8])
  1328  	strData := proc.GetData()[offset : offset+size]
  1329  	return strData
  1330  }
  1331  
  1332  func (ef *EnvFunctions) forbiddenMutable(proc *exec.WavmProcess) {
  1333  	if proc.Mutable() == false {
  1334  		err := errors.New("Mutable Forbidden: This function is not a mutable function")
  1335  		panic(err)
  1336  	}
  1337  }