func RunState(ruleSet RuleSet, statedb *state.StateDB, env, tx map[string]string) ([]byte, vm.Logs, *big.Int, error) { var ( data = common.FromHex(tx["data"]) gas = common.Big(tx["gasLimit"]) price = common.Big(tx["gasPrice"]) value = common.Big(tx["value"]) nonce = common.Big(tx["nonce"]).Uint64() ) var to *common.Address if len(tx["to"]) > 2 { t := common.HexToAddress(tx["to"]) to = &t } // Set pre compiled contracts vm.Precompiled = vm.PrecompiledContracts() snapshot := statedb.Snapshot() gaspool := new(core.GasPool).AddGas(common.Big(env["currentGasLimit"])) key, _ := hex.DecodeString(tx["secretKey"]) addr := crypto.PubkeyToAddress(crypto.ToECDSA(key).PublicKey) message := NewMessage(addr, to, data, value, gas, price, nonce) vmenv := NewEnvFromMap(ruleSet, statedb, env, tx) vmenv.origin = addr ret, _, err := core.ApplyMessage(vmenv, message, gaspool) if core.IsNonceErr(err) || core.IsInvalidTxErr(err) || core.IsGasLimitErr(err) { statedb.RevertToSnapshot(snapshot) } statedb.Commit() return ret, vmenv.state.Logs(), vmenv.Gas, err }
// ContractCall implements ContractCaller.ContractCall, executing the specified // contract with the given input data. func (b *SimulatedBackend) ContractCall(contract common.Address, data []byte, pending bool) ([]byte, error) { // Create a copy of the current state db to screw around with var ( block *types.Block statedb *state.StateDB ) if pending { block, statedb = b.pendingBlock, b.pendingState defer statedb.RevertToSnapshot(statedb.Snapshot()) } else { block = b.blockchain.CurrentBlock() statedb, _ = b.blockchain.State() } // If there's no code to interact with, respond with an appropriate error if code := statedb.GetCode(contract); len(code) == 0 { return nil, bind.ErrNoCode } // Set infinite balance to the a fake caller account from := statedb.GetOrNewStateObject(common.Address{}) from.SetBalance(common.MaxBig) // Assemble the call invocation to measure the gas usage msg := callmsg{ from: from, to: &contract, gasPrice: new(big.Int), gasLimit: common.MaxBig, value: new(big.Int), data: data, } // Execute the call and return vmenv := core.NewEnv(statedb, chainConfig, b.blockchain, msg, block.Header(), vm.Config{}) gaspool := new(core.GasPool).AddGas(common.MaxBig) out, _, err := core.ApplyMessage(vmenv, msg, gaspool) return out, err }