github.com/intfoundation/intchain@v0.0.0-20220727031208-4316ad31ca73/core/state/state_object.go (about)

     1  // Copyright 2014 The go-ethereum Authors
     2  // This file is part of the go-ethereum library.
     3  //
     4  // The go-ethereum library is free software: you can redistribute it and/or modify
     5  // it under the terms of the GNU Lesser General Public License as published by
     6  // the Free Software Foundation, either version 3 of the License, or
     7  // (at your option) any later version.
     8  //
     9  // The go-ethereum library is distributed in the hope that it will be useful,
    10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    12  // GNU Lesser General Public License for more details.
    13  //
    14  // You should have received a copy of the GNU Lesser General Public License
    15  // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
    16  
    17  package state
    18  
    19  import (
    20  	"bytes"
    21  	"fmt"
    22  	"io"
    23  	"math/big"
    24  
    25  	"github.com/intfoundation/intchain/common"
    26  	"github.com/intfoundation/intchain/crypto"
    27  	"github.com/intfoundation/intchain/rlp"
    28  )
    29  
    30  var emptyCodeHash = crypto.Keccak256(nil)
    31  
    32  type Code []byte
    33  
    34  func (self Code) String() string {
    35  	return string(self) //strings.Join(Disassemble(self), " ")
    36  }
    37  
    38  type Storage map[common.Hash]common.Hash
    39  
    40  func (self Storage) String() (str string) {
    41  	for key, value := range self {
    42  		str += fmt.Sprintf("%X : %X\n", key, value)
    43  	}
    44  
    45  	return
    46  }
    47  
    48  func (self Storage) Copy() Storage {
    49  	cpy := make(Storage)
    50  	for key, value := range self {
    51  		cpy[key] = value
    52  	}
    53  
    54  	return cpy
    55  }
    56  
    57  // stateObject represents an INT Chain account which is being modified.
    58  //
    59  // The usage pattern is as follows:
    60  // First you need to obtain a state object.
    61  // Account values can be accessed and modified through the object.
    62  // Finally, call CommitTrie to write the modified storage trie into a database.
    63  type stateObject struct {
    64  	address  common.Address
    65  	addrHash common.Hash // hash of intchain address of the account
    66  	data     Account
    67  	db       *StateDB
    68  
    69  	// DB error.
    70  	// State objects are used by the consensus core and VM which are
    71  	// unable to deal with database-level errors. Any error that occurs
    72  	// during a database read is memoized here and will eventually be returned
    73  	// by StateDB.Commit.
    74  	dbErr error
    75  
    76  	// Write caches.
    77  	trie Trie // storage trie, which becomes non-nil on first access
    78  	code Code // contract bytecode, which gets set when code is loaded
    79  
    80  	originStorage Storage // Storage cache of original entries to dedup rewrites
    81  	dirtyStorage  Storage // Storage entries that need to be flushed to disk
    82  
    83  	// Cross Chain TX trie
    84  	tx1Trie Trie // tx1 trie, which become non-nil on first access
    85  	tx3Trie Trie // tx3 trie, which become non-nil on first access
    86  
    87  	dirtyTX1 map[common.Hash]struct{} // tx1 entries that need to be flushed to disk
    88  	dirtyTX3 map[common.Hash]struct{} // tx3 entries that need to be flushed to disk
    89  
    90  	// Delegate Trie
    91  	proxiedTrie   Trie    // proxied trie, store the proxied balance from other user
    92  	originProxied Proxied // cache data of proxied trie
    93  	dirtyProxied  Proxied // dirty data of proxied trie, need to be flushed to disk later
    94  
    95  	rewardTrie   Trie   // Reward Trie, store the pending reward balance for this account
    96  	originReward Reward // cache data of Reward trie
    97  	dirtyReward  Reward // dirty data of Reward trie, need to be flushed to disk later
    98  
    99  	// Cache flags.
   100  	// When an object is marked suicided it will be delete from the trie
   101  	// during the "update" phase of the state transition.
   102  	dirtyCode bool // true if the code was updated
   103  	suicided  bool
   104  	touched   bool
   105  	deleted   bool
   106  	onDirty   func(addr common.Address) // Callback method to mark a state object newly dirty
   107  }
   108  
   109  // empty returns whether the account is considered empty.
   110  func (s *stateObject) empty() bool {
   111  	return s.data.Nonce == 0 && s.data.Balance.Sign() == 0 && bytes.Equal(s.data.CodeHash, emptyCodeHash) && s.data.DepositBalance.Sign() == 0 && len(s.data.ChildChainDepositBalance) == 0 && s.data.ChainBalance.Sign() == 0 && s.data.DelegateBalance.Sign() == 0 && s.data.ProxiedBalance.Sign() == 0 && s.data.DepositProxiedBalance.Sign() == 0 && s.data.PendingRefundBalance.Sign() == 0
   112  }
   113  
   114  // Account is the INT Chain consensus representation of accounts.
   115  // These objects are stored in the main account trie.
   116  type Account struct {
   117  	Nonce                    uint64
   118  	Balance                  *big.Int                    // for normal user
   119  	DepositBalance           *big.Int                    // for validator, can not be consumed
   120  	ChildChainDepositBalance []*childChainDepositBalance // only valid in main chain for child chain validator before child chain launch, can not be consumed
   121  	ChainBalance             *big.Int                    // only valid in main chain for child chain owner, can not be consumed
   122  	Root                     common.Hash                 // merkle root of the storage trie
   123  	TX1Root                  common.Hash                 // merkle root of the TX1 trie
   124  	TX3Root                  common.Hash                 // merkle root of the TX3 trie
   125  	CodeHash                 []byte
   126  
   127  	// Delegation
   128  	DelegateBalance       *big.Int    // the accumulative balance which this account delegate the Balance to other user
   129  	ProxiedBalance        *big.Int    // the accumulative balance which other user delegate to this account (this balance can be revoked, can be deposit for validator)
   130  	DepositProxiedBalance *big.Int    // the deposit proxied balance for validator which come from ProxiedBalance (this balance can not be revoked)
   131  	PendingRefundBalance  *big.Int    // the accumulative balance which other user try to cancel their delegate balance (this balance will be refund to user's address after epoch end)
   132  	ProxiedRoot           common.Hash // merkle root of the Proxied trie
   133  	// Candidate
   134  	Candidate  bool  // flag for Account, true indicate the account has been applied for the Delegation Candidate
   135  	Commission uint8 // commission percentage of Delegation Candidate (0-100)
   136  	//BlockTime     *big.Int // number for mined blocks current epoch
   137  	//ForbiddenTime *big.Int // timestamp for last consensus block
   138  	//IsForbidden   bool     // candidate is forbidden or not
   139  	Pubkey   string
   140  	FAddress common.Address
   141  
   142  	// Reward
   143  	RewardBalance *big.Int // the accumulative reward balance for this account
   144  	//AvailableRewardBalance *big.Int    // the available reward balance for this account
   145  	RewardRoot common.Hash // merkle root of the Reward trie
   146  
   147  }
   148  
   149  // newObject creates a state object.
   150  func newObject(db *StateDB, address common.Address, data Account, onDirty func(addr common.Address)) *stateObject {
   151  	if data.Balance == nil {
   152  		data.Balance = new(big.Int)
   153  	}
   154  	if data.DepositBalance == nil {
   155  		data.DepositBalance = new(big.Int)
   156  	}
   157  	if data.ChainBalance == nil {
   158  		data.ChainBalance = new(big.Int)
   159  	}
   160  	// init delegate balance
   161  	if data.DelegateBalance == nil {
   162  		data.DelegateBalance = new(big.Int)
   163  	}
   164  	if data.ProxiedBalance == nil {
   165  		data.ProxiedBalance = new(big.Int)
   166  	}
   167  	if data.DepositProxiedBalance == nil {
   168  		data.DepositProxiedBalance = new(big.Int)
   169  	}
   170  	if data.PendingRefundBalance == nil {
   171  		data.PendingRefundBalance = new(big.Int)
   172  	}
   173  	// init reward balance
   174  	if data.RewardBalance == nil {
   175  		data.RewardBalance = new(big.Int)
   176  	}
   177  
   178  	//if data.AvailableRewardBalance == nil {
   179  	//	data.AvailableRewardBalance = new(big.Int)
   180  	//}
   181  
   182  	//if data.BlockTime == nil {
   183  	//	data.BlockTime = new(big.Int)
   184  	//}
   185  	//
   186  	//if data.ForbiddenTime == nil {
   187  	//	data.ForbiddenTime = new(big.Int)
   188  	//}
   189  
   190  	if data.CodeHash == nil {
   191  		data.CodeHash = emptyCodeHash
   192  	}
   193  	return &stateObject{
   194  		db:            db,
   195  		address:       address,
   196  		addrHash:      crypto.Keccak256Hash(address[:]),
   197  		data:          data,
   198  		originStorage: make(Storage),
   199  		dirtyStorage:  make(Storage),
   200  		dirtyTX1:      make(map[common.Hash]struct{}),
   201  		dirtyTX3:      make(map[common.Hash]struct{}),
   202  		originProxied: make(Proxied),
   203  		dirtyProxied:  make(Proxied),
   204  		originReward:  make(Reward),
   205  		dirtyReward:   make(Reward),
   206  		onDirty:       onDirty,
   207  	}
   208  }
   209  
   210  // EncodeRLP implements rlp.Encoder.
   211  func (c *stateObject) EncodeRLP(w io.Writer) error {
   212  	return rlp.Encode(w, c.data)
   213  }
   214  
   215  // setError remembers the first non-nil error it is called with.
   216  func (self *stateObject) setError(err error) {
   217  	if self.dbErr == nil {
   218  		self.dbErr = err
   219  	}
   220  }
   221  
   222  func (self *stateObject) markSuicided() {
   223  	self.suicided = true
   224  	if self.onDirty != nil {
   225  		self.onDirty(self.Address())
   226  		self.onDirty = nil
   227  	}
   228  }
   229  
   230  func (c *stateObject) touch() {
   231  	c.db.journal = append(c.db.journal, touchChange{
   232  		account:   &c.address,
   233  		prev:      c.touched,
   234  		prevDirty: c.onDirty == nil,
   235  	})
   236  	if c.onDirty != nil {
   237  		c.onDirty(c.Address())
   238  		c.onDirty = nil
   239  	}
   240  	c.touched = true
   241  }
   242  
   243  func (c *stateObject) getTX1Trie(db Database) Trie {
   244  	if c.tx1Trie == nil {
   245  		var err error
   246  		c.tx1Trie, err = db.OpenTX1Trie(c.addrHash, c.data.TX1Root)
   247  		if err != nil {
   248  			c.tx1Trie, _ = db.OpenTX1Trie(c.addrHash, common.Hash{})
   249  			c.setError(fmt.Errorf("can't create TX1 trie: %v", err))
   250  		}
   251  	}
   252  	return c.tx1Trie
   253  }
   254  
   255  // HasTX1 returns true if tx1 is in account TX1 trie.
   256  func (self *stateObject) HasTX1(db Database, txHash common.Hash) bool {
   257  	// check the dirtyTX1 firstly.
   258  	_, ok := self.dirtyTX1[txHash]
   259  	if ok {
   260  		return true
   261  	}
   262  
   263  	// Load from DB in case it is missing.
   264  	enc, err := self.getTX1Trie(db).TryGet(txHash[:])
   265  	if err != nil {
   266  		return false
   267  	}
   268  	if len(enc) > 0 {
   269  		_, content, _, err := rlp.Split(enc)
   270  		if err != nil {
   271  			self.setError(err)
   272  			return false
   273  		}
   274  		if !bytes.Equal(content, txHash[:]) {
   275  			self.setError(fmt.Errorf("content mismatch the tx hash"))
   276  			return false
   277  		}
   278  
   279  		return true
   280  	}
   281  
   282  	return false
   283  }
   284  
   285  // AddTX1 adds a tx1 in account tx1 trie.
   286  func (self *stateObject) AddTX1(db Database, txHash common.Hash) {
   287  	self.db.journal = append(self.db.journal, addTX1Change{
   288  		account: &self.address,
   289  		txHash:  txHash,
   290  	})
   291  	self.addTX1(txHash)
   292  }
   293  
   294  func (self *stateObject) addTX1(txHash common.Hash) {
   295  	self.dirtyTX1[txHash] = struct{}{}
   296  }
   297  
   298  func (self *stateObject) removeTX1(txHash common.Hash) {
   299  	delete(self.dirtyTX1, txHash)
   300  }
   301  
   302  // updateTX1Trie writes cached tx1 modifications into the object's tx1 trie.
   303  func (self *stateObject) updateTX1Trie(db Database) Trie {
   304  	tr := self.getTX1Trie(db)
   305  
   306  	for tx1 := range self.dirtyTX1 {
   307  		delete(self.dirtyTX1, tx1)
   308  
   309  		// Encoding []byte cannot fail, ok to ignore the error.
   310  		v, _ := rlp.EncodeToBytes(bytes.TrimLeft(tx1[:], "\x00"))
   311  		self.setError(tr.TryUpdate(tx1[:], v))
   312  	}
   313  	return tr
   314  }
   315  
   316  // updateTX1Root sets the trie root to the current root hash
   317  func (self *stateObject) updateTX1Root(db Database) {
   318  	self.updateTX1Trie(db)
   319  	self.data.TX1Root = self.tx1Trie.Hash()
   320  }
   321  
   322  // CommitTX1Trie the tx1 trie of the object to dwb.
   323  // This updates the trie root.
   324  func (self *stateObject) CommitTX1Trie(db Database) error {
   325  	self.updateTX1Trie(db)
   326  	if self.dbErr != nil {
   327  		return self.dbErr
   328  	}
   329  	root, err := self.tx1Trie.Commit(nil)
   330  	if err == nil {
   331  		self.data.TX1Root = root
   332  	}
   333  	return err
   334  }
   335  
   336  func (c *stateObject) getTX3Trie(db Database) Trie {
   337  	if c.tx3Trie == nil {
   338  		var err error
   339  		c.tx3Trie, err = db.OpenTX3Trie(c.addrHash, c.data.TX3Root)
   340  		if err != nil {
   341  			c.tx3Trie, _ = db.OpenTX3Trie(c.addrHash, common.Hash{})
   342  			c.setError(fmt.Errorf("can't create TX3 trie: %v", err))
   343  		}
   344  	}
   345  	return c.tx3Trie
   346  }
   347  
   348  // HasTX3 returns true if tx3 is in account TX3 trie.
   349  func (self *stateObject) HasTX3(db Database, txHash common.Hash) bool {
   350  	// check the dirtyTX3 firstly.
   351  	_, ok := self.dirtyTX3[txHash]
   352  	if ok {
   353  		return true
   354  	}
   355  
   356  	// Load from DB in case it is missing.
   357  	enc, err := self.getTX3Trie(db).TryGet(txHash[:])
   358  	if err != nil {
   359  		return false
   360  	}
   361  	if len(enc) > 0 {
   362  		_, content, _, err := rlp.Split(enc)
   363  		if err != nil {
   364  			self.setError(err)
   365  			return false
   366  		}
   367  		if !bytes.Equal(content, txHash[:]) {
   368  			self.setError(fmt.Errorf("content mismatch the tx hash"))
   369  			return false
   370  		}
   371  
   372  		return true
   373  	}
   374  
   375  	return false
   376  }
   377  
   378  // AddTX3 adds a tx3 in account tx3 trie.
   379  func (self *stateObject) AddTX3(db Database, txHash common.Hash) {
   380  	self.db.journal = append(self.db.journal, addTX3Change{
   381  		account: &self.address,
   382  		txHash:  txHash,
   383  	})
   384  	self.addTX3(txHash)
   385  }
   386  
   387  func (self *stateObject) addTX3(txHash common.Hash) {
   388  	self.dirtyTX3[txHash] = struct{}{}
   389  }
   390  
   391  func (self *stateObject) removeTX3(txHash common.Hash) {
   392  	delete(self.dirtyTX3, txHash)
   393  }
   394  
   395  // updateTX3Trie writes cached tx3 modifications into the object's tx3 trie.
   396  func (self *stateObject) updateTX3Trie(db Database) Trie {
   397  	tr := self.getTX3Trie(db)
   398  
   399  	for tx3 := range self.dirtyTX3 {
   400  		delete(self.dirtyTX3, tx3)
   401  
   402  		// Encoding []byte cannot fail, ok to ignore the error.
   403  		v, _ := rlp.EncodeToBytes(bytes.TrimLeft(tx3[:], "\x00"))
   404  		self.setError(tr.TryUpdate(tx3[:], v))
   405  	}
   406  	return tr
   407  }
   408  
   409  // updateTX3Root sets the trie root to the current root hash
   410  func (self *stateObject) updateTX3Root(db Database) {
   411  	self.updateTX3Trie(db)
   412  	self.data.TX3Root = self.tx3Trie.Hash()
   413  }
   414  
   415  // CommitTX3Trie the tx3 trie of the object to dwb.
   416  // This updates the trie root.
   417  func (self *stateObject) CommitTX3Trie(db Database) error {
   418  	self.updateTX3Trie(db)
   419  	if self.dbErr != nil {
   420  		return self.dbErr
   421  	}
   422  	root, err := self.tx3Trie.Commit(nil)
   423  	if err == nil {
   424  		self.data.TX3Root = root
   425  	}
   426  	return err
   427  }
   428  
   429  func (c *stateObject) getTrie(db Database) Trie {
   430  	if c.trie == nil {
   431  		var err error
   432  		c.trie, err = db.OpenStorageTrie(c.addrHash, c.data.Root)
   433  		if err != nil {
   434  			c.trie, _ = db.OpenStorageTrie(c.addrHash, common.Hash{})
   435  			c.setError(fmt.Errorf("can't create storage trie: %v", err))
   436  		}
   437  	}
   438  	return c.trie
   439  }
   440  
   441  // GetState returns a value in account storage.
   442  func (self *stateObject) GetState(db Database, key common.Hash) common.Hash {
   443  	// If we have a dirty value for this state entry, return it
   444  	value, dirty := self.dirtyStorage[key]
   445  	if dirty {
   446  		return value
   447  	}
   448  	// Otherwise return the entry's original value
   449  	return self.GetCommittedState(db, key)
   450  }
   451  
   452  // GetCommittedState retrieves a value from the committed account storage trie.
   453  func (self *stateObject) GetCommittedState(db Database, key common.Hash) common.Hash {
   454  	// If we have the original value cached, return that
   455  	value, cached := self.originStorage[key]
   456  	if cached {
   457  		return value
   458  	}
   459  	// Otherwise load the value from the database
   460  	enc, err := self.getTrie(db).TryGet(key[:])
   461  	if err != nil {
   462  		self.setError(err)
   463  		return common.Hash{}
   464  	}
   465  	if len(enc) > 0 {
   466  		_, content, _, err := rlp.Split(enc)
   467  		if err != nil {
   468  			self.setError(err)
   469  		}
   470  		value.SetBytes(content)
   471  	}
   472  	self.originStorage[key] = value
   473  	return value
   474  }
   475  
   476  // SetState updates a value in account storage.
   477  func (self *stateObject) SetState(db Database, key, value common.Hash) {
   478  	self.db.journal = append(self.db.journal, storageChange{
   479  		account:  &self.address,
   480  		key:      key,
   481  		prevalue: self.GetState(db, key),
   482  	})
   483  	self.setState(key, value)
   484  }
   485  
   486  func (self *stateObject) setState(key, value common.Hash) {
   487  	self.dirtyStorage[key] = value
   488  
   489  	if self.onDirty != nil {
   490  		self.onDirty(self.Address())
   491  		self.onDirty = nil
   492  	}
   493  }
   494  
   495  // updateTrie writes cached storage modifications into the object's storage trie.
   496  func (self *stateObject) updateTrie(db Database) Trie {
   497  	tr := self.getTrie(db)
   498  	for key, value := range self.dirtyStorage {
   499  		delete(self.dirtyStorage, key)
   500  
   501  		// Skip noop changes, persist actual changes
   502  		if value == self.originStorage[key] {
   503  			continue
   504  		}
   505  		self.originStorage[key] = value
   506  
   507  		if (value == common.Hash{}) {
   508  			self.setError(tr.TryDelete(key[:]))
   509  			continue
   510  		}
   511  		// Encoding []byte cannot fail, ok to ignore the error.
   512  		v, _ := rlp.EncodeToBytes(bytes.TrimLeft(value[:], "\x00"))
   513  		self.setError(tr.TryUpdate(key[:], v))
   514  	}
   515  	return tr
   516  }
   517  
   518  // UpdateRoot sets the trie root to the current root hash of
   519  func (self *stateObject) updateRoot(db Database) {
   520  	self.updateTrie(db)
   521  	self.data.Root = self.trie.Hash()
   522  }
   523  
   524  // CommitTrie the storage trie of the object to dwb.
   525  // This updates the trie root.
   526  func (self *stateObject) CommitTrie(db Database) error {
   527  	self.updateTrie(db)
   528  	if self.dbErr != nil {
   529  		return self.dbErr
   530  	}
   531  	root, err := self.trie.Commit(nil)
   532  	if err == nil {
   533  		self.data.Root = root
   534  	}
   535  	return err
   536  }
   537  
   538  // AddBalance removes amount from c's balance.
   539  // It is used to add funds to the destination account of a transfer.
   540  func (c *stateObject) AddBalance(amount *big.Int) {
   541  	// EIP158: We must check emptiness for the objects such that the account
   542  	// clearing (0,0,0 objects) can take effect.
   543  	if amount.Sign() == 0 {
   544  		if c.empty() {
   545  			c.touch()
   546  		}
   547  
   548  		return
   549  	}
   550  	c.SetBalance(new(big.Int).Add(c.Balance(), amount))
   551  }
   552  
   553  // SubBalance removes amount from c's balance.
   554  // It is used to remove funds from the origin account of a transfer.
   555  func (c *stateObject) SubBalance(amount *big.Int) {
   556  	if amount.Sign() == 0 {
   557  		return
   558  	}
   559  	c.SetBalance(new(big.Int).Sub(c.Balance(), amount))
   560  }
   561  
   562  func (self *stateObject) SetBalance(amount *big.Int) {
   563  	self.db.journal = append(self.db.journal, balanceChange{
   564  		account: &self.address,
   565  		prev:    new(big.Int).Set(self.data.Balance),
   566  	})
   567  	self.setBalance(amount)
   568  }
   569  
   570  func (self *stateObject) setBalance(amount *big.Int) {
   571  	self.data.Balance = amount
   572  	if self.onDirty != nil {
   573  		self.onDirty(self.Address())
   574  		self.onDirty = nil
   575  	}
   576  }
   577  
   578  // Return the gas back to the origin. Used by the Virtual machine or Closures
   579  func (c *stateObject) ReturnGas(gas *big.Int) {}
   580  
   581  func (self *stateObject) deepCopy(db *StateDB, onDirty func(addr common.Address)) *stateObject {
   582  	stateObject := newObject(db, self.address, self.data, onDirty)
   583  	if self.trie != nil {
   584  		stateObject.trie = db.db.CopyTrie(self.trie)
   585  	}
   586  	if self.tx1Trie != nil {
   587  		stateObject.tx1Trie = db.db.CopyTrie(self.tx1Trie)
   588  	}
   589  	if self.tx3Trie != nil {
   590  		stateObject.tx3Trie = db.db.CopyTrie(self.tx3Trie)
   591  	}
   592  	if self.proxiedTrie != nil {
   593  		stateObject.proxiedTrie = db.db.CopyTrie(self.proxiedTrie)
   594  	}
   595  	if self.rewardTrie != nil {
   596  		stateObject.rewardTrie = db.db.CopyTrie(self.rewardTrie)
   597  	}
   598  	stateObject.code = self.code
   599  	stateObject.dirtyStorage = self.dirtyStorage.Copy()
   600  	stateObject.originStorage = self.originStorage.Copy()
   601  	stateObject.suicided = self.suicided
   602  	stateObject.dirtyCode = self.dirtyCode
   603  	stateObject.deleted = self.deleted
   604  	stateObject.dirtyTX1 = make(map[common.Hash]struct{})
   605  	for tx1 := range self.dirtyTX1 {
   606  		stateObject.dirtyTX1[tx1] = struct{}{}
   607  	}
   608  	stateObject.dirtyTX3 = make(map[common.Hash]struct{})
   609  	for tx3 := range self.dirtyTX3 {
   610  		stateObject.dirtyTX3[tx3] = struct{}{}
   611  	}
   612  	stateObject.dirtyProxied = self.dirtyProxied.Copy()
   613  	stateObject.originProxied = self.originProxied.Copy()
   614  	stateObject.dirtyReward = self.dirtyReward.Copy()
   615  	stateObject.originReward = self.originReward.Copy()
   616  	return stateObject
   617  }
   618  
   619  //
   620  // Attribute accessors
   621  //
   622  
   623  // Returns the address of the contract/account
   624  func (c *stateObject) Address() common.Address {
   625  	return c.address
   626  }
   627  
   628  // Code returns the contract code associated with this object, if any.
   629  func (self *stateObject) Code(db Database) []byte {
   630  	if self.code != nil {
   631  		return self.code
   632  	}
   633  	if bytes.Equal(self.CodeHash(), emptyCodeHash) {
   634  		return nil
   635  	}
   636  	code, err := db.ContractCode(self.addrHash, common.BytesToHash(self.CodeHash()))
   637  	if err != nil {
   638  		self.setError(fmt.Errorf("can't load code hash %x: %v", self.CodeHash(), err))
   639  	}
   640  	self.code = code
   641  	return code
   642  }
   643  
   644  func (self *stateObject) SetCode(codeHash common.Hash, code []byte) {
   645  	prevcode := self.Code(self.db.db)
   646  	self.db.journal = append(self.db.journal, codeChange{
   647  		account:  &self.address,
   648  		prevhash: self.CodeHash(),
   649  		prevcode: prevcode,
   650  	})
   651  	self.setCode(codeHash, code)
   652  }
   653  
   654  func (self *stateObject) setCode(codeHash common.Hash, code []byte) {
   655  	self.code = code
   656  	self.data.CodeHash = codeHash[:]
   657  	self.dirtyCode = true
   658  	if self.onDirty != nil {
   659  		self.onDirty(self.Address())
   660  		self.onDirty = nil
   661  	}
   662  }
   663  
   664  func (self *stateObject) SetNonce(nonce uint64) {
   665  	self.db.journal = append(self.db.journal, nonceChange{
   666  		account: &self.address,
   667  		prev:    self.data.Nonce,
   668  	})
   669  	self.setNonce(nonce)
   670  }
   671  
   672  func (self *stateObject) setNonce(nonce uint64) {
   673  	self.data.Nonce = nonce
   674  	if self.onDirty != nil {
   675  		self.onDirty(self.Address())
   676  		self.onDirty = nil
   677  	}
   678  }
   679  
   680  func (self *stateObject) CodeHash() []byte {
   681  	return self.data.CodeHash
   682  }
   683  
   684  func (self *stateObject) Balance() *big.Int {
   685  	return self.data.Balance
   686  }
   687  
   688  func (self *stateObject) Nonce() uint64 {
   689  	return self.data.Nonce
   690  }
   691  
   692  // Never called, but must be present to allow stateObject to be used
   693  // as a vm.Account interface that also satisfies the vm.ContractRef
   694  // interface. Interfaces are awesome.
   695  func (self *stateObject) Value() *big.Int {
   696  	panic("Value on stateObject should never be called")
   697  }
   698  
   699  func (self *stateObject) SetAddress(address common.Address) {
   700  	self.db.journal = append(self.db.journal, fAddressChange{
   701  		account: &self.address,
   702  		prev:    self.data.FAddress,
   703  	})
   704  
   705  	self.setAddress(address)
   706  }
   707  
   708  func (self *stateObject) setAddress(address common.Address) {
   709  	self.data.FAddress = address
   710  	if self.onDirty != nil {
   711  		self.onDirty(self.Address())
   712  		self.onDirty = nil
   713  	}
   714  }
   715  
   716  func (self *stateObject) GetAddress() common.Address {
   717  	return self.data.FAddress
   718  }