github.com/Gessiux/neatchain@v1.3.1/chain/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/Gessiux/neatchain/utilities/common"
    26  	"github.com/Gessiux/neatchain/utilities/crypto"
    27  	"github.com/Gessiux/neatchain/utilities/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 Ethereum 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 ethereum 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.SideChainDepositBalance) == 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 && s.data.AvailableRewardBalance.Sign() == 0
   112  }
   113  
   114  // Account is the Ethereum 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  	SideChainDepositBalance []*sideChainDepositBalance // only valid in main chain for side chain validator before side chain launch, can not be consumed
   121  	ChainBalance            *big.Int                   // only valid in main chain for side 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  
   141  	// Reward
   142  	RewardBalance          *big.Int    // the accumulative reward balance for this account
   143  	AvailableRewardBalance *big.Int    // the available reward balance for this account
   144  	RewardRoot             common.Hash // merkle root of the Reward trie
   145  
   146  }
   147  
   148  // newObject creates a state object.
   149  func newObject(db *StateDB, address common.Address, data Account, onDirty func(addr common.Address)) *stateObject {
   150  	if data.Balance == nil {
   151  		data.Balance = new(big.Int)
   152  	}
   153  	if data.DepositBalance == nil {
   154  		data.DepositBalance = new(big.Int)
   155  	}
   156  	if data.ChainBalance == nil {
   157  		data.ChainBalance = new(big.Int)
   158  	}
   159  	// init delegate balance
   160  	if data.DelegateBalance == nil {
   161  		data.DelegateBalance = new(big.Int)
   162  	}
   163  	if data.ProxiedBalance == nil {
   164  		data.ProxiedBalance = new(big.Int)
   165  	}
   166  	if data.DepositProxiedBalance == nil {
   167  		data.DepositProxiedBalance = new(big.Int)
   168  	}
   169  	if data.PendingRefundBalance == nil {
   170  		data.PendingRefundBalance = new(big.Int)
   171  	}
   172  	// init reward balance
   173  	if data.RewardBalance == nil {
   174  		data.RewardBalance = new(big.Int)
   175  	}
   176  
   177  	if data.AvailableRewardBalance == nil {
   178  		data.AvailableRewardBalance = new(big.Int)
   179  	}
   180  
   181  	if data.BlockTime == nil {
   182  		data.BlockTime = new(big.Int)
   183  	}
   184  
   185  	if data.ForbiddenTime == nil {
   186  		data.ForbiddenTime = new(big.Int)
   187  	}
   188  
   189  	if data.CodeHash == nil {
   190  		data.CodeHash = emptyCodeHash
   191  	}
   192  	return &stateObject{
   193  		db:            db,
   194  		address:       address,
   195  		addrHash:      crypto.Keccak256Hash(address[:]),
   196  		data:          data,
   197  		originStorage: make(Storage),
   198  		dirtyStorage:  make(Storage),
   199  		dirtyTX1:      make(map[common.Hash]struct{}),
   200  		dirtyTX3:      make(map[common.Hash]struct{}),
   201  		originProxied: make(Proxied),
   202  		dirtyProxied:  make(Proxied),
   203  		originReward:  make(Reward),
   204  		dirtyReward:   make(Reward),
   205  		onDirty:       onDirty,
   206  	}
   207  }
   208  
   209  // EncodeRLP implements rlp.Encoder.
   210  func (c *stateObject) EncodeRLP(w io.Writer) error {
   211  	return rlp.Encode(w, c.data)
   212  }
   213  
   214  // setError remembers the first non-nil error it is called with.
   215  func (self *stateObject) setError(err error) {
   216  	if self.dbErr == nil {
   217  		self.dbErr = err
   218  	}
   219  }
   220  
   221  func (self *stateObject) markSuicided() {
   222  	self.suicided = true
   223  	if self.onDirty != nil {
   224  		self.onDirty(self.Address())
   225  		self.onDirty = nil
   226  	}
   227  }
   228  
   229  func (c *stateObject) touch() {
   230  	c.db.journal = append(c.db.journal, touchChange{
   231  		account:   &c.address,
   232  		prev:      c.touched,
   233  		prevDirty: c.onDirty == nil,
   234  	})
   235  	if c.onDirty != nil {
   236  		c.onDirty(c.Address())
   237  		c.onDirty = nil
   238  	}
   239  	c.touched = true
   240  }
   241  
   242  func (c *stateObject) getTX1Trie(db Database) Trie {
   243  	if c.tx1Trie == nil {
   244  		var err error
   245  		c.tx1Trie, err = db.OpenTX1Trie(c.addrHash, c.data.TX1Root)
   246  		if err != nil {
   247  			c.tx1Trie, _ = db.OpenTX1Trie(c.addrHash, common.Hash{})
   248  			c.setError(fmt.Errorf("can't create TX1 trie: %v", err))
   249  		}
   250  	}
   251  	return c.tx1Trie
   252  }
   253  
   254  // HasTX1 returns true if tx1 is in account TX1 trie.
   255  func (self *stateObject) HasTX1(db Database, txHash common.Hash) bool {
   256  	// check the dirtyTX1 firstly.
   257  	_, ok := self.dirtyTX1[txHash]
   258  	if ok {
   259  		return true
   260  	}
   261  
   262  	// Load from DB in case it is missing.
   263  	enc, err := self.getTX1Trie(db).TryGet(txHash[:])
   264  	if err != nil {
   265  		return false
   266  	}
   267  	if len(enc) > 0 {
   268  		_, content, _, err := rlp.Split(enc)
   269  		if err != nil {
   270  			self.setError(err)
   271  			return false
   272  		}
   273  		if !bytes.Equal(content, txHash[:]) {
   274  			self.setError(fmt.Errorf("content mismatch the tx hash"))
   275  			return false
   276  		}
   277  
   278  		return true
   279  	}
   280  
   281  	return false
   282  }
   283  
   284  // AddTX1 adds a tx1 in account tx1 trie.
   285  func (self *stateObject) AddTX1(db Database, txHash common.Hash) {
   286  	self.db.journal = append(self.db.journal, addTX1Change{
   287  		account: &self.address,
   288  		txHash:  txHash,
   289  	})
   290  	self.addTX1(txHash)
   291  }
   292  
   293  func (self *stateObject) addTX1(txHash common.Hash) {
   294  	self.dirtyTX1[txHash] = struct{}{}
   295  }
   296  
   297  func (self *stateObject) removeTX1(txHash common.Hash) {
   298  	delete(self.dirtyTX1, txHash)
   299  }
   300  
   301  // updateTX1Trie writes cached tx1 modifications into the object's tx1 trie.
   302  func (self *stateObject) updateTX1Trie(db Database) Trie {
   303  	tr := self.getTX1Trie(db)
   304  
   305  	for tx1 := range self.dirtyTX1 {
   306  		delete(self.dirtyTX1, tx1)
   307  
   308  		// Encoding []byte cannot fail, ok to ignore the error.
   309  		v, _ := rlp.EncodeToBytes(bytes.TrimLeft(tx1[:], "\x00"))
   310  		self.setError(tr.TryUpdate(tx1[:], v))
   311  	}
   312  	return tr
   313  }
   314  
   315  // updateTX1Root sets the trie root to the current root hash
   316  func (self *stateObject) updateTX1Root(db Database) {
   317  	self.updateTX1Trie(db)
   318  	self.data.TX1Root = self.tx1Trie.Hash()
   319  }
   320  
   321  // CommitTX1Trie the tx1 trie of the object to dwb.
   322  // This updates the trie root.
   323  func (self *stateObject) CommitTX1Trie(db Database) error {
   324  	self.updateTX1Trie(db)
   325  	if self.dbErr != nil {
   326  		return self.dbErr
   327  	}
   328  	root, err := self.tx1Trie.Commit(nil)
   329  	if err == nil {
   330  		self.data.TX1Root = root
   331  	}
   332  	return err
   333  }
   334  
   335  func (c *stateObject) getTX3Trie(db Database) Trie {
   336  	if c.tx3Trie == nil {
   337  		var err error
   338  		c.tx3Trie, err = db.OpenTX3Trie(c.addrHash, c.data.TX3Root)
   339  		if err != nil {
   340  			c.tx3Trie, _ = db.OpenTX3Trie(c.addrHash, common.Hash{})
   341  			c.setError(fmt.Errorf("can't create TX3 trie: %v", err))
   342  		}
   343  	}
   344  	return c.tx3Trie
   345  }
   346  
   347  // HasTX3 returns true if tx3 is in account TX3 trie.
   348  func (self *stateObject) HasTX3(db Database, txHash common.Hash) bool {
   349  	// check the dirtyTX3 firstly.
   350  	_, ok := self.dirtyTX3[txHash]
   351  	if ok {
   352  		return true
   353  	}
   354  
   355  	// Load from DB in case it is missing.
   356  	enc, err := self.getTX3Trie(db).TryGet(txHash[:])
   357  	if err != nil {
   358  		return false
   359  	}
   360  	if len(enc) > 0 {
   361  		_, content, _, err := rlp.Split(enc)
   362  		if err != nil {
   363  			self.setError(err)
   364  			return false
   365  		}
   366  		if !bytes.Equal(content, txHash[:]) {
   367  			self.setError(fmt.Errorf("content mismatch the tx hash"))
   368  			return false
   369  		}
   370  
   371  		return true
   372  	}
   373  
   374  	return false
   375  }
   376  
   377  // AddTX3 adds a tx3 in account tx3 trie.
   378  func (self *stateObject) AddTX3(db Database, txHash common.Hash) {
   379  	self.db.journal = append(self.db.journal, addTX3Change{
   380  		account: &self.address,
   381  		txHash:  txHash,
   382  	})
   383  	self.addTX3(txHash)
   384  }
   385  
   386  func (self *stateObject) addTX3(txHash common.Hash) {
   387  	self.dirtyTX3[txHash] = struct{}{}
   388  }
   389  
   390  func (self *stateObject) removeTX3(txHash common.Hash) {
   391  	delete(self.dirtyTX3, txHash)
   392  }
   393  
   394  // updateTX3Trie writes cached tx3 modifications into the object's tx3 trie.
   395  func (self *stateObject) updateTX3Trie(db Database) Trie {
   396  	tr := self.getTX3Trie(db)
   397  
   398  	for tx3 := range self.dirtyTX3 {
   399  		delete(self.dirtyTX3, tx3)
   400  
   401  		// Encoding []byte cannot fail, ok to ignore the error.
   402  		v, _ := rlp.EncodeToBytes(bytes.TrimLeft(tx3[:], "\x00"))
   403  		self.setError(tr.TryUpdate(tx3[:], v))
   404  	}
   405  	return tr
   406  }
   407  
   408  // updateTX3Root sets the trie root to the current root hash
   409  func (self *stateObject) updateTX3Root(db Database) {
   410  	self.updateTX3Trie(db)
   411  	self.data.TX3Root = self.tx3Trie.Hash()
   412  }
   413  
   414  // CommitTX3Trie the tx3 trie of the object to dwb.
   415  // This updates the trie root.
   416  func (self *stateObject) CommitTX3Trie(db Database) error {
   417  	self.updateTX3Trie(db)
   418  	if self.dbErr != nil {
   419  		return self.dbErr
   420  	}
   421  	root, err := self.tx3Trie.Commit(nil)
   422  	if err == nil {
   423  		self.data.TX3Root = root
   424  	}
   425  	return err
   426  }
   427  
   428  func (c *stateObject) getTrie(db Database) Trie {
   429  	if c.trie == nil {
   430  		var err error
   431  		c.trie, err = db.OpenStorageTrie(c.addrHash, c.data.Root)
   432  		if err != nil {
   433  			c.trie, _ = db.OpenStorageTrie(c.addrHash, common.Hash{})
   434  			c.setError(fmt.Errorf("can't create storage trie: %v", err))
   435  		}
   436  	}
   437  	return c.trie
   438  }
   439  
   440  // GetState returns a value in account storage.
   441  func (self *stateObject) GetState(db Database, key common.Hash) common.Hash {
   442  	// If we have a dirty value for this state entry, return it
   443  	value, dirty := self.dirtyStorage[key]
   444  	if dirty {
   445  		return value
   446  	}
   447  	// Otherwise return the entry's original value
   448  	return self.GetCommittedState(db, key)
   449  }
   450  
   451  // GetCommittedState retrieves a value from the committed account storage trie.
   452  func (self *stateObject) GetCommittedState(db Database, key common.Hash) common.Hash {
   453  	// If we have the original value cached, return that
   454  	value, cached := self.originStorage[key]
   455  	if cached {
   456  		return value
   457  	}
   458  	// Otherwise load the value from the database
   459  	enc, err := self.getTrie(db).TryGet(key[:])
   460  	if err != nil {
   461  		self.setError(err)
   462  		return common.Hash{}
   463  	}
   464  	if len(enc) > 0 {
   465  		_, content, _, err := rlp.Split(enc)
   466  		if err != nil {
   467  			self.setError(err)
   468  		}
   469  		value.SetBytes(content)
   470  	}
   471  	self.originStorage[key] = value
   472  	return value
   473  }
   474  
   475  // SetState updates a value in account storage.
   476  func (self *stateObject) SetState(db Database, key, value common.Hash) {
   477  	self.db.journal = append(self.db.journal, storageChange{
   478  		account:  &self.address,
   479  		key:      key,
   480  		prevalue: self.GetState(db, key),
   481  	})
   482  	self.setState(key, value)
   483  }
   484  
   485  func (self *stateObject) setState(key, value common.Hash) {
   486  	self.dirtyStorage[key] = value
   487  
   488  	if self.onDirty != nil {
   489  		self.onDirty(self.Address())
   490  		self.onDirty = nil
   491  	}
   492  }
   493  
   494  // updateTrie writes cached storage modifications into the object's storage trie.
   495  func (self *stateObject) updateTrie(db Database) Trie {
   496  	tr := self.getTrie(db)
   497  	for key, value := range self.dirtyStorage {
   498  		delete(self.dirtyStorage, key)
   499  
   500  		// Skip noop changes, persist actual changes
   501  		if value == self.originStorage[key] {
   502  			continue
   503  		}
   504  		self.originStorage[key] = value
   505  
   506  		if (value == common.Hash{}) {
   507  			self.setError(tr.TryDelete(key[:]))
   508  			continue
   509  		}
   510  		// Encoding []byte cannot fail, ok to ignore the error.
   511  		v, _ := rlp.EncodeToBytes(bytes.TrimLeft(value[:], "\x00"))
   512  		self.setError(tr.TryUpdate(key[:], v))
   513  	}
   514  	return tr
   515  }
   516  
   517  // UpdateRoot sets the trie root to the current root hash of
   518  func (self *stateObject) updateRoot(db Database) {
   519  	self.updateTrie(db)
   520  	self.data.Root = self.trie.Hash()
   521  }
   522  
   523  // CommitTrie the storage trie of the object to dwb.
   524  // This updates the trie root.
   525  func (self *stateObject) CommitTrie(db Database) error {
   526  	self.updateTrie(db)
   527  	if self.dbErr != nil {
   528  		return self.dbErr
   529  	}
   530  	root, err := self.trie.Commit(nil)
   531  	if err == nil {
   532  		self.data.Root = root
   533  	}
   534  	return err
   535  }
   536  
   537  // AddBalance removes amount from c's balance.
   538  // It is used to add funds to the destination account of a transfer.
   539  func (c *stateObject) AddBalance(amount *big.Int) {
   540  	// EIP158: We must check emptiness for the objects such that the account
   541  	// clearing (0,0,0 objects) can take effect.
   542  	if amount.Sign() == 0 {
   543  		if c.empty() {
   544  			c.touch()
   545  		}
   546  
   547  		return
   548  	}
   549  	c.SetBalance(new(big.Int).Add(c.Balance(), amount))
   550  }
   551  
   552  // SubBalance removes amount from c's balance.
   553  // It is used to remove funds from the origin account of a transfer.
   554  func (c *stateObject) SubBalance(amount *big.Int) {
   555  	if amount.Sign() == 0 {
   556  		return
   557  	}
   558  	c.SetBalance(new(big.Int).Sub(c.Balance(), amount))
   559  }
   560  
   561  func (self *stateObject) SetBalance(amount *big.Int) {
   562  	self.db.journal = append(self.db.journal, balanceChange{
   563  		account: &self.address,
   564  		prev:    new(big.Int).Set(self.data.Balance),
   565  	})
   566  	self.setBalance(amount)
   567  }
   568  
   569  func (self *stateObject) setBalance(amount *big.Int) {
   570  	self.data.Balance = amount
   571  	if self.onDirty != nil {
   572  		self.onDirty(self.Address())
   573  		self.onDirty = nil
   574  	}
   575  }
   576  
   577  // Return the gas back to the origin. Used by the Virtual machine or Closures
   578  func (c *stateObject) ReturnGas(gas *big.Int) {}
   579  
   580  func (self *stateObject) deepCopy(db *StateDB, onDirty func(addr common.Address)) *stateObject {
   581  	stateObject := newObject(db, self.address, self.data, onDirty)
   582  	if self.trie != nil {
   583  		stateObject.trie = db.db.CopyTrie(self.trie)
   584  	}
   585  	if self.tx1Trie != nil {
   586  		stateObject.tx1Trie = db.db.CopyTrie(self.tx1Trie)
   587  	}
   588  	if self.tx3Trie != nil {
   589  		stateObject.tx3Trie = db.db.CopyTrie(self.tx3Trie)
   590  	}
   591  	if self.proxiedTrie != nil {
   592  		stateObject.proxiedTrie = db.db.CopyTrie(self.proxiedTrie)
   593  	}
   594  	if self.rewardTrie != nil {
   595  		stateObject.rewardTrie = db.db.CopyTrie(self.rewardTrie)
   596  	}
   597  	stateObject.code = self.code
   598  	stateObject.dirtyStorage = self.dirtyStorage.Copy()
   599  	stateObject.originStorage = self.originStorage.Copy()
   600  	stateObject.suicided = self.suicided
   601  	stateObject.dirtyCode = self.dirtyCode
   602  	stateObject.deleted = self.deleted
   603  	stateObject.dirtyTX1 = make(map[common.Hash]struct{})
   604  	for tx1 := range self.dirtyTX1 {
   605  		stateObject.dirtyTX1[tx1] = struct{}{}
   606  	}
   607  	stateObject.dirtyTX3 = make(map[common.Hash]struct{})
   608  	for tx3 := range self.dirtyTX3 {
   609  		stateObject.dirtyTX3[tx3] = struct{}{}
   610  	}
   611  	stateObject.dirtyProxied = self.dirtyProxied.Copy()
   612  	stateObject.originProxied = self.originProxied.Copy()
   613  	stateObject.dirtyReward = self.dirtyReward.Copy()
   614  	stateObject.originReward = self.originReward.Copy()
   615  	return stateObject
   616  }
   617  
   618  //
   619  // Attribute accessors
   620  //
   621  
   622  // Returns the address of the contract/account
   623  func (c *stateObject) Address() common.Address {
   624  	return c.address
   625  }
   626  
   627  // Code returns the contract code associated with this object, if any.
   628  func (self *stateObject) Code(db Database) []byte {
   629  	if self.code != nil {
   630  		return self.code
   631  	}
   632  	if bytes.Equal(self.CodeHash(), emptyCodeHash) {
   633  		return nil
   634  	}
   635  	code, err := db.ContractCode(self.addrHash, common.BytesToHash(self.CodeHash()))
   636  	if err != nil {
   637  		self.setError(fmt.Errorf("can't load code hash %x: %v", self.CodeHash(), err))
   638  	}
   639  	self.code = code
   640  	return code
   641  }
   642  
   643  func (self *stateObject) SetCode(codeHash common.Hash, code []byte) {
   644  	prevcode := self.Code(self.db.db)
   645  	self.db.journal = append(self.db.journal, codeChange{
   646  		account:  &self.address,
   647  		prevhash: self.CodeHash(),
   648  		prevcode: prevcode,
   649  	})
   650  	self.setCode(codeHash, code)
   651  }
   652  
   653  func (self *stateObject) setCode(codeHash common.Hash, code []byte) {
   654  	self.code = code
   655  	self.data.CodeHash = codeHash[:]
   656  	self.dirtyCode = true
   657  	if self.onDirty != nil {
   658  		self.onDirty(self.Address())
   659  		self.onDirty = nil
   660  	}
   661  }
   662  
   663  func (self *stateObject) SetNonce(nonce uint64) {
   664  	self.db.journal = append(self.db.journal, nonceChange{
   665  		account: &self.address,
   666  		prev:    self.data.Nonce,
   667  	})
   668  	self.setNonce(nonce)
   669  }
   670  
   671  func (self *stateObject) setNonce(nonce uint64) {
   672  	self.data.Nonce = nonce
   673  	if self.onDirty != nil {
   674  		self.onDirty(self.Address())
   675  		self.onDirty = nil
   676  	}
   677  }
   678  
   679  func (self *stateObject) CodeHash() []byte {
   680  	return self.data.CodeHash
   681  }
   682  
   683  func (self *stateObject) Balance() *big.Int {
   684  	return self.data.Balance
   685  }
   686  
   687  func (self *stateObject) Nonce() uint64 {
   688  	return self.data.Nonce
   689  }
   690  
   691  // Never called, but must be present to allow stateObject to be used
   692  // as a vm.Account interface that also satisfies the vm.ContractRef
   693  // interface. Interfaces are awesome.
   694  func (self *stateObject) Value() *big.Int {
   695  	panic("Value on stateObject should never be called")
   696  }