| 
									
										
										
										
											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" | 
					
						
							| 
									
										
										
										
											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
										 |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 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-03-16 11:27:38 +01:00
										 |  |  | type Storage map[string]*common.Value | 
					
						
							| 
									
										
										
										
											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 { | 
					
						
							|  |  |  | 		str += fmt.Sprintf("%X : %X\n", key, value.Bytes()) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-22 11:54:48 +02:00
										 |  |  | func (self Storage) Copy() Storage { | 
					
						
							|  |  |  | 	cpy := make(Storage) | 
					
						
							|  |  |  | 	for key, value := range self { | 
					
						
							|  |  |  | 		// XXX Do we need a 'value' copy or is this sufficient? | 
					
						
							|  |  |  | 		cpy[key] = value | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return cpy | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | type StateObject struct { | 
					
						
							| 
									
										
										
										
											2015-03-12 22:29:10 +01:00
										 |  |  | 	// State database for storing state changes | 
					
						
							| 
									
										
										
										
											2015-03-16 11:27:38 +01:00
										 |  |  | 	db common.Database | 
					
						
							| 
									
										
										
										
											2015-03-12 22:29:10 +01:00
										 |  |  | 	// The state object | 
					
						
							|  |  |  | 	State *StateDB | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// 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 | 
					
						
							| 
									
										
										
										
											2015-03-12 22:29:10 +01:00
										 |  |  | 	// Temporary prepaid gas, reward after transition | 
					
						
							|  |  |  | 	prepaid *big.Int | 
					
						
							| 
									
										
										
										
											2014-07-22 11:54:48 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// Total gas pool is the total amount of gas currently | 
					
						
							|  |  |  | 	// left if this object is the coinbase. Gas is directly | 
					
						
							|  |  |  | 	// purchased of the coinbase. | 
					
						
							|  |  |  | 	gasPool *big.Int | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// 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 | 
					
						
							|  |  |  | 	remove bool | 
					
						
							| 
									
										
										
										
											2015-02-19 22:33:22 +01:00
										 |  |  | 	dirty  bool | 
					
						
							| 
									
										
										
										
											2014-07-22 11:54:48 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (self *StateObject) Reset() { | 
					
						
							|  |  |  | 	self.storage = make(Storage) | 
					
						
							| 
									
										
										
										
											2014-07-24 12:04:15 +02:00
										 |  |  | 	self.State.Reset() | 
					
						
							| 
									
										
										
										
											2014-07-22 11:54:48 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-16 11:59:52 +01:00
										 |  |  | func NewStateObject(address common.Address, db common.Database) *StateObject { | 
					
						
							| 
									
										
										
										
											2014-07-22 11:54:48 +02:00
										 |  |  | 	// This to ensure that it has 20 bytes (and not 0 bytes), thus left or right pad doesn't matter. | 
					
						
							| 
									
										
										
										
											2015-03-16 11:59:52 +01:00
										 |  |  | 	//address := common.ToAddress(addr) | 
					
						
							| 
									
										
										
										
											2014-07-22 11:54:48 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-20 14:01:30 +01:00
										 |  |  | 	object := &StateObject{db: db, address: address, balance: new(big.Int), gasPool: new(big.Int), dirty: true} | 
					
						
							| 
									
										
										
										
											2015-03-16 23:48:18 +01:00
										 |  |  | 	object.State = New(common.Hash{}, db) //New(trie.New(common.Config.Db, "")) | 
					
						
							| 
									
										
										
										
											2014-07-22 11:54:48 +02:00
										 |  |  | 	object.storage = make(Storage) | 
					
						
							|  |  |  | 	object.gasPool = new(big.Int) | 
					
						
							| 
									
										
										
										
											2015-03-12 22:29:10 +01:00
										 |  |  | 	object.prepaid = new(big.Int) | 
					
						
							| 
									
										
										
										
											2014-07-22 11:54:48 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return object | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-16 11:59:52 +01:00
										 |  |  | func NewStateObjectFromBytes(address common.Address, data []byte, db common.Database) *StateObject { | 
					
						
							| 
									
										
										
										
											2015-02-17 13:10:18 +01:00
										 |  |  | 	// TODO clean me up | 
					
						
							|  |  |  | 	var extobject struct { | 
					
						
							|  |  |  | 		Nonce    uint64 | 
					
						
							|  |  |  | 		Balance  *big.Int | 
					
						
							| 
									
										
										
										
											2015-03-16 11:59:52 +01:00
										 |  |  | 		Root     common.Hash | 
					
						
							| 
									
										
										
										
											2015-02-17 13:10:18 +01:00
										 |  |  | 		CodeHash []byte | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	err := rlp.Decode(bytes.NewReader(data), &extobject) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		fmt.Println(err) | 
					
						
							|  |  |  | 		return nil | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-07 13:17:48 +01:00
										 |  |  | 	object := &StateObject{address: address, db: db} | 
					
						
							| 
									
										
										
										
											2015-02-17 13:10:18 +01:00
										 |  |  | 	//object.RlpDecode(data) | 
					
						
							| 
									
										
										
										
											2015-02-20 14:19:34 +01:00
										 |  |  | 	object.nonce = extobject.Nonce | 
					
						
							| 
									
										
										
										
											2015-02-17 13:10:18 +01:00
										 |  |  | 	object.balance = extobject.Balance | 
					
						
							|  |  |  | 	object.codeHash = extobject.CodeHash | 
					
						
							| 
									
										
										
										
											2015-03-16 23:48:18 +01:00
										 |  |  | 	object.State = New(extobject.Root, db) | 
					
						
							| 
									
										
										
										
											2015-03-16 11:27:38 +01:00
										 |  |  | 	object.storage = make(map[string]*common.Value) | 
					
						
							| 
									
										
										
										
											2015-02-17 13:10:18 +01:00
										 |  |  | 	object.gasPool = new(big.Int) | 
					
						
							| 
									
										
										
										
											2015-03-12 22:29:10 +01:00
										 |  |  | 	object.prepaid = new(big.Int) | 
					
						
							| 
									
										
										
										
											2015-02-20 14:19:34 +01:00
										 |  |  | 	object.code, _ = db.Get(extobject.CodeHash) | 
					
						
							| 
									
										
										
										
											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-03-16 17:09:08 +01:00
										 |  |  | func (c *StateObject) getAddr(addr common.Hash) *common.Value { | 
					
						
							|  |  |  | 	return common.NewValueFromBytes([]byte(c.State.trie.Get(addr[:]))) | 
					
						
							| 
									
										
										
										
											2014-07-22 11:54:48 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-23 18:35:36 +01:00
										 |  |  | func (c *StateObject) setAddr(addr []byte, value interface{}) { | 
					
						
							| 
									
										
										
										
											2015-03-16 11:27:38 +01:00
										 |  |  | 	c.State.trie.Update(addr, common.Encode(value)) | 
					
						
							| 
									
										
										
										
											2014-07-22 11:54:48 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-16 11:27:38 +01:00
										 |  |  | func (self *StateObject) GetStorage(key *big.Int) *common.Value { | 
					
						
							| 
									
										
										
										
											2015-03-16 17:09:08 +01:00
										 |  |  | 	return self.GetState(common.BytesToHash(key.Bytes())) | 
					
						
							| 
									
										
										
										
											2014-07-22 11:54:48 +02:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2015-03-16 11:27:38 +01:00
										 |  |  | func (self *StateObject) SetStorage(key *big.Int, value *common.Value) { | 
					
						
							| 
									
										
										
										
											2015-03-16 17:09:08 +01:00
										 |  |  | 	self.SetState(common.BytesToHash(key.Bytes()), value) | 
					
						
							| 
									
										
										
										
											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-03-16 17:09:08 +01:00
										 |  |  | func (self *StateObject) GetState(key common.Hash) *common.Value { | 
					
						
							|  |  |  | 	strkey := key.Str() | 
					
						
							|  |  |  | 	value := self.storage[strkey] | 
					
						
							| 
									
										
										
										
											2014-07-22 11:54:48 +02:00
										 |  |  | 	if value == nil { | 
					
						
							| 
									
										
										
										
											2014-12-23 18:35:36 +01:00
										 |  |  | 		value = self.getAddr(key) | 
					
						
							| 
									
										
										
										
											2014-07-22 11:54:48 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		if !value.IsNil() { | 
					
						
							| 
									
										
										
										
											2015-03-16 17:09:08 +01:00
										 |  |  | 			self.storage[strkey] = value | 
					
						
							| 
									
										
										
										
											2014-07-22 11:54:48 +02:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return value | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-16 17:09:08 +01:00
										 |  |  | func (self *StateObject) SetState(k common.Hash, value *common.Value) { | 
					
						
							|  |  |  | 	self.storage[k.Str()] = value.Copy() | 
					
						
							| 
									
										
										
										
											2015-02-20 14:01:30 +01:00
										 |  |  | 	self.dirty = true | 
					
						
							| 
									
										
										
										
											2014-07-22 11:54:48 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (self *StateObject) Sync() { | 
					
						
							|  |  |  | 	for key, value := range self.storage { | 
					
						
							| 
									
										
										
										
											2014-11-19 15:05:08 +01:00
										 |  |  | 		if value.Len() == 0 { | 
					
						
							| 
									
										
										
										
											2014-12-23 18:35:36 +01:00
										 |  |  | 			self.State.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
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-02-19 13:34:27 +01:00
										 |  |  | 	self.storage = make(Storage) | 
					
						
							| 
									
										
										
										
											2014-07-22 11:54:48 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-16 11:27:38 +01:00
										 |  |  | func (c *StateObject) GetInstr(pc *big.Int) *common.Value { | 
					
						
							| 
									
										
										
										
											2015-02-20 14:19:34 +01:00
										 |  |  | 	if int64(len(c.code)-1) < pc.Int64() { | 
					
						
							| 
									
										
										
										
											2015-03-16 11:27:38 +01:00
										 |  |  | 		return common.NewValue(0) | 
					
						
							| 
									
										
										
										
											2014-07-22 11:54:48 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-16 11:27:38 +01:00
										 |  |  | 	return common.NewValueFromBytes([]byte{c.code[pc.Int64()]}) | 
					
						
							| 
									
										
										
										
											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
										 |  |  | // | 
					
						
							|  |  |  | // Gas setters and getters | 
					
						
							|  |  |  | // | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Return the gas back to the origin. Used by the Virtual machine or Closures | 
					
						
							|  |  |  | func (c *StateObject) ReturnGas(gas, price *big.Int) {} | 
					
						
							|  |  |  | func (c *StateObject) ConvertGas(gas, price *big.Int) error { | 
					
						
							|  |  |  | 	total := new(big.Int).Mul(gas, price) | 
					
						
							| 
									
										
										
										
											2014-10-22 15:22:21 +02:00
										 |  |  | 	if total.Cmp(c.balance) > 0 { | 
					
						
							|  |  |  | 		return fmt.Errorf("insufficient amount: %v, %v", c.balance, total) | 
					
						
							| 
									
										
										
										
											2014-07-22 11:54:48 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-26 18:39:05 +01:00
										 |  |  | 	c.SubBalance(total) | 
					
						
							| 
									
										
										
										
											2014-07-22 11:54:48 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-20 14:01:30 +01:00
										 |  |  | 	c.dirty = true | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-22 11:54:48 +02:00
										 |  |  | 	return nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (self *StateObject) SetGasPool(gasLimit *big.Int) { | 
					
						
							|  |  |  | 	self.gasPool = new(big.Int).Set(gasLimit) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-04 13:24:01 +02:00
										 |  |  | 	if glog.V(logger.Core) { | 
					
						
							| 
									
										
										
										
											2015-04-04 12:40:11 +02:00
										 |  |  | 		glog.Infof("%x: gas (+ %v)", self.Address(), self.gasPool) | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-07-22 11:54:48 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (self *StateObject) BuyGas(gas, price *big.Int) error { | 
					
						
							|  |  |  | 	if self.gasPool.Cmp(gas) < 0 { | 
					
						
							|  |  |  | 		return GasLimitError(self.gasPool, gas) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-19 22:33:22 +01:00
										 |  |  | 	self.gasPool.Sub(self.gasPool, gas) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-22 11:54:48 +02:00
										 |  |  | 	rGas := new(big.Int).Set(gas) | 
					
						
							|  |  |  | 	rGas.Mul(rGas, price) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-20 14:01:30 +01:00
										 |  |  | 	self.dirty = true | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-22 11:54:48 +02:00
										 |  |  | 	return nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (self *StateObject) RefundGas(gas, price *big.Int) { | 
					
						
							|  |  |  | 	self.gasPool.Add(self.gasPool, gas) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 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 | 
					
						
							| 
									
										
										
										
											2014-07-24 12:04:15 +02:00
										 |  |  | 	if self.State != nil { | 
					
						
							|  |  |  | 		stateObject.State = self.State.Copy() | 
					
						
							| 
									
										
										
										
											2014-07-22 11:54:48 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											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() | 
					
						
							|  |  |  | 	stateObject.gasPool.Set(self.gasPool) | 
					
						
							| 
									
										
										
										
											2014-08-25 11:29:42 +02:00
										 |  |  | 	stateObject.remove = self.remove | 
					
						
							| 
									
										
										
										
											2015-02-19 22:33:22 +01:00
										 |  |  | 	stateObject.dirty = self.dirty | 
					
						
							| 
									
										
										
										
											2014-07-22 11:54:48 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return stateObject | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (self *StateObject) Set(stateObject *StateObject) { | 
					
						
							|  |  |  | 	*self = *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
										 |  |  | func (c *StateObject) N() *big.Int { | 
					
						
							| 
									
										
										
										
											2015-02-20 14:19:34 +01:00
										 |  |  | 	return big.NewInt(int64(c.nonce)) | 
					
						
							| 
									
										
										
										
											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 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Returns the initialization Code | 
					
						
							|  |  |  | func (c *StateObject) Init() Code { | 
					
						
							| 
									
										
										
										
											2015-02-20 14:19:34 +01:00
										 |  |  | 	return c.initCode | 
					
						
							| 
									
										
										
										
											2014-07-22 11:54:48 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-03 12:25:44 +01:00
										 |  |  | func (self *StateObject) Trie() *trie.SecureTrie { | 
					
						
							| 
									
										
										
										
											2014-12-23 18:35:36 +01:00
										 |  |  | 	return self.State.trie | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-03 23:45:44 +01:00
										 |  |  | func (self *StateObject) Root() []byte { | 
					
						
							| 
									
										
										
										
											2014-12-23 18:35:36 +01: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 | 
					
						
							|  |  |  | 	self.dirty = true | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (self *StateObject) SetInitCode(code []byte) { | 
					
						
							|  |  |  | 	self.initCode = code | 
					
						
							|  |  |  | 	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
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-22 11:54:48 +02:00
										 |  |  | // | 
					
						
							|  |  |  | // Encoding | 
					
						
							|  |  |  | // | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // State object encoding methods | 
					
						
							|  |  |  | func (c *StateObject) RlpEncode() []byte { | 
					
						
							| 
									
										
										
										
											2015-03-16 11:27:38 +01:00
										 |  |  | 	return common.Encode([]interface{}{c.nonce, c.balance, c.Root(), c.CodeHash()}) | 
					
						
							| 
									
										
										
										
											2014-09-15 15:42:12 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-16 11:27:38 +01:00
										 |  |  | func (c *StateObject) CodeHash() common.Bytes { | 
					
						
							| 
									
										
										
										
											2015-02-20 14:19:34 +01:00
										 |  |  | 	return crypto.Sha3(c.code) | 
					
						
							| 
									
										
										
										
											2014-07-22 11:54:48 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (c *StateObject) RlpDecode(data []byte) { | 
					
						
							| 
									
										
										
										
											2015-03-16 11:27:38 +01:00
										 |  |  | 	decoder := common.NewValueFromBytes(data) | 
					
						
							| 
									
										
										
										
											2015-02-20 14:19:34 +01:00
										 |  |  | 	c.nonce = decoder.Get(0).Uint() | 
					
						
							| 
									
										
										
										
											2014-10-22 15:22:21 +02:00
										 |  |  | 	c.balance = decoder.Get(1).BigInt() | 
					
						
							| 
									
										
										
										
											2015-03-16 23:48:18 +01:00
										 |  |  | 	c.State = New(common.BytesToHash(decoder.Get(2).Bytes()), c.db) //New(trie.New(common.Config.Db, decoder.Get(2).Interface())) | 
					
						
							| 
									
										
										
										
											2015-03-16 11:27:38 +01:00
										 |  |  | 	c.storage = make(map[string]*common.Value) | 
					
						
							| 
									
										
										
										
											2014-07-22 11:54:48 +02:00
										 |  |  | 	c.gasPool = new(big.Int) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-15 15:42:12 +02:00
										 |  |  | 	c.codeHash = decoder.Get(3).Bytes() | 
					
						
							| 
									
										
										
										
											2014-07-22 11:54:48 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-20 14:19:34 +01:00
										 |  |  | 	c.code, _ = c.db.Get(c.codeHash) | 
					
						
							| 
									
										
										
										
											2014-07-22 11:54:48 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Storage change object. Used by the manifest for notifying changes to | 
					
						
							|  |  |  | // the sub channels. | 
					
						
							|  |  |  | type StorageState struct { | 
					
						
							|  |  |  | 	StateAddress []byte | 
					
						
							|  |  |  | 	Address      []byte | 
					
						
							|  |  |  | 	Value        *big.Int | 
					
						
							|  |  |  | } |