| 
									
										
										
										
											2015-07-07 02:54:22 +02:00
										 |  |  | // Copyright 2014 The go-ethereum Authors | 
					
						
							| 
									
										
										
										
											2015-07-22 18:48:40 +02:00
										 |  |  | // This file is part of the go-ethereum library. | 
					
						
							| 
									
										
										
										
											2015-07-07 02:54:22 +02:00
										 |  |  | // | 
					
						
							| 
									
										
										
										
											2015-07-23 18:35:11 +02:00
										 |  |  | // The go-ethereum library is free software: you can redistribute it and/or modify | 
					
						
							| 
									
										
										
										
											2015-07-07 02:54:22 +02:00
										 |  |  | // it under the terms of the GNU Lesser General Public License as published by | 
					
						
							|  |  |  | // the Free Software Foundation, either version 3 of the License, or | 
					
						
							|  |  |  | // (at your option) any later version. | 
					
						
							|  |  |  | // | 
					
						
							| 
									
										
										
										
											2015-07-22 18:48:40 +02:00
										 |  |  | // The go-ethereum library is distributed in the hope that it will be useful, | 
					
						
							| 
									
										
										
										
											2015-07-07 02:54:22 +02:00
										 |  |  | // but WITHOUT ANY WARRANTY; without even the implied warranty of | 
					
						
							| 
									
										
										
										
											2015-07-22 18:48:40 +02:00
										 |  |  | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 
					
						
							| 
									
										
										
										
											2015-07-07 02:54:22 +02:00
										 |  |  | // GNU Lesser General Public License for more details. | 
					
						
							|  |  |  | // | 
					
						
							|  |  |  | // You should have received a copy of the GNU Lesser General Public License | 
					
						
							| 
									
										
										
										
											2015-07-22 18:48:40 +02:00
										 |  |  | // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. | 
					
						
							| 
									
										
										
										
											2015-07-07 02:54:22 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-31 14:43:14 +01:00
										 |  |  | package state | 
					
						
							| 
									
										
										
										
											2014-07-22 11:54:48 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							| 
									
										
										
										
											2015-02-17 13:10:18 +01:00
										 |  |  | 	"bytes" | 
					
						
							| 
									
										
										
										
											2014-07-22 11:54:48 +02:00
										 |  |  | 	"fmt" | 
					
						
							| 
									
										
										
										
											2015-12-11 01:29:41 +01:00
										 |  |  | 	"io" | 
					
						
							| 
									
										
										
										
											2014-07-30 00:31:15 +02:00
										 |  |  | 	"math/big" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-16 11:27:38 +01:00
										 |  |  | 	"github.com/ethereum/go-ethereum/common" | 
					
						
							| 
									
										
										
										
											2015-03-16 11:59:52 +01:00
										 |  |  | 	"github.com/ethereum/go-ethereum/crypto" | 
					
						
							| 
									
										
										
										
											2015-04-04 12:40:11 +02:00
										 |  |  | 	"github.com/ethereum/go-ethereum/logger" | 
					
						
							|  |  |  | 	"github.com/ethereum/go-ethereum/logger/glog" | 
					
						
							| 
									
										
										
										
											2015-02-17 13:10:18 +01:00
										 |  |  | 	"github.com/ethereum/go-ethereum/rlp" | 
					
						
							| 
									
										
										
										
											2015-01-08 11:47:04 +01:00
										 |  |  | 	"github.com/ethereum/go-ethereum/trie" | 
					
						
							| 
									
										
										
										
											2014-07-22 11:54:48 +02:00
										 |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-21 18:40:27 +00:00
										 |  |  | var emptyCodeHash = crypto.Keccak256(nil) | 
					
						
							| 
									
										
										
										
											2015-12-11 01:29:41 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-22 11:54:48 +02:00
										 |  |  | type Code []byte | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (self Code) String() string { | 
					
						
							| 
									
										
										
										
											2014-07-22 15:57:54 +02:00
										 |  |  | 	return string(self) //strings.Join(Disassemble(self), " ") | 
					
						
							| 
									
										
										
										
											2014-07-22 11:54:48 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-03 23:46:27 +01:00
										 |  |  | type Storage map[common.Hash]common.Hash | 
					
						
							| 
									
										
										
										
											2014-07-22 11:54:48 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-26 18:39:05 +01:00
										 |  |  | func (self Storage) String() (str string) { | 
					
						
							|  |  |  | 	for key, value := range self { | 
					
						
							| 
									
										
										
										
											2015-06-17 11:24:40 +02:00
										 |  |  | 		str += fmt.Sprintf("%X : %X\n", key, value) | 
					
						
							| 
									
										
										
										
											2015-02-26 18:39:05 +01:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-22 11:54:48 +02:00
										 |  |  | func (self Storage) Copy() Storage { | 
					
						
							|  |  |  | 	cpy := make(Storage) | 
					
						
							|  |  |  | 	for key, value := range self { | 
					
						
							|  |  |  | 		cpy[key] = value | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return cpy | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-22 21:04:58 +02:00
										 |  |  | // StateObject represents an Ethereum account which is being modified. | 
					
						
							|  |  |  | // | 
					
						
							|  |  |  | // The usage pattern is as follows: | 
					
						
							|  |  |  | // First you need to obtain a state object. | 
					
						
							|  |  |  | // Account values can be accessed and modified through the object. | 
					
						
							|  |  |  | // Finally, call CommitTrie to write the modified storage trie into a database. | 
					
						
							| 
									
										
										
										
											2014-07-22 11:54:48 +02:00
										 |  |  | type StateObject struct { | 
					
						
							| 
									
										
										
										
											2016-09-22 21:04:58 +02:00
										 |  |  | 	address common.Address // Ethereum address of this account | 
					
						
							|  |  |  | 	data    Account | 
					
						
							| 
									
										
										
										
											2016-10-04 12:36:02 +02:00
										 |  |  | 	db      *StateDB | 
					
						
							| 
									
										
										
										
											2016-09-22 21:04:58 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// DB error. | 
					
						
							|  |  |  | 	// State objects are used by the consensus core and VM which are | 
					
						
							|  |  |  | 	// unable to deal with database-level errors. Any error that occurs | 
					
						
							|  |  |  | 	// during a database read is memoized here and will eventually be returned | 
					
						
							|  |  |  | 	// by StateDB.Commit. | 
					
						
							|  |  |  | 	dbErr error | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Write caches. | 
					
						
							| 
									
										
										
										
											2016-10-03 10:48:01 +03:00
										 |  |  | 	trie *trie.SecureTrie // storage trie, which becomes non-nil on first access | 
					
						
							|  |  |  | 	code Code             // contract bytecode, which gets set when code is loaded | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	cachedStorage Storage // Storage entry cache to avoid duplicate reads | 
					
						
							|  |  |  | 	dirtyStorage  Storage // Storage entries that need to be flushed to disk | 
					
						
							| 
									
										
										
										
											2016-09-22 21:04:58 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// Cache flags. | 
					
						
							| 
									
										
										
										
											2016-10-05 22:22:31 +02:00
										 |  |  | 	// When an object is marked suicided it will be delete from the trie | 
					
						
							|  |  |  | 	// during the "update" phase of the state transition. | 
					
						
							| 
									
										
										
										
											2016-09-22 21:04:58 +02:00
										 |  |  | 	dirtyCode bool // true if the code was updated | 
					
						
							| 
									
										
										
										
											2016-10-05 22:22:31 +02:00
										 |  |  | 	suicided  bool | 
					
						
							| 
									
										
										
										
											2016-09-22 21:04:58 +02:00
										 |  |  | 	deleted   bool | 
					
						
							|  |  |  | 	onDirty   func(addr common.Address) // Callback method to mark a state object newly dirty | 
					
						
							| 
									
										
										
										
											2014-07-22 11:54:48 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-22 21:04:58 +02:00
										 |  |  | // Account is the Ethereum consensus representation of accounts. | 
					
						
							|  |  |  | // These objects are stored in the main account trie. | 
					
						
							|  |  |  | type Account struct { | 
					
						
							|  |  |  | 	Nonce    uint64 | 
					
						
							|  |  |  | 	Balance  *big.Int | 
					
						
							|  |  |  | 	Root     common.Hash // merkle root of the storage trie | 
					
						
							|  |  |  | 	CodeHash []byte | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2015-04-04 12:40:11 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-04 12:36:02 +02:00
										 |  |  | // newObject creates a state object. | 
					
						
							|  |  |  | func newObject(db *StateDB, address common.Address, data Account, onDirty func(addr common.Address)) *StateObject { | 
					
						
							| 
									
										
										
										
											2016-09-22 21:04:58 +02:00
										 |  |  | 	if data.Balance == nil { | 
					
						
							|  |  |  | 		data.Balance = new(big.Int) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if data.CodeHash == nil { | 
					
						
							|  |  |  | 		data.CodeHash = emptyCodeHash | 
					
						
							| 
									
										
										
										
											2015-04-04 12:40:11 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-10-04 12:36:02 +02:00
										 |  |  | 	return &StateObject{db: db, address: address, data: data, cachedStorage: make(Storage), dirtyStorage: make(Storage), onDirty: onDirty} | 
					
						
							| 
									
										
										
										
											2014-07-22 11:54:48 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-22 21:04:58 +02:00
										 |  |  | // EncodeRLP implements rlp.Encoder. | 
					
						
							|  |  |  | func (c *StateObject) EncodeRLP(w io.Writer) error { | 
					
						
							|  |  |  | 	return rlp.Encode(w, c.data) | 
					
						
							| 
									
										
										
										
											2014-07-22 11:54:48 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-22 21:04:58 +02:00
										 |  |  | // setError remembers the first non-nil error it is called with. | 
					
						
							|  |  |  | func (self *StateObject) setError(err error) { | 
					
						
							|  |  |  | 	if self.dbErr == nil { | 
					
						
							|  |  |  | 		self.dbErr = err | 
					
						
							| 
									
										
										
										
											2015-06-17 11:24:40 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-07-22 11:54:48 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-05 22:22:31 +02:00
										 |  |  | func (self *StateObject) markSuicided() { | 
					
						
							|  |  |  | 	self.suicided = true | 
					
						
							| 
									
										
										
										
											2016-09-22 21:04:58 +02:00
										 |  |  | 	if self.onDirty != nil { | 
					
						
							|  |  |  | 		self.onDirty(self.Address()) | 
					
						
							|  |  |  | 		self.onDirty = nil | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if glog.V(logger.Core) { | 
					
						
							|  |  |  | 		glog.Infof("%x: #%d %v X\n", self.Address(), self.Nonce(), self.Balance()) | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-10-16 13:38:21 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-22 21:04:58 +02:00
										 |  |  | func (c *StateObject) getTrie(db trie.Database) *trie.SecureTrie { | 
					
						
							|  |  |  | 	if c.trie == nil { | 
					
						
							|  |  |  | 		var err error | 
					
						
							| 
									
										
										
										
											2016-10-14 18:04:33 +02:00
										 |  |  | 		c.trie, err = trie.NewSecure(c.data.Root, db, 0) | 
					
						
							| 
									
										
										
										
											2016-09-22 21:04:58 +02:00
										 |  |  | 		if err != nil { | 
					
						
							| 
									
										
										
										
											2016-10-14 18:04:33 +02:00
										 |  |  | 			c.trie, _ = trie.NewSecure(common.Hash{}, db, 0) | 
					
						
							| 
									
										
										
										
											2016-09-22 21:04:58 +02:00
										 |  |  | 			c.setError(fmt.Errorf("can't create storage trie: %v", err)) | 
					
						
							| 
									
										
										
										
											2014-07-22 11:54:48 +02:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-09-22 21:04:58 +02:00
										 |  |  | 	return c.trie | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2014-07-22 11:54:48 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-22 21:04:58 +02:00
										 |  |  | // GetState returns a value in account storage. | 
					
						
							|  |  |  | func (self *StateObject) GetState(db trie.Database, key common.Hash) common.Hash { | 
					
						
							| 
									
										
										
										
											2016-10-03 10:48:01 +03:00
										 |  |  | 	value, exists := self.cachedStorage[key] | 
					
						
							| 
									
										
										
										
											2016-09-22 21:04:58 +02:00
										 |  |  | 	if exists { | 
					
						
							|  |  |  | 		return value | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	// Load from DB in case it is missing. | 
					
						
							| 
									
										
										
										
											2016-10-05 22:56:07 +02:00
										 |  |  | 	if enc := self.getTrie(db).Get(key[:]); len(enc) > 0 { | 
					
						
							|  |  |  | 		_, content, _, err := rlp.Split(enc) | 
					
						
							|  |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			self.setError(err) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		value.SetBytes(content) | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-09-22 21:04:58 +02:00
										 |  |  | 	if (value != common.Hash{}) { | 
					
						
							| 
									
										
										
										
											2016-10-03 10:48:01 +03:00
										 |  |  | 		self.cachedStorage[key] = value | 
					
						
							| 
									
										
										
										
											2016-09-22 21:04:58 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-07-22 11:54:48 +02:00
										 |  |  | 	return value | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-22 21:04:58 +02:00
										 |  |  | // SetState updates a value in account storage. | 
					
						
							| 
									
										
										
										
											2016-10-04 12:36:02 +02:00
										 |  |  | func (self *StateObject) SetState(db trie.Database, key, value common.Hash) { | 
					
						
							|  |  |  | 	self.db.journal = append(self.db.journal, storageChange{ | 
					
						
							|  |  |  | 		account:  &self.address, | 
					
						
							|  |  |  | 		key:      key, | 
					
						
							|  |  |  | 		prevalue: self.GetState(db, key), | 
					
						
							|  |  |  | 	}) | 
					
						
							|  |  |  | 	self.setState(key, value) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (self *StateObject) setState(key, value common.Hash) { | 
					
						
							| 
									
										
										
										
											2016-10-03 10:48:01 +03:00
										 |  |  | 	self.cachedStorage[key] = value | 
					
						
							|  |  |  | 	self.dirtyStorage[key] = value | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-22 21:04:58 +02:00
										 |  |  | 	if self.onDirty != nil { | 
					
						
							|  |  |  | 		self.onDirty(self.Address()) | 
					
						
							|  |  |  | 		self.onDirty = nil | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-07-22 11:54:48 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-22 21:04:58 +02:00
										 |  |  | // updateTrie writes cached storage modifications into the object's storage trie. | 
					
						
							|  |  |  | func (self *StateObject) updateTrie(db trie.Database) { | 
					
						
							|  |  |  | 	tr := self.getTrie(db) | 
					
						
							| 
									
										
										
										
											2016-10-03 10:48:01 +03:00
										 |  |  | 	for key, value := range self.dirtyStorage { | 
					
						
							|  |  |  | 		delete(self.dirtyStorage, key) | 
					
						
							| 
									
										
										
										
											2015-06-17 11:24:40 +02:00
										 |  |  | 		if (value == common.Hash{}) { | 
					
						
							| 
									
										
										
										
											2016-09-22 21:04:58 +02:00
										 |  |  | 			tr.Delete(key[:]) | 
					
						
							| 
									
										
										
										
											2014-07-22 11:54:48 +02:00
										 |  |  | 			continue | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2016-09-22 21:04:58 +02:00
										 |  |  | 		// Encoding []byte cannot fail, ok to ignore the error. | 
					
						
							|  |  |  | 		v, _ := rlp.EncodeToBytes(bytes.TrimLeft(value[:], "\x00")) | 
					
						
							|  |  |  | 		tr.Update(key[:], v) | 
					
						
							| 
									
										
										
										
											2014-07-22 11:54:48 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-22 21:04:58 +02:00
										 |  |  | // UpdateRoot sets the trie root to the current root hash of | 
					
						
							| 
									
										
										
										
											2016-10-04 12:36:02 +02:00
										 |  |  | func (self *StateObject) updateRoot(db trie.Database) { | 
					
						
							| 
									
										
										
										
											2016-09-22 21:04:58 +02:00
										 |  |  | 	self.updateTrie(db) | 
					
						
							|  |  |  | 	self.data.Root = self.trie.Hash() | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // CommitTrie the storage trie of the object to dwb. | 
					
						
							|  |  |  | // This updates the trie root. | 
					
						
							|  |  |  | func (self *StateObject) CommitTrie(db trie.Database, dbw trie.DatabaseWriter) error { | 
					
						
							|  |  |  | 	self.updateTrie(db) | 
					
						
							|  |  |  | 	if self.dbErr != nil { | 
					
						
							|  |  |  | 		return self.dbErr | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	root, err := self.trie.CommitTo(dbw) | 
					
						
							|  |  |  | 	if err == nil { | 
					
						
							|  |  |  | 		self.data.Root = root | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return err | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-22 15:22:21 +02:00
										 |  |  | func (c *StateObject) AddBalance(amount *big.Int) { | 
					
						
							| 
									
										
										
										
											2016-09-26 01:25:50 -04:00
										 |  |  | 	if amount.Cmp(common.Big0) == 0 { | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-09-22 21:04:58 +02:00
										 |  |  | 	c.SetBalance(new(big.Int).Add(c.Balance(), amount)) | 
					
						
							| 
									
										
										
										
											2014-07-22 11:54:48 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-04 13:24:01 +02:00
										 |  |  | 	if glog.V(logger.Core) { | 
					
						
							| 
									
										
										
										
											2016-09-22 21:04:58 +02:00
										 |  |  | 		glog.Infof("%x: #%d %v (+ %v)\n", c.Address(), c.Nonce(), c.Balance(), amount) | 
					
						
							| 
									
										
										
										
											2015-04-04 12:40:11 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-07-22 11:54:48 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-22 15:22:21 +02:00
										 |  |  | func (c *StateObject) SubBalance(amount *big.Int) { | 
					
						
							| 
									
										
										
										
											2016-09-26 01:25:50 -04:00
										 |  |  | 	if amount.Cmp(common.Big0) == 0 { | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-09-22 21:04:58 +02:00
										 |  |  | 	c.SetBalance(new(big.Int).Sub(c.Balance(), amount)) | 
					
						
							| 
									
										
										
										
											2014-07-22 11:54:48 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-04 13:24:01 +02:00
										 |  |  | 	if glog.V(logger.Core) { | 
					
						
							| 
									
										
										
										
											2016-09-22 21:04:58 +02:00
										 |  |  | 		glog.Infof("%x: #%d %v (- %v)\n", c.Address(), c.Nonce(), c.Balance(), amount) | 
					
						
							| 
									
										
										
										
											2015-04-04 12:40:11 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-07-22 11:54:48 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-22 21:04:58 +02:00
										 |  |  | func (self *StateObject) SetBalance(amount *big.Int) { | 
					
						
							| 
									
										
										
										
											2016-10-04 12:36:02 +02:00
										 |  |  | 	self.db.journal = append(self.db.journal, balanceChange{ | 
					
						
							|  |  |  | 		account: &self.address, | 
					
						
							|  |  |  | 		prev:    new(big.Int).Set(self.data.Balance), | 
					
						
							|  |  |  | 	}) | 
					
						
							|  |  |  | 	self.setBalance(amount) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (self *StateObject) setBalance(amount *big.Int) { | 
					
						
							| 
									
										
										
										
											2016-09-22 21:04:58 +02:00
										 |  |  | 	self.data.Balance = amount | 
					
						
							|  |  |  | 	if self.onDirty != nil { | 
					
						
							|  |  |  | 		self.onDirty(self.Address()) | 
					
						
							|  |  |  | 		self.onDirty = nil | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-02-26 18:39:05 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-22 11:54:48 +02:00
										 |  |  | // Return the gas back to the origin. Used by the Virtual machine or Closures | 
					
						
							|  |  |  | func (c *StateObject) ReturnGas(gas, price *big.Int) {} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-04 12:36:02 +02:00
										 |  |  | func (self *StateObject) deepCopy(db *StateDB, onDirty func(addr common.Address)) *StateObject { | 
					
						
							|  |  |  | 	stateObject := newObject(db, self.address, self.data, onDirty) | 
					
						
							| 
									
										
										
										
											2015-06-17 13:27:51 +02:00
										 |  |  | 	stateObject.trie = self.trie | 
					
						
							| 
									
										
										
										
											2016-09-19 07:56:23 +08:00
										 |  |  | 	stateObject.code = self.code | 
					
						
							| 
									
										
										
										
											2016-10-03 10:48:01 +03:00
										 |  |  | 	stateObject.dirtyStorage = self.dirtyStorage.Copy() | 
					
						
							|  |  |  | 	stateObject.cachedStorage = self.dirtyStorage.Copy() | 
					
						
							| 
									
										
										
										
											2016-10-05 22:22:31 +02:00
										 |  |  | 	stateObject.suicided = self.suicided | 
					
						
							| 
									
										
										
										
											2016-09-22 21:04:58 +02:00
										 |  |  | 	stateObject.dirtyCode = self.dirtyCode | 
					
						
							| 
									
										
										
										
											2015-09-08 15:53:17 +02:00
										 |  |  | 	stateObject.deleted = self.deleted | 
					
						
							| 
									
										
										
										
											2014-07-22 11:54:48 +02:00
										 |  |  | 	return stateObject | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // | 
					
						
							|  |  |  | // Attribute accessors | 
					
						
							|  |  |  | // | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Returns the address of the contract/account | 
					
						
							| 
									
										
										
										
											2015-03-16 11:59:52 +01:00
										 |  |  | func (c *StateObject) Address() common.Address { | 
					
						
							| 
									
										
										
										
											2014-07-22 11:54:48 +02:00
										 |  |  | 	return c.address | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-22 21:04:58 +02:00
										 |  |  | // Code returns the contract code associated with this object, if any. | 
					
						
							|  |  |  | func (self *StateObject) Code(db trie.Database) []byte { | 
					
						
							|  |  |  | 	if self.code != nil { | 
					
						
							|  |  |  | 		return self.code | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if bytes.Equal(self.CodeHash(), emptyCodeHash) { | 
					
						
							|  |  |  | 		return nil | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	code, err := db.Get(self.CodeHash()) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		self.setError(fmt.Errorf("can't load code hash %x: %v", self.CodeHash(), err)) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	self.code = code | 
					
						
							|  |  |  | 	return code | 
					
						
							| 
									
										
										
										
											2014-11-03 23:45:44 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-01 15:44:53 +03:00
										 |  |  | func (self *StateObject) SetCode(codeHash common.Hash, code []byte) { | 
					
						
							| 
									
										
										
										
											2016-10-04 12:36:02 +02:00
										 |  |  | 	prevcode := self.Code(self.db.db) | 
					
						
							|  |  |  | 	self.db.journal = append(self.db.journal, codeChange{ | 
					
						
							|  |  |  | 		account:  &self.address, | 
					
						
							|  |  |  | 		prevhash: self.CodeHash(), | 
					
						
							|  |  |  | 		prevcode: prevcode, | 
					
						
							|  |  |  | 	}) | 
					
						
							|  |  |  | 	self.setCode(codeHash, code) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (self *StateObject) setCode(codeHash common.Hash, code []byte) { | 
					
						
							| 
									
										
										
										
											2015-02-20 14:19:34 +01:00
										 |  |  | 	self.code = code | 
					
						
							| 
									
										
										
										
											2016-10-01 15:44:53 +03:00
										 |  |  | 	self.data.CodeHash = codeHash[:] | 
					
						
							| 
									
										
										
										
											2016-09-22 21:04:58 +02:00
										 |  |  | 	self.dirtyCode = true | 
					
						
							|  |  |  | 	if self.onDirty != nil { | 
					
						
							|  |  |  | 		self.onDirty(self.Address()) | 
					
						
							|  |  |  | 		self.onDirty = nil | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-02-20 14:19:34 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (self *StateObject) SetNonce(nonce uint64) { | 
					
						
							| 
									
										
										
										
											2016-10-04 12:36:02 +02:00
										 |  |  | 	self.db.journal = append(self.db.journal, nonceChange{ | 
					
						
							|  |  |  | 		account: &self.address, | 
					
						
							|  |  |  | 		prev:    self.data.Nonce, | 
					
						
							|  |  |  | 	}) | 
					
						
							|  |  |  | 	self.setNonce(nonce) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (self *StateObject) setNonce(nonce uint64) { | 
					
						
							| 
									
										
										
										
											2016-09-22 21:04:58 +02:00
										 |  |  | 	self.data.Nonce = nonce | 
					
						
							|  |  |  | 	if self.onDirty != nil { | 
					
						
							|  |  |  | 		self.onDirty(self.Address()) | 
					
						
							|  |  |  | 		self.onDirty = nil | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (self *StateObject) CodeHash() []byte { | 
					
						
							|  |  |  | 	return self.data.CodeHash | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (self *StateObject) Balance() *big.Int { | 
					
						
							|  |  |  | 	return self.data.Balance | 
					
						
							| 
									
										
										
										
											2015-02-20 14:19:34 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (self *StateObject) Nonce() uint64 { | 
					
						
							| 
									
										
										
										
											2016-09-22 21:04:58 +02:00
										 |  |  | 	return self.data.Nonce | 
					
						
							| 
									
										
										
										
											2014-12-03 17:06:54 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-27 15:40:29 +01:00
										 |  |  | // Never called, but must be present to allow StateObject to be used | 
					
						
							|  |  |  | // as a vm.Account interface that also satisfies the vm.ContractRef | 
					
						
							|  |  |  | // interface. Interfaces are awesome. | 
					
						
							|  |  |  | func (self *StateObject) Value() *big.Int { | 
					
						
							| 
									
										
										
										
											2016-01-19 23:50:00 +01:00
										 |  |  | 	panic("Value on StateObject should never be called") | 
					
						
							| 
									
										
										
										
											2015-11-27 15:40:29 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-03 23:46:27 +01:00
										 |  |  | func (self *StateObject) ForEachStorage(cb func(key, value common.Hash) bool) { | 
					
						
							| 
									
										
										
										
											2015-06-10 12:57:37 +02:00
										 |  |  | 	// When iterating over the storage check the cache first | 
					
						
							| 
									
										
										
										
											2016-10-03 10:48:01 +03:00
										 |  |  | 	for h, value := range self.cachedStorage { | 
					
						
							| 
									
										
										
										
											2016-02-03 23:46:27 +01:00
										 |  |  | 		cb(h, value) | 
					
						
							| 
									
										
										
										
											2015-06-10 12:57:37 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-04 12:36:02 +02:00
										 |  |  | 	it := self.getTrie(self.db.db).Iterator() | 
					
						
							| 
									
										
										
										
											2015-06-10 12:57:37 +02:00
										 |  |  | 	for it.Next() { | 
					
						
							|  |  |  | 		// ignore cached values | 
					
						
							| 
									
										
										
										
											2016-02-03 23:46:27 +01:00
										 |  |  | 		key := common.BytesToHash(self.trie.GetKey(it.Key)) | 
					
						
							| 
									
										
										
										
											2016-10-03 10:48:01 +03:00
										 |  |  | 		if _, ok := self.cachedStorage[key]; !ok { | 
					
						
							| 
									
										
										
										
											2016-02-03 23:46:27 +01:00
										 |  |  | 			cb(key, common.BytesToHash(it.Value)) | 
					
						
							| 
									
										
										
										
											2015-06-10 12:57:37 +02:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } |