github.com/jeffallen/go-ethereum@v1.1.4-0.20150910155051-571d3236c49c/xeth/xeth.go (about) 1 // Copyright 2014 The go-ethereum Authors 2 // This file is part of the go-ethereum library. 3 // 4 // The go-ethereum 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-ethereum 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-ethereum library. If not, see <http://www.gnu.org/licenses/>. 16 17 // Package xeth is the interface to all Ethereum functionality. 18 package xeth 19 20 import ( 21 "bytes" 22 "encoding/json" 23 "errors" 24 "fmt" 25 "math/big" 26 "regexp" 27 "sync" 28 "time" 29 30 "github.com/ethereum/go-ethereum/accounts" 31 "github.com/ethereum/go-ethereum/common" 32 "github.com/ethereum/go-ethereum/common/compiler" 33 "github.com/ethereum/go-ethereum/core" 34 "github.com/ethereum/go-ethereum/core/state" 35 "github.com/ethereum/go-ethereum/core/types" 36 "github.com/ethereum/go-ethereum/crypto" 37 "github.com/ethereum/go-ethereum/eth" 38 "github.com/ethereum/go-ethereum/event/filter" 39 "github.com/ethereum/go-ethereum/logger" 40 "github.com/ethereum/go-ethereum/logger/glog" 41 "github.com/ethereum/go-ethereum/miner" 42 "github.com/ethereum/go-ethereum/rlp" 43 ) 44 45 var ( 46 filterTickerTime = 5 * time.Minute 47 defaultGasPrice = big.NewInt(10000000000000) //150000000000 48 defaultGas = big.NewInt(90000) //500000 49 dappStorePre = []byte("dapp-") 50 addrReg = regexp.MustCompile(`^(0x)?[a-fA-F0-9]{40}$`) 51 ) 52 53 // byte will be inferred 54 const ( 55 UnknownFilterTy = iota 56 BlockFilterTy 57 TransactionFilterTy 58 LogFilterTy 59 ) 60 61 func DefaultGas() *big.Int { return new(big.Int).Set(defaultGas) } 62 63 func (self *XEth) DefaultGasPrice() *big.Int { 64 if self.gpo == nil { 65 self.gpo = eth.NewGasPriceOracle(self.backend) 66 } 67 return self.gpo.SuggestPrice() 68 } 69 70 type XEth struct { 71 backend *eth.Ethereum 72 frontend Frontend 73 74 state *State 75 whisper *Whisper 76 77 quit chan struct{} 78 filterManager *filter.FilterManager 79 80 logMu sync.RWMutex 81 logQueue map[int]*logQueue 82 83 blockMu sync.RWMutex 84 blockQueue map[int]*hashQueue 85 86 transactionMu sync.RWMutex 87 transactionQueue map[int]*hashQueue 88 89 messagesMu sync.RWMutex 90 messages map[int]*whisperFilter 91 92 transactMu sync.Mutex 93 94 agent *miner.RemoteAgent 95 96 gpo *eth.GasPriceOracle 97 } 98 99 func NewTest(eth *eth.Ethereum, frontend Frontend) *XEth { 100 return &XEth{ 101 backend: eth, 102 frontend: frontend, 103 } 104 } 105 106 // New creates an XEth that uses the given frontend. 107 // If a nil Frontend is provided, a default frontend which 108 // confirms all transactions will be used. 109 func New(ethereum *eth.Ethereum, frontend Frontend) *XEth { 110 xeth := &XEth{ 111 backend: ethereum, 112 frontend: frontend, 113 quit: make(chan struct{}), 114 filterManager: filter.NewFilterManager(ethereum.EventMux()), 115 logQueue: make(map[int]*logQueue), 116 blockQueue: make(map[int]*hashQueue), 117 transactionQueue: make(map[int]*hashQueue), 118 messages: make(map[int]*whisperFilter), 119 agent: miner.NewRemoteAgent(), 120 } 121 if ethereum.Whisper() != nil { 122 xeth.whisper = NewWhisper(ethereum.Whisper()) 123 } 124 ethereum.Miner().Register(xeth.agent) 125 if frontend == nil { 126 xeth.frontend = dummyFrontend{} 127 } 128 xeth.state = NewState(xeth, xeth.backend.ChainManager().State()) 129 130 go xeth.start() 131 go xeth.filterManager.Start() 132 133 return xeth 134 } 135 136 func (self *XEth) start() { 137 timer := time.NewTicker(2 * time.Second) 138 done: 139 for { 140 select { 141 case <-timer.C: 142 self.logMu.Lock() 143 for id, filter := range self.logQueue { 144 if time.Since(filter.timeout) > filterTickerTime { 145 self.filterManager.UninstallFilter(id) 146 delete(self.logQueue, id) 147 } 148 } 149 self.logMu.Unlock() 150 151 self.blockMu.Lock() 152 for id, filter := range self.blockQueue { 153 if time.Since(filter.timeout) > filterTickerTime { 154 self.filterManager.UninstallFilter(id) 155 delete(self.blockQueue, id) 156 } 157 } 158 self.blockMu.Unlock() 159 160 self.transactionMu.Lock() 161 for id, filter := range self.transactionQueue { 162 if time.Since(filter.timeout) > filterTickerTime { 163 self.filterManager.UninstallFilter(id) 164 delete(self.transactionQueue, id) 165 } 166 } 167 self.transactionMu.Unlock() 168 169 self.messagesMu.Lock() 170 for id, filter := range self.messages { 171 if time.Since(filter.activity()) > filterTickerTime { 172 self.Whisper().Unwatch(id) 173 delete(self.messages, id) 174 } 175 } 176 self.messagesMu.Unlock() 177 case <-self.quit: 178 break done 179 } 180 } 181 } 182 183 func (self *XEth) stop() { 184 close(self.quit) 185 } 186 187 func cAddress(a []string) []common.Address { 188 bslice := make([]common.Address, len(a)) 189 for i, addr := range a { 190 bslice[i] = common.HexToAddress(addr) 191 } 192 return bslice 193 } 194 195 func cTopics(t [][]string) [][]common.Hash { 196 topics := make([][]common.Hash, len(t)) 197 for i, iv := range t { 198 topics[i] = make([]common.Hash, len(iv)) 199 for j, jv := range iv { 200 topics[i][j] = common.HexToHash(jv) 201 } 202 } 203 return topics 204 } 205 206 func (self *XEth) RemoteMining() *miner.RemoteAgent { return self.agent } 207 208 func (self *XEth) AtStateNum(num int64) *XEth { 209 var st *state.StateDB 210 switch num { 211 case -2: 212 st = self.backend.Miner().PendingState().Copy() 213 default: 214 if block := self.getBlockByHeight(num); block != nil { 215 st = state.New(block.Root(), self.backend.ChainDb()) 216 } else { 217 st = state.New(self.backend.ChainManager().GetBlockByNumber(0).Root(), self.backend.ChainDb()) 218 } 219 } 220 221 return self.WithState(st) 222 } 223 224 func (self *XEth) WithState(statedb *state.StateDB) *XEth { 225 xeth := &XEth{ 226 backend: self.backend, 227 frontend: self.frontend, 228 gpo: self.gpo, 229 } 230 231 xeth.state = NewState(xeth, statedb) 232 return xeth 233 } 234 235 func (self *XEth) State() *State { return self.state } 236 237 // subscribes to new head block events and 238 // waits until blockchain height is greater n at any time 239 // given the current head, waits for the next chain event 240 // sets the state to the current head 241 // loop is async and quit by closing the channel 242 // used in tests and JS console debug module to control advancing private chain manually 243 // Note: this is not threadsafe, only called in JS single process and tests 244 func (self *XEth) UpdateState() (wait chan *big.Int) { 245 wait = make(chan *big.Int) 246 go func() { 247 sub := self.backend.EventMux().Subscribe(core.ChainHeadEvent{}) 248 var m, n *big.Int 249 var ok bool 250 out: 251 for { 252 select { 253 case event := <-sub.Chan(): 254 ev, ok := event.(core.ChainHeadEvent) 255 if ok { 256 m = ev.Block.Number() 257 if n != nil && n.Cmp(m) < 0 { 258 wait <- n 259 n = nil 260 } 261 statedb := state.New(ev.Block.Root(), self.backend.ChainDb()) 262 self.state = NewState(self, statedb) 263 } 264 case n, ok = <-wait: 265 if !ok { 266 break out 267 } 268 } 269 } 270 sub.Unsubscribe() 271 }() 272 return 273 } 274 275 func (self *XEth) Whisper() *Whisper { return self.whisper } 276 277 func (self *XEth) getBlockByHeight(height int64) *types.Block { 278 var num uint64 279 280 switch height { 281 case -2: 282 return self.backend.Miner().PendingBlock() 283 case -1: 284 return self.CurrentBlock() 285 default: 286 if height < 0 { 287 return nil 288 } 289 290 num = uint64(height) 291 } 292 293 return self.backend.ChainManager().GetBlockByNumber(num) 294 } 295 296 func (self *XEth) BlockByHash(strHash string) *Block { 297 hash := common.HexToHash(strHash) 298 block := self.backend.ChainManager().GetBlock(hash) 299 300 return NewBlock(block) 301 } 302 303 func (self *XEth) EthBlockByHash(strHash string) *types.Block { 304 hash := common.HexToHash(strHash) 305 block := self.backend.ChainManager().GetBlock(hash) 306 307 return block 308 } 309 310 func (self *XEth) EthTransactionByHash(hash string) (tx *types.Transaction, blhash common.Hash, blnum *big.Int, txi uint64) { 311 // Due to increasing return params and need to determine if this is from transaction pool or 312 // some chain, this probably needs to be refactored for more expressiveness 313 data, _ := self.backend.ChainDb().Get(common.FromHex(hash)) 314 if len(data) != 0 { 315 dtx := new(types.Transaction) 316 if err := rlp.DecodeBytes(data, dtx); err != nil { 317 glog.V(logger.Error).Infoln(err) 318 return 319 } 320 tx = dtx 321 } else { // check pending transactions 322 tx = self.backend.TxPool().GetTransaction(common.HexToHash(hash)) 323 } 324 325 // meta 326 var txExtra struct { 327 BlockHash common.Hash 328 BlockIndex uint64 329 Index uint64 330 } 331 332 v, dberr := self.backend.ChainDb().Get(append(common.FromHex(hash), 0x0001)) 333 // TODO check specifically for ErrNotFound 334 if dberr != nil { 335 return 336 } 337 r := bytes.NewReader(v) 338 err := rlp.Decode(r, &txExtra) 339 if err == nil { 340 blhash = txExtra.BlockHash 341 blnum = big.NewInt(int64(txExtra.BlockIndex)) 342 txi = txExtra.Index 343 } else { 344 glog.V(logger.Error).Infoln(err) 345 } 346 347 return 348 } 349 350 func (self *XEth) BlockByNumber(num int64) *Block { 351 return NewBlock(self.getBlockByHeight(num)) 352 } 353 354 func (self *XEth) EthBlockByNumber(num int64) *types.Block { 355 return self.getBlockByHeight(num) 356 } 357 358 func (self *XEth) CurrentBlock() *types.Block { 359 return self.backend.ChainManager().CurrentBlock() 360 } 361 362 func (self *XEth) GetBlockReceipts(bhash common.Hash) types.Receipts { 363 return self.backend.BlockProcessor().GetBlockReceipts(bhash) 364 } 365 366 func (self *XEth) GetTxReceipt(txhash common.Hash) *types.Receipt { 367 return core.GetReceipt(self.backend.ChainDb(), txhash) 368 } 369 370 func (self *XEth) GasLimit() *big.Int { 371 return self.backend.ChainManager().GasLimit() 372 } 373 374 func (self *XEth) Block(v interface{}) *Block { 375 if n, ok := v.(int32); ok { 376 return self.BlockByNumber(int64(n)) 377 } else if str, ok := v.(string); ok { 378 return self.BlockByHash(str) 379 } else if f, ok := v.(float64); ok { // JSON numbers are represented as float64 380 return self.BlockByNumber(int64(f)) 381 } 382 383 return nil 384 } 385 386 func (self *XEth) Accounts() []string { 387 // TODO: check err? 388 accounts, _ := self.backend.AccountManager().Accounts() 389 accountAddresses := make([]string, len(accounts)) 390 for i, ac := range accounts { 391 accountAddresses[i] = ac.Address.Hex() 392 } 393 return accountAddresses 394 } 395 396 // accessor for solidity compiler. 397 // memoized if available, retried on-demand if not 398 func (self *XEth) Solc() (*compiler.Solidity, error) { 399 return self.backend.Solc() 400 } 401 402 // set in js console via admin interface or wrapper from cli flags 403 func (self *XEth) SetSolc(solcPath string) (*compiler.Solidity, error) { 404 self.backend.SetSolc(solcPath) 405 return self.Solc() 406 } 407 408 // store DApp value in extra database 409 func (self *XEth) DbPut(key, val []byte) bool { 410 self.backend.DappDb().Put(append(dappStorePre, key...), val) 411 return true 412 } 413 414 // retrieve DApp value from extra database 415 func (self *XEth) DbGet(key []byte) ([]byte, error) { 416 val, err := self.backend.DappDb().Get(append(dappStorePre, key...)) 417 return val, err 418 } 419 420 func (self *XEth) PeerCount() int { 421 return self.backend.PeerCount() 422 } 423 424 func (self *XEth) IsMining() bool { 425 return self.backend.IsMining() 426 } 427 428 func (self *XEth) HashRate() int64 { 429 return self.backend.Miner().HashRate() 430 } 431 432 func (self *XEth) EthVersion() string { 433 return fmt.Sprintf("%d", self.backend.EthVersion()) 434 } 435 436 func (self *XEth) NetworkVersion() string { 437 return fmt.Sprintf("%d", self.backend.NetVersion()) 438 } 439 440 func (self *XEth) WhisperVersion() string { 441 return fmt.Sprintf("%d", self.backend.ShhVersion()) 442 } 443 444 func (self *XEth) ClientVersion() string { 445 return self.backend.ClientVersion() 446 } 447 448 func (self *XEth) SetMining(shouldmine bool, threads int) bool { 449 ismining := self.backend.IsMining() 450 if shouldmine && !ismining { 451 err := self.backend.StartMining(threads) 452 return err == nil 453 } 454 if ismining && !shouldmine { 455 self.backend.StopMining() 456 } 457 return self.backend.IsMining() 458 } 459 460 func (self *XEth) IsListening() bool { 461 return self.backend.IsListening() 462 } 463 464 func (self *XEth) Coinbase() string { 465 eb, err := self.backend.Etherbase() 466 if err != nil { 467 return "0x0" 468 } 469 return eb.Hex() 470 } 471 472 func (self *XEth) NumberToHuman(balance string) string { 473 b := common.Big(balance) 474 475 return common.CurrencyToString(b) 476 } 477 478 func (self *XEth) StorageAt(addr, storageAddr string) string { 479 return self.State().state.GetState(common.HexToAddress(addr), common.HexToHash(storageAddr)).Hex() 480 } 481 482 func (self *XEth) BalanceAt(addr string) string { 483 return common.ToHex(self.State().state.GetBalance(common.HexToAddress(addr)).Bytes()) 484 } 485 486 func (self *XEth) TxCountAt(address string) int { 487 return int(self.State().state.GetNonce(common.HexToAddress(address))) 488 } 489 490 func (self *XEth) CodeAt(address string) string { 491 return common.ToHex(self.State().state.GetCode(common.HexToAddress(address))) 492 } 493 494 func (self *XEth) CodeAtBytes(address string) []byte { 495 return self.State().SafeGet(address).Code() 496 } 497 498 func (self *XEth) IsContract(address string) bool { 499 return len(self.State().SafeGet(address).Code()) > 0 500 } 501 502 func (self *XEth) UninstallFilter(id int) bool { 503 defer self.filterManager.UninstallFilter(id) 504 505 if _, ok := self.logQueue[id]; ok { 506 self.logMu.Lock() 507 defer self.logMu.Unlock() 508 delete(self.logQueue, id) 509 return true 510 } 511 if _, ok := self.blockQueue[id]; ok { 512 self.blockMu.Lock() 513 defer self.blockMu.Unlock() 514 delete(self.blockQueue, id) 515 return true 516 } 517 if _, ok := self.transactionQueue[id]; ok { 518 self.transactionMu.Lock() 519 defer self.transactionMu.Unlock() 520 delete(self.transactionQueue, id) 521 return true 522 } 523 524 return false 525 } 526 527 func (self *XEth) NewLogFilter(earliest, latest int64, skip, max int, address []string, topics [][]string) int { 528 self.logMu.Lock() 529 defer self.logMu.Unlock() 530 531 var id int 532 filter := core.NewFilter(self.backend) 533 filter.SetEarliestBlock(earliest) 534 filter.SetLatestBlock(latest) 535 filter.SetSkip(skip) 536 filter.SetMax(max) 537 filter.SetAddress(cAddress(address)) 538 filter.SetTopics(cTopics(topics)) 539 filter.LogsCallback = func(logs state.Logs) { 540 self.logMu.Lock() 541 defer self.logMu.Unlock() 542 543 self.logQueue[id].add(logs...) 544 } 545 id = self.filterManager.InstallFilter(filter) 546 self.logQueue[id] = &logQueue{timeout: time.Now()} 547 548 return id 549 } 550 551 func (self *XEth) NewTransactionFilter() int { 552 self.transactionMu.Lock() 553 defer self.transactionMu.Unlock() 554 555 var id int 556 filter := core.NewFilter(self.backend) 557 filter.TransactionCallback = func(tx *types.Transaction) { 558 self.transactionMu.Lock() 559 defer self.transactionMu.Unlock() 560 561 self.transactionQueue[id].add(tx.Hash()) 562 } 563 id = self.filterManager.InstallFilter(filter) 564 self.transactionQueue[id] = &hashQueue{timeout: time.Now()} 565 return id 566 } 567 568 func (self *XEth) NewBlockFilter() int { 569 self.blockMu.Lock() 570 defer self.blockMu.Unlock() 571 572 var id int 573 filter := core.NewFilter(self.backend) 574 filter.BlockCallback = func(block *types.Block, logs state.Logs) { 575 self.blockMu.Lock() 576 defer self.blockMu.Unlock() 577 578 self.blockQueue[id].add(block.Hash()) 579 } 580 id = self.filterManager.InstallFilter(filter) 581 self.blockQueue[id] = &hashQueue{timeout: time.Now()} 582 return id 583 } 584 585 func (self *XEth) GetFilterType(id int) byte { 586 if _, ok := self.blockQueue[id]; ok { 587 return BlockFilterTy 588 } else if _, ok := self.transactionQueue[id]; ok { 589 return TransactionFilterTy 590 } else if _, ok := self.logQueue[id]; ok { 591 return LogFilterTy 592 } 593 594 return UnknownFilterTy 595 } 596 597 func (self *XEth) LogFilterChanged(id int) state.Logs { 598 self.logMu.Lock() 599 defer self.logMu.Unlock() 600 601 if self.logQueue[id] != nil { 602 return self.logQueue[id].get() 603 } 604 return nil 605 } 606 607 func (self *XEth) BlockFilterChanged(id int) []common.Hash { 608 self.blockMu.Lock() 609 defer self.blockMu.Unlock() 610 611 if self.blockQueue[id] != nil { 612 return self.blockQueue[id].get() 613 } 614 return nil 615 } 616 617 func (self *XEth) TransactionFilterChanged(id int) []common.Hash { 618 self.blockMu.Lock() 619 defer self.blockMu.Unlock() 620 621 if self.transactionQueue[id] != nil { 622 return self.transactionQueue[id].get() 623 } 624 return nil 625 } 626 627 func (self *XEth) Logs(id int) state.Logs { 628 filter := self.filterManager.GetFilter(id) 629 if filter != nil { 630 return filter.Find() 631 } 632 633 return nil 634 } 635 636 func (self *XEth) AllLogs(earliest, latest int64, skip, max int, address []string, topics [][]string) state.Logs { 637 filter := core.NewFilter(self.backend) 638 filter.SetEarliestBlock(earliest) 639 filter.SetLatestBlock(latest) 640 filter.SetSkip(skip) 641 filter.SetMax(max) 642 filter.SetAddress(cAddress(address)) 643 filter.SetTopics(cTopics(topics)) 644 645 return filter.Find() 646 } 647 648 // NewWhisperFilter creates and registers a new message filter to watch for 649 // inbound whisper messages. All parameters at this point are assumed to be 650 // HEX encoded. 651 func (p *XEth) NewWhisperFilter(to, from string, topics [][]string) int { 652 // Pre-define the id to be filled later 653 var id int 654 655 // Callback to delegate core whisper messages to this xeth filter 656 callback := func(msg WhisperMessage) { 657 p.messagesMu.RLock() // Only read lock to the filter pool 658 defer p.messagesMu.RUnlock() 659 p.messages[id].insert(msg) 660 } 661 // Initialize the core whisper filter and wrap into xeth 662 id = p.Whisper().Watch(to, from, topics, callback) 663 664 p.messagesMu.Lock() 665 p.messages[id] = newWhisperFilter(id, p.Whisper()) 666 p.messagesMu.Unlock() 667 668 return id 669 } 670 671 // UninstallWhisperFilter disables and removes an existing filter. 672 func (p *XEth) UninstallWhisperFilter(id int) bool { 673 p.messagesMu.Lock() 674 defer p.messagesMu.Unlock() 675 676 if _, ok := p.messages[id]; ok { 677 delete(p.messages, id) 678 return true 679 } 680 return false 681 } 682 683 // WhisperMessages retrieves all the known messages that match a specific filter. 684 func (self *XEth) WhisperMessages(id int) []WhisperMessage { 685 self.messagesMu.RLock() 686 defer self.messagesMu.RUnlock() 687 688 if self.messages[id] != nil { 689 return self.messages[id].messages() 690 } 691 return nil 692 } 693 694 // WhisperMessagesChanged retrieves all the new messages matched by a filter 695 // since the last retrieval 696 func (self *XEth) WhisperMessagesChanged(id int) []WhisperMessage { 697 self.messagesMu.RLock() 698 defer self.messagesMu.RUnlock() 699 700 if self.messages[id] != nil { 701 return self.messages[id].retrieve() 702 } 703 return nil 704 } 705 706 // func (self *XEth) Register(args string) bool { 707 // self.regmut.Lock() 708 // defer self.regmut.Unlock() 709 710 // if _, ok := self.register[args]; ok { 711 // self.register[args] = nil // register with empty 712 // } 713 // return true 714 // } 715 716 // func (self *XEth) Unregister(args string) bool { 717 // self.regmut.Lock() 718 // defer self.regmut.Unlock() 719 720 // if _, ok := self.register[args]; ok { 721 // delete(self.register, args) 722 // return true 723 // } 724 725 // return false 726 // } 727 728 // // TODO improve return type 729 // func (self *XEth) PullWatchTx(args string) []*interface{} { 730 // self.regmut.Lock() 731 // defer self.regmut.Unlock() 732 733 // txs := self.register[args] 734 // self.register[args] = nil 735 736 // return txs 737 // } 738 739 type KeyVal struct { 740 Key string `json:"key"` 741 Value string `json:"value"` 742 } 743 744 func (self *XEth) EachStorage(addr string) string { 745 var values []KeyVal 746 object := self.State().SafeGet(addr) 747 it := object.Trie().Iterator() 748 for it.Next() { 749 values = append(values, KeyVal{common.ToHex(object.Trie().GetKey(it.Key)), common.ToHex(it.Value)}) 750 } 751 752 valuesJson, err := json.Marshal(values) 753 if err != nil { 754 return "" 755 } 756 757 return string(valuesJson) 758 } 759 760 func (self *XEth) ToAscii(str string) string { 761 padded := common.RightPadBytes([]byte(str), 32) 762 763 return "0x" + common.ToHex(padded) 764 } 765 766 func (self *XEth) FromAscii(str string) string { 767 if common.IsHex(str) { 768 str = str[2:] 769 } 770 771 return string(bytes.Trim(common.FromHex(str), "\x00")) 772 } 773 774 func (self *XEth) FromNumber(str string) string { 775 if common.IsHex(str) { 776 str = str[2:] 777 } 778 779 return common.BigD(common.FromHex(str)).String() 780 } 781 782 func (self *XEth) PushTx(encodedTx string) (string, error) { 783 tx := new(types.Transaction) 784 err := rlp.DecodeBytes(common.FromHex(encodedTx), tx) 785 if err != nil { 786 glog.V(logger.Error).Infoln(err) 787 return "", err 788 } 789 790 err = self.backend.TxPool().Add(tx) 791 if err != nil { 792 return "", err 793 } 794 795 if tx.To() == nil { 796 from, err := tx.From() 797 if err != nil { 798 return "", err 799 } 800 801 addr := crypto.CreateAddress(from, tx.Nonce()) 802 glog.V(logger.Info).Infof("Tx(%x) created: %x\n", tx.Hash(), addr) 803 } else { 804 glog.V(logger.Info).Infof("Tx(%x) to: %x\n", tx.Hash(), tx.To()) 805 } 806 807 return tx.Hash().Hex(), nil 808 } 809 810 func (self *XEth) Call(fromStr, toStr, valueStr, gasStr, gasPriceStr, dataStr string) (string, string, error) { 811 statedb := self.State().State().Copy() 812 var from *state.StateObject 813 if len(fromStr) == 0 { 814 accounts, err := self.backend.AccountManager().Accounts() 815 if err != nil || len(accounts) == 0 { 816 from = statedb.GetOrNewStateObject(common.Address{}) 817 } else { 818 from = statedb.GetOrNewStateObject(accounts[0].Address) 819 } 820 } else { 821 from = statedb.GetOrNewStateObject(common.HexToAddress(fromStr)) 822 } 823 824 from.SetBalance(common.MaxBig) 825 from.SetGasLimit(common.MaxBig) 826 827 msg := callmsg{ 828 from: from, 829 gas: common.Big(gasStr), 830 gasPrice: common.Big(gasPriceStr), 831 value: common.Big(valueStr), 832 data: common.FromHex(dataStr), 833 } 834 if len(toStr) > 0 { 835 addr := common.HexToAddress(toStr) 836 msg.to = &addr 837 } 838 839 if msg.gas.Cmp(big.NewInt(0)) == 0 { 840 msg.gas = big.NewInt(50000000) 841 } 842 843 if msg.gasPrice.Cmp(big.NewInt(0)) == 0 { 844 msg.gasPrice = self.DefaultGasPrice() 845 } 846 847 header := self.CurrentBlock().Header() 848 vmenv := core.NewEnv(statedb, self.backend.ChainManager(), msg, header) 849 850 res, gas, err := core.ApplyMessage(vmenv, msg, from) 851 return common.ToHex(res), gas.String(), err 852 } 853 854 func (self *XEth) ConfirmTransaction(tx string) bool { 855 return self.frontend.ConfirmTransaction(tx) 856 } 857 858 func (self *XEth) doSign(from common.Address, hash common.Hash, didUnlock bool) ([]byte, error) { 859 sig, err := self.backend.AccountManager().Sign(accounts.Account{Address: from}, hash.Bytes()) 860 if err == accounts.ErrLocked { 861 if didUnlock { 862 return nil, fmt.Errorf("signer account still locked after successful unlock") 863 } 864 if !self.frontend.UnlockAccount(from.Bytes()) { 865 return nil, fmt.Errorf("could not unlock signer account") 866 } 867 // retry signing, the account should now be unlocked. 868 return self.doSign(from, hash, true) 869 } else if err != nil { 870 return nil, err 871 } 872 return sig, nil 873 } 874 875 func (self *XEth) Sign(fromStr, hashStr string, didUnlock bool) (string, error) { 876 var ( 877 from = common.HexToAddress(fromStr) 878 hash = common.HexToHash(hashStr) 879 ) 880 sig, err := self.doSign(from, hash, didUnlock) 881 if err != nil { 882 return "", err 883 } 884 return common.ToHex(sig), nil 885 } 886 887 func isAddress(addr string) bool { 888 return addrReg.MatchString(addr) 889 } 890 891 func (self *XEth) Frontend() Frontend { 892 return self.frontend 893 } 894 895 func (self *XEth) Transact(fromStr, toStr, nonceStr, valueStr, gasStr, gasPriceStr, codeStr string) (string, error) { 896 897 // this minimalistic recoding is enough (works for natspec.js) 898 var jsontx = fmt.Sprintf(`{"params":[{"to":"%s","data": "%s"}]}`, toStr, codeStr) 899 if !self.ConfirmTransaction(jsontx) { 900 err := fmt.Errorf("Transaction not confirmed") 901 return "", err 902 } 903 904 if len(toStr) > 0 && toStr != "0x" && !isAddress(toStr) { 905 return "", errors.New("Invalid address") 906 } 907 908 var ( 909 from = common.HexToAddress(fromStr) 910 to = common.HexToAddress(toStr) 911 value = common.Big(valueStr) 912 gas *big.Int 913 price *big.Int 914 data []byte 915 contractCreation bool 916 ) 917 918 if len(gasStr) == 0 { 919 gas = DefaultGas() 920 } else { 921 gas = common.Big(gasStr) 922 } 923 924 if len(gasPriceStr) == 0 { 925 price = self.DefaultGasPrice() 926 } else { 927 price = common.Big(gasPriceStr) 928 } 929 930 data = common.FromHex(codeStr) 931 if len(toStr) == 0 { 932 contractCreation = true 933 } 934 935 // 2015-05-18 Is this still needed? 936 // TODO if no_private_key then 937 //if _, exists := p.register[args.From]; exists { 938 // p.register[args.From] = append(p.register[args.From], args) 939 //} else { 940 /* 941 account := accounts.Get(common.FromHex(args.From)) 942 if account != nil { 943 if account.Unlocked() { 944 if !unlockAccount(account) { 945 return 946 } 947 } 948 949 result, _ := account.Transact(common.FromHex(args.To), common.FromHex(args.Value), common.FromHex(args.Gas), common.FromHex(args.GasPrice), common.FromHex(args.Data)) 950 if len(result) > 0 { 951 *reply = common.ToHex(result) 952 } 953 } else if _, exists := p.register[args.From]; exists { 954 p.register[ags.From] = append(p.register[args.From], args) 955 } 956 */ 957 958 self.transactMu.Lock() 959 defer self.transactMu.Unlock() 960 961 var nonce uint64 962 if len(nonceStr) != 0 { 963 nonce = common.Big(nonceStr).Uint64() 964 } else { 965 state := self.backend.TxPool().State() 966 nonce = state.GetNonce(from) 967 } 968 var tx *types.Transaction 969 if contractCreation { 970 tx = types.NewContractCreation(nonce, value, gas, price, data) 971 } else { 972 tx = types.NewTransaction(nonce, to, value, gas, price, data) 973 } 974 975 signed, err := self.sign(tx, from, false) 976 if err != nil { 977 return "", err 978 } 979 if err = self.backend.TxPool().Add(signed); err != nil { 980 return "", err 981 } 982 983 if contractCreation { 984 addr := crypto.CreateAddress(from, nonce) 985 glog.V(logger.Info).Infof("Tx(%s) created: %s\n", signed.Hash().Hex(), addr.Hex()) 986 } else { 987 glog.V(logger.Info).Infof("Tx(%s) to: %s\n", signed.Hash().Hex(), tx.To().Hex()) 988 } 989 990 return signed.Hash().Hex(), nil 991 } 992 993 func (self *XEth) sign(tx *types.Transaction, from common.Address, didUnlock bool) (*types.Transaction, error) { 994 hash := tx.SigHash() 995 sig, err := self.doSign(from, hash, didUnlock) 996 if err != nil { 997 return tx, err 998 } 999 return tx.WithSignature(sig) 1000 } 1001 1002 // callmsg is the message type used for call transations. 1003 type callmsg struct { 1004 from *state.StateObject 1005 to *common.Address 1006 gas, gasPrice *big.Int 1007 value *big.Int 1008 data []byte 1009 } 1010 1011 // accessor boilerplate to implement core.Message 1012 func (m callmsg) From() (common.Address, error) { return m.from.Address(), nil } 1013 func (m callmsg) Nonce() uint64 { return m.from.Nonce() } 1014 func (m callmsg) To() *common.Address { return m.to } 1015 func (m callmsg) GasPrice() *big.Int { return m.gasPrice } 1016 func (m callmsg) Gas() *big.Int { return m.gas } 1017 func (m callmsg) Value() *big.Int { return m.value } 1018 func (m callmsg) Data() []byte { return m.data } 1019 1020 type logQueue struct { 1021 logs state.Logs 1022 timeout time.Time 1023 id int 1024 } 1025 1026 func (l *logQueue) add(logs ...*state.Log) { 1027 l.logs = append(l.logs, logs...) 1028 } 1029 1030 func (l *logQueue) get() state.Logs { 1031 l.timeout = time.Now() 1032 tmp := l.logs 1033 l.logs = nil 1034 return tmp 1035 } 1036 1037 type hashQueue struct { 1038 hashes []common.Hash 1039 timeout time.Time 1040 id int 1041 } 1042 1043 func (l *hashQueue) add(hashes ...common.Hash) { 1044 l.hashes = append(l.hashes, hashes...) 1045 } 1046 1047 func (l *hashQueue) get() []common.Hash { 1048 l.timeout = time.Now() 1049 tmp := l.hashes 1050 l.hashes = nil 1051 return tmp 1052 }