| 
									
										
										
										
											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
										 |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-11 01:29:41 +01:00
										 |  |  | var emptyCodeHash = crypto.Sha3(nil) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-06-17 11:24:40 +02:00
										 |  |  | type Storage map[string]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 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | type StateObject struct { | 
					
						
							| 
									
										
										
										
											2015-12-11 01:29:41 +01:00
										 |  |  | 	db   trie.Database // State database for storing state changes | 
					
						
							| 
									
										
										
										
											2015-06-17 13:27:51 +02:00
										 |  |  | 	trie *trie.SecureTrie | 
					
						
							| 
									
										
										
										
											2015-03-12 22:29:10 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// Address belonging to this account | 
					
						
							| 
									
										
										
										
											2015-03-16 11:59:52 +01:00
										 |  |  | 	address common.Address | 
					
						
							| 
									
										
										
										
											2015-03-12 22:29:10 +01:00
										 |  |  | 	// The balance of the account | 
					
						
							|  |  |  | 	balance *big.Int | 
					
						
							|  |  |  | 	// The nonce of the account | 
					
						
							|  |  |  | 	nonce uint64 | 
					
						
							|  |  |  | 	// The code hash if code is present (i.e. a contract) | 
					
						
							| 
									
										
										
										
											2014-09-15 15:42:12 +02:00
										 |  |  | 	codeHash []byte | 
					
						
							| 
									
										
										
										
											2015-03-12 22:29:10 +01:00
										 |  |  | 	// The code for this account | 
					
						
							|  |  |  | 	code Code | 
					
						
							|  |  |  | 	// Temporarily initialisation code | 
					
						
							| 
									
										
										
										
											2015-02-20 14:19:34 +01:00
										 |  |  | 	initCode Code | 
					
						
							| 
									
										
										
										
											2015-03-12 22:29:10 +01:00
										 |  |  | 	// Cached storage (flushed when updated) | 
					
						
							| 
									
										
										
										
											2014-07-22 11:54:48 +02:00
										 |  |  | 	storage Storage | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Mark for deletion | 
					
						
							|  |  |  | 	// When an object is marked for deletion it will be delete from the trie | 
					
						
							|  |  |  | 	// during the "update" phase of the state transition | 
					
						
							| 
									
										
										
										
											2015-08-20 18:22:50 +02:00
										 |  |  | 	remove  bool | 
					
						
							|  |  |  | 	deleted bool | 
					
						
							|  |  |  | 	dirty   bool | 
					
						
							| 
									
										
										
										
											2014-07-22 11:54:48 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-11 01:29:41 +01:00
										 |  |  | func NewStateObject(address common.Address, db trie.Database) *StateObject { | 
					
						
							|  |  |  | 	object := &StateObject{ | 
					
						
							|  |  |  | 		db:       db, | 
					
						
							|  |  |  | 		address:  address, | 
					
						
							|  |  |  | 		balance:  new(big.Int), | 
					
						
							|  |  |  | 		dirty:    true, | 
					
						
							|  |  |  | 		codeHash: emptyCodeHash, | 
					
						
							|  |  |  | 		storage:  make(Storage), | 
					
						
							| 
									
										
										
										
											2015-02-17 13:10:18 +01:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-12-11 01:29:41 +01:00
										 |  |  | 	object.trie, _ = trie.NewSecure(common.Hash{}, db) | 
					
						
							| 
									
										
										
										
											2014-07-22 11:54:48 +02:00
										 |  |  | 	return object | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (self *StateObject) MarkForDeletion() { | 
					
						
							|  |  |  | 	self.remove = true | 
					
						
							| 
									
										
										
										
											2015-02-20 14:19:34 +01:00
										 |  |  | 	self.dirty = true | 
					
						
							| 
									
										
										
										
											2015-04-04 12:40:11 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-04 13:24:01 +02:00
										 |  |  | 	if glog.V(logger.Core) { | 
					
						
							| 
									
										
										
										
											2015-04-04 12:40:11 +02:00
										 |  |  | 		glog.Infof("%x: #%d %v X\n", self.Address(), self.nonce, self.balance) | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-07-22 11:54:48 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-06-17 11:30:42 +02:00
										 |  |  | func (c *StateObject) getAddr(addr common.Hash) common.Hash { | 
					
						
							|  |  |  | 	var ret []byte | 
					
						
							| 
									
										
										
										
											2015-06-17 13:27:51 +02:00
										 |  |  | 	rlp.DecodeBytes(c.trie.Get(addr[:]), &ret) | 
					
						
							| 
									
										
										
										
											2015-06-17 11:30:42 +02:00
										 |  |  | 	return common.BytesToHash(ret) | 
					
						
							| 
									
										
										
										
											2014-07-22 11:54:48 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-06-17 11:24:40 +02:00
										 |  |  | func (c *StateObject) setAddr(addr []byte, value common.Hash) { | 
					
						
							|  |  |  | 	v, err := rlp.EncodeToBytes(bytes.TrimLeft(value[:], "\x00")) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		// if RLPing failed we better panic and not fail silently. This would be considered a consensus issue | 
					
						
							|  |  |  | 		panic(err) | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-06-17 13:27:51 +02:00
										 |  |  | 	c.trie.Update(addr, v) | 
					
						
							| 
									
										
										
										
											2014-07-22 11:54:48 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-26 18:39:05 +01:00
										 |  |  | func (self *StateObject) Storage() Storage { | 
					
						
							| 
									
										
										
										
											2014-10-16 13:38:21 +02:00
										 |  |  | 	return self.storage | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-06-17 11:24:40 +02:00
										 |  |  | func (self *StateObject) GetState(key common.Hash) common.Hash { | 
					
						
							| 
									
										
										
										
											2015-03-16 17:09:08 +01:00
										 |  |  | 	strkey := key.Str() | 
					
						
							| 
									
										
										
										
											2015-06-17 11:24:40 +02:00
										 |  |  | 	value, exists := self.storage[strkey] | 
					
						
							|  |  |  | 	if !exists { | 
					
						
							| 
									
										
										
										
											2014-12-23 18:35:36 +01:00
										 |  |  | 		value = self.getAddr(key) | 
					
						
							| 
									
										
										
										
											2015-06-17 11:24:40 +02:00
										 |  |  | 		if (value != common.Hash{}) { | 
					
						
							| 
									
										
										
										
											2015-03-16 17:09:08 +01:00
										 |  |  | 			self.storage[strkey] = value | 
					
						
							| 
									
										
										
										
											2014-07-22 11:54:48 +02:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return value | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-06-17 11:24:40 +02:00
										 |  |  | func (self *StateObject) SetState(k, value common.Hash) { | 
					
						
							|  |  |  | 	self.storage[k.Str()] = value | 
					
						
							| 
									
										
										
										
											2015-02-20 14:01:30 +01:00
										 |  |  | 	self.dirty = true | 
					
						
							| 
									
										
										
										
											2014-07-22 11:54:48 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-06-17 13:27:51 +02:00
										 |  |  | // Update updates the current cached storage to the trie | 
					
						
							|  |  |  | func (self *StateObject) Update() { | 
					
						
							| 
									
										
										
										
											2014-07-22 11:54:48 +02:00
										 |  |  | 	for key, value := range self.storage { | 
					
						
							| 
									
										
										
										
											2015-06-17 11:24:40 +02:00
										 |  |  | 		if (value == common.Hash{}) { | 
					
						
							| 
									
										
										
										
											2015-06-17 13:27:51 +02:00
										 |  |  | 			self.trie.Delete([]byte(key)) | 
					
						
							| 
									
										
										
										
											2014-07-22 11:54:48 +02:00
										 |  |  | 			continue | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2014-12-23 18:35:36 +01:00
										 |  |  | 		self.setAddr([]byte(key), value) | 
					
						
							| 
									
										
										
										
											2014-07-22 11:54:48 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-22 15:22:21 +02:00
										 |  |  | func (c *StateObject) AddBalance(amount *big.Int) { | 
					
						
							|  |  |  | 	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) { | 
					
						
							| 
									
										
										
										
											2015-04-04 12:40:11 +02:00
										 |  |  | 		glog.Infof("%x: #%d %v (+ %v)\n", c.Address(), c.nonce, c.balance, amount) | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-07-22 11:54:48 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-22 15:22:21 +02:00
										 |  |  | func (c *StateObject) SubBalance(amount *big.Int) { | 
					
						
							|  |  |  | 	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) { | 
					
						
							| 
									
										
										
										
											2015-04-04 12:40:11 +02:00
										 |  |  | 		glog.Infof("%x: #%d %v (- %v)\n", c.Address(), c.nonce, c.balance, amount) | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-07-22 11:54:48 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-30 00:31:15 +02:00
										 |  |  | func (c *StateObject) SetBalance(amount *big.Int) { | 
					
						
							| 
									
										
										
										
											2014-10-22 15:22:21 +02:00
										 |  |  | 	c.balance = amount | 
					
						
							| 
									
										
										
										
											2015-02-20 14:01:30 +01:00
										 |  |  | 	c.dirty = true | 
					
						
							| 
									
										
										
										
											2014-07-22 11:54:48 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-26 18:39:05 +01:00
										 |  |  | func (c *StateObject) St() Storage { | 
					
						
							|  |  |  | 	return c.storage | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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) {} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (self *StateObject) Copy() *StateObject { | 
					
						
							| 
									
										
										
										
											2015-01-07 13:17:48 +01:00
										 |  |  | 	stateObject := NewStateObject(self.Address(), self.db) | 
					
						
							| 
									
										
										
										
											2014-10-22 15:22:21 +02:00
										 |  |  | 	stateObject.balance.Set(self.balance) | 
					
						
							| 
									
										
										
										
											2015-03-16 11:27:38 +01:00
										 |  |  | 	stateObject.codeHash = common.CopyBytes(self.codeHash) | 
					
						
							| 
									
										
										
										
											2015-02-20 14:19:34 +01:00
										 |  |  | 	stateObject.nonce = self.nonce | 
					
						
							| 
									
										
										
										
											2015-06-17 13:27:51 +02:00
										 |  |  | 	stateObject.trie = self.trie | 
					
						
							| 
									
										
										
										
											2015-03-16 11:27:38 +01:00
										 |  |  | 	stateObject.code = common.CopyBytes(self.code) | 
					
						
							|  |  |  | 	stateObject.initCode = common.CopyBytes(self.initCode) | 
					
						
							| 
									
										
										
										
											2014-07-22 11:54:48 +02:00
										 |  |  | 	stateObject.storage = self.storage.Copy() | 
					
						
							| 
									
										
										
										
											2014-08-25 11:29:42 +02:00
										 |  |  | 	stateObject.remove = self.remove | 
					
						
							| 
									
										
										
										
											2015-02-19 22:33:22 +01:00
										 |  |  | 	stateObject.dirty = self.dirty | 
					
						
							| 
									
										
										
										
											2015-09-08 15:53:17 +02:00
										 |  |  | 	stateObject.deleted = self.deleted | 
					
						
							| 
									
										
										
										
											2014-07-22 11:54:48 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return stateObject | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // | 
					
						
							|  |  |  | // Attribute accessors | 
					
						
							|  |  |  | // | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-20 14:19:34 +01:00
										 |  |  | func (self *StateObject) Balance() *big.Int { | 
					
						
							|  |  |  | 	return self.balance | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-22 11:54:48 +02:00
										 |  |  | // 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 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-03 12:25:44 +01:00
										 |  |  | func (self *StateObject) Trie() *trie.SecureTrie { | 
					
						
							| 
									
										
										
										
											2015-06-17 13:27:51 +02:00
										 |  |  | 	return self.trie | 
					
						
							| 
									
										
										
										
											2014-12-23 18:35:36 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-03 23:45:44 +01:00
										 |  |  | func (self *StateObject) Root() []byte { | 
					
						
							| 
									
										
										
										
											2015-06-17 13:27:51 +02:00
										 |  |  | 	return self.trie.Root() | 
					
						
							| 
									
										
										
										
											2014-11-03 23:45:44 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-20 14:19:34 +01:00
										 |  |  | func (self *StateObject) Code() []byte { | 
					
						
							|  |  |  | 	return self.code | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-03 17:06:54 +01:00
										 |  |  | func (self *StateObject) SetCode(code []byte) { | 
					
						
							| 
									
										
										
										
											2015-02-20 14:19:34 +01:00
										 |  |  | 	self.code = code | 
					
						
							| 
									
										
										
										
											2015-12-11 01:29:41 +01:00
										 |  |  | 	self.codeHash = crypto.Sha3(code) | 
					
						
							| 
									
										
										
										
											2015-02-20 14:19:34 +01:00
										 |  |  | 	self.dirty = true | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (self *StateObject) SetNonce(nonce uint64) { | 
					
						
							|  |  |  | 	self.nonce = nonce | 
					
						
							|  |  |  | 	self.dirty = true | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (self *StateObject) Nonce() uint64 { | 
					
						
							|  |  |  | 	return self.nonce | 
					
						
							| 
									
										
										
										
											2014-12-03 17:06:54 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-06-10 12:57:37 +02:00
										 |  |  | func (self *StateObject) EachStorage(cb func(key, value []byte)) { | 
					
						
							|  |  |  | 	// When iterating over the storage check the cache first | 
					
						
							|  |  |  | 	for h, v := range self.storage { | 
					
						
							|  |  |  | 		cb([]byte(h), v.Bytes()) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-06-17 13:27:51 +02:00
										 |  |  | 	it := self.trie.Iterator() | 
					
						
							| 
									
										
										
										
											2015-06-10 12:57:37 +02:00
										 |  |  | 	for it.Next() { | 
					
						
							|  |  |  | 		// ignore cached values | 
					
						
							| 
									
										
										
										
											2015-06-17 13:27:51 +02:00
										 |  |  | 		key := self.trie.GetKey(it.Key) | 
					
						
							| 
									
										
										
										
											2015-06-10 12:57:37 +02:00
										 |  |  | 		if _, ok := self.storage[string(key)]; !ok { | 
					
						
							|  |  |  | 			cb(key, it.Value) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-22 11:54:48 +02:00
										 |  |  | // Encoding | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-11 01:29:41 +01:00
										 |  |  | type extStateObject struct { | 
					
						
							|  |  |  | 	Nonce    uint64 | 
					
						
							|  |  |  | 	Balance  *big.Int | 
					
						
							|  |  |  | 	Root     common.Hash | 
					
						
							|  |  |  | 	CodeHash []byte | 
					
						
							| 
									
										
										
										
											2014-09-15 15:42:12 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-11 01:29:41 +01:00
										 |  |  | // EncodeRLP implements rlp.Encoder. | 
					
						
							|  |  |  | func (c *StateObject) EncodeRLP(w io.Writer) error { | 
					
						
							|  |  |  | 	return rlp.Encode(w, []interface{}{c.nonce, c.balance, c.Root(), c.codeHash}) | 
					
						
							| 
									
										
										
										
											2014-07-22 11:54:48 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-11 01:29:41 +01:00
										 |  |  | // DecodeObject decodes an RLP-encoded state object. | 
					
						
							|  |  |  | func DecodeObject(address common.Address, db trie.Database, data []byte) (*StateObject, error) { | 
					
						
							|  |  |  | 	var ( | 
					
						
							|  |  |  | 		obj = &StateObject{address: address, db: db, storage: make(Storage)} | 
					
						
							|  |  |  | 		ext extStateObject | 
					
						
							|  |  |  | 		err error | 
					
						
							|  |  |  | 	) | 
					
						
							|  |  |  | 	if err = rlp.DecodeBytes(data, &ext); err != nil { | 
					
						
							|  |  |  | 		return nil, err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if obj.trie, err = trie.NewSecure(ext.Root, db); err != nil { | 
					
						
							|  |  |  | 		return nil, err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if !bytes.Equal(ext.CodeHash, emptyCodeHash) { | 
					
						
							|  |  |  | 		if obj.code, err = db.Get(ext.CodeHash); err != nil { | 
					
						
							|  |  |  | 			return nil, fmt.Errorf("can't find code for hash %x: %v", ext.CodeHash, err) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	obj.nonce = ext.Nonce | 
					
						
							|  |  |  | 	obj.balance = ext.Balance | 
					
						
							|  |  |  | 	obj.codeHash = ext.CodeHash | 
					
						
							|  |  |  | 	return obj, nil | 
					
						
							| 
									
										
										
										
											2014-07-22 11:54:48 +02:00
										 |  |  | } |