func RunState(statedb *state.StateDB, env, tx map[string]string) ([]byte, state.Logs, *big.Int, error) { var ( keyPair, _ = crypto.NewKeyPairFromSec([]byte(common.Hex2Bytes(tx["secretKey"]))) 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() caddr = common.HexToAddress(env["currentCoinbase"]) ) 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.Copy() coinbase := statedb.GetOrNewStateObject(caddr) coinbase.SetGasLimit(common.Big(env["currentGasLimit"])) message := NewMessage(common.BytesToAddress(keyPair.Address()), to, data, value, gas, price, nonce) vmenv := NewEnvFromMap(statedb, env, tx) vmenv.origin = common.BytesToAddress(keyPair.Address()) ret, _, err := core.ApplyMessage(vmenv, message, coinbase) if core.IsNonceErr(err) || core.IsInvalidTxErr(err) || state.IsGasLimitErr(err) { statedb.Set(snapshot) } statedb.Update() return ret, vmenv.state.Logs(), vmenv.Gas, err }
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.Copy() 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.Set(snapshot) } statedb.Commit() return ret, vmenv.state.Logs(), vmenv.Gas, err }
func (self *XEth) SignTransaction(fromStr, toStr, nonceStr, valueStr, gasStr, gasPriceStr, codeStr string) (*types.Transaction, error) { if len(toStr) > 0 && toStr != "0x" && !isAddress(toStr) { return nil, errors.New("Invalid address") } var ( from = common.HexToAddress(fromStr) to = common.HexToAddress(toStr) value = common.Big(valueStr) gas *big.Int price *big.Int data []byte contractCreation bool ) if len(gasStr) == 0 { gas = DefaultGas() } else { gas = common.Big(gasStr) } if len(gasPriceStr) == 0 { price = self.DefaultGasPrice() } else { price = common.Big(gasPriceStr) } data = common.FromHex(codeStr) if len(toStr) == 0 { contractCreation = true } var nonce uint64 if len(nonceStr) != 0 { nonce = common.Big(nonceStr).Uint64() } else { // XXX: replaced tx pool state with managed state from app // state := self.backend.TxPool().State() state := self.ManagedState() nonce = state.GetNonce(from) } var tx *types.Transaction if contractCreation { tx = types.NewContractCreation(nonce, value, gas, price, data) } else { tx = types.NewTransaction(nonce, to, value, gas, price, data) } signed, err := self.sign(tx, from, false) if err != nil { return nil, err } return signed, nil }
func StateObjectFromAccount(db common.Database, addr string, account Account) *state.StateObject { obj := state.NewStateObject(common.HexToAddress(addr), db) obj.SetBalance(common.Big(account.Balance)) if common.IsHex(account.Code) { account.Code = account.Code[2:] } obj.SetCode(common.Hex2Bytes(account.Code)) obj.SetNonce(common.Big(account.Nonce).Uint64()) return obj }
func run(ctx *cli.Context) { vm.Debug = ctx.GlobalBool(DebugFlag.Name) vm.ForceJit = ctx.GlobalBool(ForceJitFlag.Name) vm.EnableJit = !ctx.GlobalBool(DisableJitFlag.Name) glog.SetToStderr(true) glog.SetV(ctx.GlobalInt(VerbosityFlag.Name)) db, _ := ethdb.NewMemDatabase() statedb, _ := state.New(common.Hash{}, db) sender := statedb.CreateAccount(common.StringToAddress("sender")) receiver := statedb.CreateAccount(common.StringToAddress("receiver")) receiver.SetCode(common.Hex2Bytes(ctx.GlobalString(CodeFlag.Name))) vmenv := NewEnv(statedb, common.StringToAddress("evmuser"), common.Big(ctx.GlobalString(ValueFlag.Name))) tstart := time.Now() ret, e := vmenv.Call( sender, receiver.Address(), common.Hex2Bytes(ctx.GlobalString(InputFlag.Name)), common.Big(ctx.GlobalString(GasFlag.Name)), common.Big(ctx.GlobalString(PriceFlag.Name)), common.Big(ctx.GlobalString(ValueFlag.Name)), ) vmdone := time.Since(tstart) if ctx.GlobalBool(DumpFlag.Name) { fmt.Println(string(statedb.Dump())) } vm.StdErrFormat(vmenv.StructLogs()) if ctx.GlobalBool(SysStatFlag.Name) { var mem runtime.MemStats runtime.ReadMemStats(&mem) fmt.Printf("vm took %v\n", vmdone) fmt.Printf(`alloc: %d tot alloc: %d no. malloc: %d heap alloc: %d heap objs: %d num gc: %d `, mem.Alloc, mem.TotalAlloc, mem.Mallocs, mem.HeapAlloc, mem.HeapObjects, mem.NumGC) } fmt.Printf("OUT: 0x%x", ret) if e != nil { fmt.Printf(" error: %v", e) } fmt.Println() }
func NewEnvFromMap(state *state.StateDB, envValues map[string]string, exeValues map[string]string) *Env { env := NewEnv(state) env.origin = common.HexToAddress(exeValues["caller"]) //env.parent = common.Hex2Bytes(envValues["previousHash"]) env.coinbase = common.HexToAddress(envValues["currentCoinbase"]) env.number = common.Big(envValues["currentNumber"]) env.time = common.Big(envValues["currentTimestamp"]).Int64() env.difficulty = common.Big(envValues["currentDifficulty"]) env.gasLimit = common.Big(envValues["currentGasLimit"]) env.Gas = new(big.Int) return env }
// Call forms a transaction from the given arguments and tries to execute it on // a private VM with a copy of the state. Any changes are therefore only temporary // and not part of the actual state. This allows for local execution/queries. func (be *registryAPIBackend) Call(fromStr, toStr, valueStr, gasStr, gasPriceStr, dataStr string) (string, string, error) { block := be.bc.CurrentBlock() statedb, err := state.New(block.Root(), be.chainDb) if err != nil { return "", "", err } var from *state.StateObject if len(fromStr) == 0 { accounts, err := be.am.Accounts() if err != nil || len(accounts) == 0 { from = statedb.GetOrNewStateObject(common.Address{}) } else { from = statedb.GetOrNewStateObject(accounts[0].Address) } } else { from = statedb.GetOrNewStateObject(common.HexToAddress(fromStr)) } from.SetBalance(common.MaxBig) msg := callmsg{ from: from, gas: common.Big(gasStr), gasPrice: common.Big(gasPriceStr), value: common.Big(valueStr), data: common.FromHex(dataStr), } if len(toStr) > 0 { addr := common.HexToAddress(toStr) msg.to = &addr } if msg.gas.Cmp(big.NewInt(0)) == 0 { msg.gas = big.NewInt(50000000) } if msg.gasPrice.Cmp(big.NewInt(0)) == 0 { msg.gasPrice = new(big.Int).Mul(big.NewInt(50), common.Shannon) } header := be.bc.CurrentBlock().Header() vmenv := core.NewEnv(statedb, be.bc, msg, header) gp := new(core.GasPool).AddGas(common.MaxBig) res, gas, err := core.ApplyMessage(vmenv, msg, gp) return common.ToHex(res), gas.String(), err }
// GenesisBlock creates a genesis block with the given nonce. func GenesisBlock(nonce uint64, db common.Database) *types.Block { var accounts map[string]struct { Balance string Code string } err := json.Unmarshal(GenesisAccounts, &accounts) if err != nil { fmt.Println("unable to decode genesis json data:", err) os.Exit(1) } statedb := state.New(common.Hash{}, db) for addr, account := range accounts { codedAddr := common.Hex2Bytes(addr) accountState := statedb.CreateAccount(common.BytesToAddress(codedAddr)) accountState.SetBalance(common.Big(account.Balance)) accountState.SetCode(common.FromHex(account.Code)) statedb.UpdateStateObject(accountState) } statedb.Sync() block := types.NewBlock(&types.Header{ Difficulty: params.GenesisDifficulty, GasLimit: params.GenesisGasLimit, Nonce: types.EncodeNonce(nonce), Root: statedb.Root(), }, nil, nil, nil) block.Td = params.GenesisDifficulty return block }
func NewEnvFromMap(ruleSet RuleSet, state *state.StateDB, envValues map[string]string, exeValues map[string]string) *Env { env := NewEnv(ruleSet, state) env.origin = common.HexToAddress(exeValues["caller"]) env.parent = common.HexToHash(envValues["previousHash"]) env.coinbase = common.HexToAddress(envValues["currentCoinbase"]) env.number = common.Big(envValues["currentNumber"]) env.time = common.Big(envValues["currentTimestamp"]) env.difficulty = common.Big(envValues["currentDifficulty"]) env.gasLimit = common.Big(envValues["currentGasLimit"]) env.Gas = new(big.Int) env.evm = vm.New(env, vm.Config{ EnableJit: EnableJit, ForceJit: ForceJit, }) return env }
func (self *XEth) Call(fromStr, toStr, valueStr, gasStr, gasPriceStr, dataStr string) (string, string, error) { statedb := self.State().State().Copy() var from *state.StateObject if len(fromStr) == 0 { accounts, err := self.backend.AccountManager().Accounts() if err != nil || len(accounts) == 0 { from = statedb.GetOrNewStateObject(common.Address{}) } else { from = statedb.GetOrNewStateObject(accounts[0].Address) } } else { from = statedb.GetOrNewStateObject(common.HexToAddress(fromStr)) } from.SetBalance(common.MaxBig) from.SetGasLimit(common.MaxBig) msg := callmsg{ from: from, gas: common.Big(gasStr), gasPrice: common.Big(gasPriceStr), value: common.Big(valueStr), data: common.FromHex(dataStr), } if len(toStr) > 0 { addr := common.HexToAddress(toStr) msg.to = &addr } if msg.gas.Cmp(big.NewInt(0)) == 0 { msg.gas = big.NewInt(50000000) } if msg.gasPrice.Cmp(big.NewInt(0)) == 0 { msg.gasPrice = self.DefaultGasPrice() } header := self.CurrentBlock().Header() vmenv := core.NewEnv(statedb, self.backend.ChainManager(), msg, header) res, gas, err := core.ApplyMessage(vmenv, msg, from) return common.ToHex(res), gas.String(), err }
func main() { flag.Parse() logger.AddLogSystem(logger.NewStdLogSystem(os.Stdout, log.LstdFlags, logger.LogLevel(*loglevel))) vm.Debug = true db, _ := ethdb.NewMemDatabase() statedb := state.New(common.Hash{}, db) sender := statedb.CreateAccount(common.StringToAddress("sender")) receiver := statedb.CreateAccount(common.StringToAddress("receiver")) receiver.SetCode(common.Hex2Bytes(*code)) vmenv := NewEnv(statedb, common.StringToAddress("evmuser"), common.Big(*value)) tstart := time.Now() ret, e := vmenv.Call(sender, receiver.Address(), common.Hex2Bytes(*data), common.Big(*gas), common.Big(*price), common.Big(*value)) logger.Flush() if e != nil { perr(e) } if *dump { fmt.Println(string(statedb.Dump())) } vm.StdErrFormat(vmenv.StructLogs()) var mem runtime.MemStats runtime.ReadMemStats(&mem) fmt.Printf("vm took %v\n", time.Since(tstart)) fmt.Printf(`alloc: %d tot alloc: %d no. malloc: %d heap alloc: %d heap objs: %d num gc: %d `, mem.Alloc, mem.TotalAlloc, mem.Mallocs, mem.HeapAlloc, mem.HeapObjects, mem.NumGC) fmt.Printf("%x\n", ret) }
func RunVm(state *state.StateDB, env, exec map[string]string) ([]byte, vm.Logs, *big.Int, error) { var ( to = common.HexToAddress(exec["address"]) from = common.HexToAddress(exec["caller"]) data = common.FromHex(exec["data"]) gas = common.Big(exec["gas"]) price = common.Big(exec["gasPrice"]) value = common.Big(exec["value"]) ) // Reset the pre-compiled contracts for VM tests. vm.Precompiled = make(map[string]*vm.PrecompiledAccount) caller := state.GetOrNewStateObject(from) vmenv := NewEnvFromMap(RuleSet{params.MainNetHomesteadBlock}, state, env, exec) vmenv.vmTest = true vmenv.skipTransfer = true vmenv.initial = true ret, err := vmenv.Call(caller, to, data, gas, price, value) return ret, vmenv.state.Logs(), vmenv.Gas, err }
func (self *XEth) Call(fromStr, toStr, valueStr, gasStr, gasPriceStr, dataStr string) (string, string, error) { statedb := self.State().State() //self.eth.ChainManager().TransState() var from *state.StateObject if len(fromStr) == 0 { accounts, err := self.backend.AccountManager().Accounts() if err != nil || len(accounts) == 0 { from = statedb.GetOrNewStateObject(common.Address{}) } else { from = statedb.GetOrNewStateObject(common.BytesToAddress(accounts[0].Address)) } } else { from = statedb.GetOrNewStateObject(common.HexToAddress(fromStr)) } from.SetGasPool(self.backend.ChainManager().GasLimit()) msg := callmsg{ from: from, to: common.HexToAddress(toStr), gas: common.Big(gasStr), gasPrice: common.Big(gasPriceStr), value: common.Big(valueStr), data: common.FromHex(dataStr), } if msg.gas.Cmp(big.NewInt(0)) == 0 { msg.gas = DefaultGas() } if msg.gasPrice.Cmp(big.NewInt(0)) == 0 { msg.gasPrice = DefaultGasPrice() } block := self.CurrentBlock() vmenv := core.NewEnv(statedb, self.backend.ChainManager(), msg, block) res, gas, err := core.ApplyMessage(vmenv, msg, from) return common.ToHex(res), gas.String(), err }
func mapToTxParams(object map[string]interface{}) map[string]string { // Default values if object["from"] == nil { object["from"] = "" } if object["to"] == nil { object["to"] = "" } if object["value"] == nil { object["value"] = "" } if object["gas"] == nil { object["gas"] = "" } if object["gasPrice"] == nil { object["gasPrice"] = "" } var dataStr string var data []string if list, ok := object["data"].(*qml.List); ok { list.Convert(&data) } else if str, ok := object["data"].(string); ok { data = []string{str} } for _, str := range data { if common.IsHex(str) { str = str[2:] if len(str) != 64 { str = common.LeftPadString(str, 64) } } else { str = common.Bytes2Hex(common.LeftPadBytes(common.Big(str).Bytes(), 32)) } dataStr += str } object["data"] = dataStr conv := make(map[string]string) for key, value := range object { if v, ok := value.(string); ok { conv[key] = v } } return conv }
func (bc *ChainManager) Reset() { bc.mu.Lock() defer bc.mu.Unlock() for block := bc.currentBlock; block != nil; block = bc.GetBlock(block.ParentHash()) { bc.removeBlock(block) } bc.cache, _ = lru.New(blockCacheLimit) // Prepare the genesis block bc.write(bc.genesisBlock) bc.insert(bc.genesisBlock) bc.currentBlock = bc.genesisBlock bc.makeCache() bc.setTotalDifficulty(common.Big("0")) }
func GenesisBlock(db common.Database) *types.Block { genesis := types.NewBlock(common.Hash{}, common.Address{}, common.Hash{}, params.GenesisDifficulty, 42, nil) genesis.Header().Number = common.Big0 genesis.Header().GasLimit = params.GenesisGasLimit genesis.Header().GasUsed = common.Big0 genesis.Header().Time = 0 genesis.Td = common.Big0 genesis.SetUncles([]*types.Header{}) genesis.SetTransactions(types.Transactions{}) genesis.SetReceipts(types.Receipts{}) var accounts map[string]struct { Balance string Code string } err := json.Unmarshal(GenesisData, &accounts) if err != nil { fmt.Println("enable to decode genesis json data:", err) os.Exit(1) } statedb := state.New(genesis.Root(), db) for addr, account := range accounts { codedAddr := common.Hex2Bytes(addr) accountState := statedb.CreateAccount(common.BytesToAddress(codedAddr)) accountState.SetBalance(common.Big(account.Balance)) accountState.SetCode(common.FromHex(account.Code)) statedb.UpdateStateObject(accountState) } statedb.Sync() genesis.Header().Root = statedb.Root() genesis.Td = params.GenesisDifficulty return genesis }
func (args *HashIndexArgs) UnmarshalJSON(b []byte) (err error) { var obj []interface{} if err := json.Unmarshal(b, &obj); err != nil { return shared.NewDecodeParamError(err.Error()) } if len(obj) < 2 { return shared.NewInsufficientParamsError(len(obj), 2) } arg0, ok := obj[0].(string) if !ok { return shared.NewInvalidTypeError("hash", "not a string") } args.Hash = arg0 arg1, ok := obj[1].(string) if !ok { return shared.NewInvalidTypeError("index", "not a string") } args.Index = common.Big(arg1).Int64() return nil }
func (self *XEth) NumberToHuman(balance string) string { b := common.Big(balance) return common.CurrencyToString(b) }
func RunVmTest(r io.Reader) (failed int) { tests := make(map[string]VmTest) data, _ := ioutil.ReadAll(r) err := json.Unmarshal(data, &tests) if err != nil { log.Fatalln(err) } vm.Debug = true glog.SetV(4) glog.SetToStderr(true) for name, test := range tests { db, _ := ethdb.NewMemDatabase() statedb := state.New(common.Hash{}, db) for addr, account := range test.Pre { obj := StateObjectFromAccount(db, addr, account) statedb.SetStateObject(obj) } env := make(map[string]string) env["currentCoinbase"] = test.Env.CurrentCoinbase env["currentDifficulty"] = test.Env.CurrentDifficulty env["currentGasLimit"] = test.Env.CurrentGasLimit env["currentNumber"] = test.Env.CurrentNumber env["previousHash"] = test.Env.PreviousHash if n, ok := test.Env.CurrentTimestamp.(float64); ok { env["currentTimestamp"] = strconv.Itoa(int(n)) } else { env["currentTimestamp"] = test.Env.CurrentTimestamp.(string) } ret, logs, _, _ := helper.RunState(statedb, env, test.Transaction) statedb.Sync() rexp := helper.FromHex(test.Out) if bytes.Compare(rexp, ret) != 0 { glog.V(logger.Info).Infof("%s's return failed. Expected %x, got %x\n", name, rexp, ret) failed = 1 } for addr, account := range test.Post { obj := statedb.GetStateObject(common.HexToAddress(addr)) if obj == nil { continue } if len(test.Exec) == 0 { if obj.Balance().Cmp(common.Big(account.Balance)) != 0 { glog.V(logger.Info).Infof("%s's : (%x) balance failed. Expected %v, got %v => %v\n", name, obj.Address().Bytes()[:4], account.Balance, obj.Balance(), new(big.Int).Sub(common.Big(account.Balance), obj.Balance())) failed = 1 } } for addr, value := range account.Storage { v := obj.GetState(common.HexToHash(addr)).Bytes() vexp := helper.FromHex(value) if bytes.Compare(v, vexp) != 0 { glog.V(logger.Info).Infof("%s's : (%x: %s) storage failed. Expected %x, got %x (%v %v)\n", name, obj.Address().Bytes()[0:4], addr, vexp, v, common.BigD(vexp), common.BigD(v)) failed = 1 } } } statedb.Sync() //if !bytes.Equal(common.Hex2Bytes(test.PostStateRoot), statedb.Root()) { if common.HexToHash(test.PostStateRoot) != statedb.Root() { glog.V(logger.Info).Infof("%s's : Post state root failed. Expected %s, got %x", name, test.PostStateRoot, statedb.Root()) failed = 1 } if len(test.Logs) > 0 { if len(test.Logs) != len(logs) { glog.V(logger.Info).Infof("log length failed. Expected %d, got %d", len(test.Logs), len(logs)) failed = 1 } else { for i, log := range test.Logs { if common.HexToAddress(log.AddressF) != logs[i].Address { glog.V(logger.Info).Infof("'%s' log address failed. Expected %v got %x", name, log.AddressF, logs[i].Address) failed = 1 } if !bytes.Equal(logs[i].Data, helper.FromHex(log.DataF)) { glog.V(logger.Info).Infof("'%s' log data failed. Expected %v got %x", name, log.DataF, logs[i].Data) failed = 1 } if len(log.TopicsF) != len(logs[i].Topics) { glog.V(logger.Info).Infof("'%s' log topics length failed. Expected %d got %d", name, len(log.TopicsF), logs[i].Topics) failed = 1 } else { for j, topic := range log.TopicsF { if common.HexToHash(topic) != logs[i].Topics[j] { glog.V(logger.Info).Infof("'%s' log topic[%d] failed. Expected %v got %x", name, j, topic, logs[i].Topics[j]) failed = 1 } } } genBloom := common.LeftPadBytes(types.LogsBloom(state.Logs{logs[i]}).Bytes(), 256) if !bytes.Equal(genBloom, common.Hex2Bytes(log.BloomF)) { glog.V(logger.Info).Infof("'%s' bloom failed.", name) failed = 1 } } } } if failed == 1 { glog.V(logger.Info).Infoln(string(statedb.Dump())) } logger.Flush() } return }
func runStateTest(ruleSet RuleSet, test VmTest) error { db, _ := ethdb.NewMemDatabase() statedb, _ := state.New(common.Hash{}, db) for addr, account := range test.Pre { obj := StateObjectFromAccount(db, addr, account) statedb.SetStateObject(obj) for a, v := range account.Storage { obj.SetState(common.HexToHash(a), common.HexToHash(v)) } } // XXX Yeah, yeah... env := make(map[string]string) env["currentCoinbase"] = test.Env.CurrentCoinbase env["currentDifficulty"] = test.Env.CurrentDifficulty env["currentGasLimit"] = test.Env.CurrentGasLimit env["currentNumber"] = test.Env.CurrentNumber env["previousHash"] = test.Env.PreviousHash if n, ok := test.Env.CurrentTimestamp.(float64); ok { env["currentTimestamp"] = strconv.Itoa(int(n)) } else { env["currentTimestamp"] = test.Env.CurrentTimestamp.(string) } var ( ret []byte // gas *big.Int // err error logs vm.Logs ) ret, logs, _, _ = RunState(ruleSet, statedb, env, test.Transaction) // Compare expected and actual return rexp := common.FromHex(test.Out) if bytes.Compare(rexp, ret) != 0 { return fmt.Errorf("return failed. Expected %x, got %x\n", rexp, ret) } // check post state for addr, account := range test.Post { obj := statedb.GetStateObject(common.HexToAddress(addr)) if obj == nil { return fmt.Errorf("did not find expected post-state account: %s", addr) } if obj.Balance().Cmp(common.Big(account.Balance)) != 0 { return fmt.Errorf("(%x) balance failed. Expected: %v have: %v\n", obj.Address().Bytes()[:4], common.String2Big(account.Balance), obj.Balance()) } if obj.Nonce() != common.String2Big(account.Nonce).Uint64() { return fmt.Errorf("(%x) nonce failed. Expected: %v have: %v\n", obj.Address().Bytes()[:4], account.Nonce, obj.Nonce()) } for addr, value := range account.Storage { v := obj.GetState(common.HexToHash(addr)) vexp := common.HexToHash(value) if v != vexp { return fmt.Errorf("storage failed:\n%x: %s:\nexpected: %x\nhave: %x\n(%v %v)\n", obj.Address().Bytes(), addr, vexp, v, vexp.Big(), v.Big()) } } } root, _ := statedb.Commit() if common.HexToHash(test.PostStateRoot) != root { return fmt.Errorf("Post state root error. Expected: %s have: %x", test.PostStateRoot, root) } // check logs if len(test.Logs) > 0 { if err := checkLogs(test.Logs, logs); err != nil { return err } } return nil }
func runVmTest(test VmTest) error { db, _ := ethdb.NewMemDatabase() statedb, _ := state.New(common.Hash{}, db) for addr, account := range test.Pre { obj := StateObjectFromAccount(db, addr, account) statedb.SetStateObject(obj) for a, v := range account.Storage { obj.SetState(common.HexToHash(a), common.HexToHash(v)) } } // XXX Yeah, yeah... env := make(map[string]string) env["currentCoinbase"] = test.Env.CurrentCoinbase env["currentDifficulty"] = test.Env.CurrentDifficulty env["currentGasLimit"] = test.Env.CurrentGasLimit env["currentNumber"] = test.Env.CurrentNumber env["previousHash"] = test.Env.PreviousHash if n, ok := test.Env.CurrentTimestamp.(float64); ok { env["currentTimestamp"] = strconv.Itoa(int(n)) } else { env["currentTimestamp"] = test.Env.CurrentTimestamp.(string) } var ( ret []byte gas *big.Int err error logs vm.Logs ) ret, logs, gas, err = RunVm(statedb, env, test.Exec) // Compare expected and actual return rexp := common.FromHex(test.Out) if bytes.Compare(rexp, ret) != 0 { return fmt.Errorf("return failed. Expected %x, got %x\n", rexp, ret) } // Check gas usage if len(test.Gas) == 0 && err == nil { return fmt.Errorf("gas unspecified, indicating an error. VM returned (incorrectly) successfull") } else { gexp := common.Big(test.Gas) if gexp.Cmp(gas) != 0 { return fmt.Errorf("gas failed. Expected %v, got %v\n", gexp, gas) } } // check post state for addr, account := range test.Post { obj := statedb.GetStateObject(common.HexToAddress(addr)) if obj == nil { continue } for addr, value := range account.Storage { v := obj.GetState(common.HexToHash(addr)) vexp := common.HexToHash(value) if v != vexp { return fmt.Errorf("(%x: %s) storage failed. Expected %x, got %x (%v %v)\n", obj.Address().Bytes()[0:4], addr, vexp, v, vexp.Big(), v.Big()) } } } // check logs if len(test.Logs) > 0 { lerr := checkLogs(test.Logs, logs) if lerr != nil { return lerr } } return nil }
// Transact forms a transaction from the given arguments and submits it to the // transactio pool for execution. func (be *registryAPIBackend) Transact(fromStr, toStr, nonceStr, valueStr, gasStr, gasPriceStr, codeStr string) (string, error) { if len(toStr) > 0 && toStr != "0x" && !common.IsHexAddress(toStr) { return "", errors.New("invalid address") } var ( from = common.HexToAddress(fromStr) to = common.HexToAddress(toStr) value = common.Big(valueStr) gas *big.Int price *big.Int data []byte contractCreation bool ) if len(gasStr) == 0 { gas = big.NewInt(90000) } else { gas = common.Big(gasStr) } if len(gasPriceStr) == 0 { price = big.NewInt(10000000000000) } else { price = common.Big(gasPriceStr) } data = common.FromHex(codeStr) if len(toStr) == 0 { contractCreation = true } nonce := be.txPool.State().GetNonce(from) if len(nonceStr) != 0 { nonce = common.Big(nonceStr).Uint64() } var tx *types.Transaction if contractCreation { tx = types.NewContractCreation(nonce, value, gas, price, data) } else { tx = types.NewTransaction(nonce, to, value, gas, price, data) } acc := accounts.Account{from} signature, err := be.am.Sign(acc, tx.SigHash().Bytes()) if err != nil { return "", err } signedTx, err := tx.WithSignature(signature) if err != nil { return "", err } be.txPool.SetLocal(signedTx) if err := be.txPool.Add(signedTx); err != nil { return "", nil } if contractCreation { addr := crypto.CreateAddress(from, nonce) glog.V(logger.Info).Infof("Tx(%s) created: %s\n", signedTx.Hash().Hex(), addr.Hex()) } else { glog.V(logger.Info).Infof("Tx(%s) to: %s\n", signedTx.Hash().Hex(), tx.To().Hex()) } return signedTx.Hash().Hex(), nil }
func RunVmTest(p string, t *testing.T) { tests := make(map[string]VmTest) helper.CreateFileTests(t, p, &tests) for name, test := range tests { /* vm.Debug = true glog.SetV(4) glog.SetToStderr(true) if name != "stackLimitPush32_1024" { continue } */ db, _ := ethdb.NewMemDatabase() statedb := state.New(common.Hash{}, db) for addr, account := range test.Pre { obj := StateObjectFromAccount(db, addr, account) statedb.SetStateObject(obj) for a, v := range account.Storage { obj.SetState(common.HexToHash(a), common.NewValue(helper.FromHex(v))) } } // XXX Yeah, yeah... env := make(map[string]string) env["currentCoinbase"] = test.Env.CurrentCoinbase env["currentDifficulty"] = test.Env.CurrentDifficulty env["currentGasLimit"] = test.Env.CurrentGasLimit env["currentNumber"] = test.Env.CurrentNumber env["previousHash"] = test.Env.PreviousHash if n, ok := test.Env.CurrentTimestamp.(float64); ok { env["currentTimestamp"] = strconv.Itoa(int(n)) } else { env["currentTimestamp"] = test.Env.CurrentTimestamp.(string) } var ( ret []byte gas *big.Int err error logs state.Logs ) isVmTest := len(test.Exec) > 0 if isVmTest { ret, logs, gas, err = helper.RunVm(statedb, env, test.Exec) } else { ret, logs, gas, err = helper.RunState(statedb, env, test.Transaction) } rexp := helper.FromHex(test.Out) if bytes.Compare(rexp, ret) != 0 { t.Errorf("%s's return failed. Expected %x, got %x\n", name, rexp, ret) } if isVmTest { if len(test.Gas) == 0 && err == nil { t.Errorf("%s's gas unspecified, indicating an error. VM returned (incorrectly) successfull", name) } else { gexp := common.Big(test.Gas) if gexp.Cmp(gas) != 0 { t.Errorf("%s's gas failed. Expected %v, got %v\n", name, gexp, gas) } } } for addr, account := range test.Post { obj := statedb.GetStateObject(common.HexToAddress(addr)) if obj == nil { continue } if len(test.Exec) == 0 { if obj.Balance().Cmp(common.Big(account.Balance)) != 0 { t.Errorf("%s's : (%x) balance failed. Expected %v, got %v => %v\n", name, obj.Address().Bytes()[:4], account.Balance, obj.Balance(), new(big.Int).Sub(common.Big(account.Balance), obj.Balance())) } if obj.Nonce() != common.String2Big(account.Nonce).Uint64() { t.Errorf("%s's : (%x) nonce failed. Expected %v, got %v\n", name, obj.Address().Bytes()[:4], account.Nonce, obj.Nonce()) } } for addr, value := range account.Storage { v := obj.GetState(common.HexToHash(addr)).Bytes() vexp := helper.FromHex(value) if bytes.Compare(v, vexp) != 0 { t.Errorf("%s's : (%x: %s) storage failed. Expected %x, got %x (%v %v)\n", name, obj.Address().Bytes()[0:4], addr, vexp, v, common.BigD(vexp), common.BigD(v)) } } } if !isVmTest { statedb.Sync() //if !bytes.Equal(common.Hex2Bytes(test.PostStateRoot), statedb.Root()) { if common.HexToHash(test.PostStateRoot) != statedb.Root() { t.Errorf("%s's : Post state root error. Expected %s, got %x", name, test.PostStateRoot, statedb.Root()) } } if len(test.Logs) > 0 { if len(test.Logs) != len(logs) { t.Errorf("log length mismatch. Expected %d, got %d", len(test.Logs), len(logs)) } else { for i, log := range test.Logs { if common.HexToAddress(log.AddressF) != logs[i].Address { t.Errorf("'%s' log address expected %v got %x", name, log.AddressF, logs[i].Address) } if !bytes.Equal(logs[i].Data, helper.FromHex(log.DataF)) { t.Errorf("'%s' log data expected %v got %x", name, log.DataF, logs[i].Data) } if len(log.TopicsF) != len(logs[i].Topics) { t.Errorf("'%s' log topics length expected %d got %d", name, len(log.TopicsF), logs[i].Topics) } else { for j, topic := range log.TopicsF { if common.HexToHash(topic) != logs[i].Topics[j] { t.Errorf("'%s' log topic[%d] expected %v got %x", name, j, topic, logs[i].Topics[j]) } } } genBloom := common.LeftPadBytes(types.LogsBloom(state.Logs{logs[i]}).Bytes(), 256) if !bytes.Equal(genBloom, common.Hex2Bytes(log.BloomF)) { t.Errorf("'%s' bloom mismatch", name) } } } } //fmt.Println(string(statedb.Dump())) } logger.Flush() }
func (self *XEth) Transact(fromStr, toStr, nonceStr, valueStr, gasStr, gasPriceStr, codeStr string) (string, error) { // this minimalistic recoding is enough (works for natspec.js) var jsontx = fmt.Sprintf(`{"params":[{"to":"%s","data": "%s"}]}`, toStr, codeStr) if !self.ConfirmTransaction(jsontx) { err := fmt.Errorf("Transaction not confirmed") return "", err } var ( from = common.HexToAddress(fromStr) to = common.HexToAddress(toStr) value = common.Big(valueStr) gas *big.Int price *big.Int data []byte contractCreation bool ) if len(gasStr) == 0 { gas = DefaultGas() } else { gas = common.Big(gasStr) } if len(gasPriceStr) == 0 { price = self.DefaultGasPrice() } else { price = common.Big(gasPriceStr) } data = common.FromHex(codeStr) if len(toStr) == 0 { contractCreation = true } // 2015-05-18 Is this still needed? // TODO if no_private_key then //if _, exists := p.register[args.From]; exists { // p.register[args.From] = append(p.register[args.From], args) //} else { /* account := accounts.Get(common.FromHex(args.From)) if account != nil { if account.Unlocked() { if !unlockAccount(account) { return } } result, _ := account.Transact(common.FromHex(args.To), common.FromHex(args.Value), common.FromHex(args.Gas), common.FromHex(args.GasPrice), common.FromHex(args.Data)) if len(result) > 0 { *reply = common.ToHex(result) } } else if _, exists := p.register[args.From]; exists { p.register[ags.From] = append(p.register[args.From], args) } */ // TODO: align default values to have the same type, e.g. not depend on // common.Value conversions later on var nonce uint64 if len(nonceStr) != 0 { nonce = common.Big(nonceStr).Uint64() } else { state := self.backend.TxPool().State() nonce = state.GetNonce(from) } var tx *types.Transaction if contractCreation { tx = types.NewContractCreation(nonce, value, gas, price, data) } else { tx = types.NewTransaction(nonce, to, value, gas, price, data) } signed, err := self.sign(tx, from, false) if err != nil { return "", err } if err = self.backend.TxPool().Add(signed); err != nil { return "", err } if contractCreation { addr := crypto.CreateAddress(from, nonce) glog.V(logger.Info).Infof("Tx(%x) created: %x\n", tx.Hash(), addr) } else { glog.V(logger.Info).Infof("Tx(%x) to: %x\n", tx.Hash(), tx.To()) } return signed.Hash().Hex(), nil }
func newHexData(input interface{}) *hexdata { d := new(hexdata) if input == nil { d.isNil = true return d } switch input := input.(type) { case []byte: d.data = input case common.Hash: d.data = input.Bytes() case *common.Hash: if input == nil { d.isNil = true } else { d.data = input.Bytes() } case common.Address: d.data = input.Bytes() case *common.Address: if input == nil { d.isNil = true } else { d.data = input.Bytes() } case types.Bloom: d.data = input.Bytes() case *types.Bloom: if input == nil { d.isNil = true } else { d.data = input.Bytes() } case *big.Int: if input == nil { d.isNil = true } else { d.data = input.Bytes() } case int64: d.data = big.NewInt(input).Bytes() case uint64: buff := make([]byte, 8) binary.BigEndian.PutUint64(buff, input) d.data = buff case int: d.data = big.NewInt(int64(input)).Bytes() case uint: d.data = big.NewInt(int64(input)).Bytes() case int8: d.data = big.NewInt(int64(input)).Bytes() case uint8: d.data = big.NewInt(int64(input)).Bytes() case int16: d.data = big.NewInt(int64(input)).Bytes() case uint16: buff := make([]byte, 2) binary.BigEndian.PutUint16(buff, input) d.data = buff case int32: d.data = big.NewInt(int64(input)).Bytes() case uint32: buff := make([]byte, 4) binary.BigEndian.PutUint32(buff, input) d.data = buff case string: // hexstring d.data = common.Big(input).Bytes() default: d.isNil = true } return d }
func (self *XEth) Transact(fromStr, toStr, nonceStr, valueStr, gasStr, gasPriceStr, codeStr string) (string, error) { var ( from = common.HexToAddress(fromStr) to = common.HexToAddress(toStr) value = common.NewValue(valueStr) gas = common.Big(gasStr) price = common.Big(gasPriceStr) data []byte contractCreation bool ) // TODO if no_private_key then //if _, exists := p.register[args.From]; exists { // p.register[args.From] = append(p.register[args.From], args) //} else { /* account := accounts.Get(common.FromHex(args.From)) if account != nil { if account.Unlocked() { if !unlockAccount(account) { return } } result, _ := account.Transact(common.FromHex(args.To), common.FromHex(args.Value), common.FromHex(args.Gas), common.FromHex(args.GasPrice), common.FromHex(args.Data)) if len(result) > 0 { *reply = common.ToHex(result) } } else if _, exists := p.register[args.From]; exists { p.register[ags.From] = append(p.register[args.From], args) } */ // TODO: align default values to have the same type, e.g. not depend on // common.Value conversions later on if gas.Cmp(big.NewInt(0)) == 0 { gas = DefaultGas() } if price.Cmp(big.NewInt(0)) == 0 { price = DefaultGasPrice() } data = common.FromHex(codeStr) if len(toStr) == 0 { contractCreation = true } var tx *types.Transaction if contractCreation { tx = types.NewContractCreationTx(value.BigInt(), gas, price, data) } else { tx = types.NewTransactionMessage(to, value.BigInt(), gas, price, data) } state := self.backend.ChainManager().TxState() var nonce uint64 if len(nonceStr) != 0 { nonce = common.Big(nonceStr).Uint64() } else { nonce = state.NewNonce(from) } tx.SetNonce(nonce) if err := self.sign(tx, from, false); err != nil { return "", err } if err := self.backend.TxPool().Add(tx); err != nil { return "", err } if contractCreation { addr := core.AddressFromMessage(tx) glog.V(logger.Info).Infof("Tx(%x) created: %x\n", tx.Hash(), addr) return core.AddressFromMessage(tx).Hex(), nil } else { glog.V(logger.Info).Infof("Tx(%x) to: %x\n", tx.Hash(), tx.To()) } return tx.Hash().Hex(), nil }