github.com/linapex/ethereum-go-chinese@v0.0.0-20190316121929-f8b7a73c3fa1/core/state/statedb.go (about)

     1  
     2  //<developer>
     3  //    <name>linapex 曹一峰</name>
     4  //    <email>linapex@163.com</email>
     5  //    <wx>superexc</wx>
     6  //    <qqgroup>128148617</qqgroup>
     7  //    <url>https://jsq.ink</url>
     8  //    <role>pku engineer</role>
     9  //    <date>2019-03-16 19:16:35</date>
    10  //</624450080241356800>
    11  
    12  
    13  //包状态在以太坊状态trie上提供一个缓存层。
    14  package state
    15  
    16  import (
    17  	"errors"
    18  	"fmt"
    19  	"math/big"
    20  	"sort"
    21  
    22  	"github.com/ethereum/go-ethereum/common"
    23  	"github.com/ethereum/go-ethereum/core/types"
    24  	"github.com/ethereum/go-ethereum/crypto"
    25  	"github.com/ethereum/go-ethereum/log"
    26  	"github.com/ethereum/go-ethereum/rlp"
    27  	"github.com/ethereum/go-ethereum/trie"
    28  )
    29  
    30  type revision struct {
    31  	id           int
    32  	journalIndex int
    33  }
    34  
    35  var (
    36  //EmptyState是空状态trie项的已知哈希。
    37  	emptyState = crypto.Keccak256Hash(nil)
    38  
    39  //emptycode是空EVM字节码的已知哈希。
    40  	emptyCode = crypto.Keccak256Hash(nil)
    41  )
    42  
    43  type proofList [][]byte
    44  
    45  func (n *proofList) Put(key []byte, value []byte) error {
    46  	*n = append(*n, value)
    47  	return nil
    48  }
    49  
    50  //以太坊协议中的statedbs用于存储任何内容
    51  //在梅克尔特里亚。statedbs负责缓存和存储
    52  //嵌套状态。它是要检索的常规查询接口:
    53  //*合同
    54  //*帐户
    55  type StateDB struct {
    56  	db   Database
    57  	trie Trie
    58  
    59  //此映射包含“活动”对象,在处理状态转换时将对其进行修改。
    60  	stateObjects      map[common.Address]*stateObject
    61  	stateObjectsDirty map[common.Address]struct{}
    62  
    63  //数据库错误。
    64  //状态对象由共识核心和虚拟机使用,它们是
    65  //无法处理数据库级错误。发生的任何错误
    66  //在数据库读取过程中,将在此处记忆并最终返回
    67  //按statedb.commit。
    68  	dbErr error
    69  
    70  //The refund counter, also used by state transitioning.
    71  	refund uint64
    72  
    73  	thash, bhash common.Hash
    74  	txIndex      int
    75  	logs         map[common.Hash][]*types.Log
    76  	logSize      uint
    77  
    78  	preimages map[common.Hash][]byte
    79  
    80  //国家修改杂志。这是
    81  //快照并还原为快照。
    82  	journal        *journal
    83  	validRevisions []revision
    84  	nextRevisionId int
    85  }
    86  
    87  //从给定的trie创建新状态。
    88  func New(root common.Hash, db Database) (*StateDB, error) {
    89  	tr, err := db.OpenTrie(root)
    90  	if err != nil {
    91  		return nil, err
    92  	}
    93  	return &StateDB{
    94  		db:                db,
    95  		trie:              tr,
    96  		stateObjects:      make(map[common.Address]*stateObject),
    97  		stateObjectsDirty: make(map[common.Address]struct{}),
    98  		logs:              make(map[common.Hash][]*types.Log),
    99  		preimages:         make(map[common.Hash][]byte),
   100  		journal:           newJournal(),
   101  	}, nil
   102  }
   103  
   104  //setError remembers the first non-nil error it is called with.
   105  func (self *StateDB) setError(err error) {
   106  	if self.dbErr == nil {
   107  		self.dbErr = err
   108  	}
   109  }
   110  
   111  func (self *StateDB) Error() error {
   112  	return self.dbErr
   113  }
   114  
   115  //重置从状态数据库中清除所有短暂状态对象,但保留
   116  //基础状态将尝试避免为下一个操作重新加载数据。
   117  func (self *StateDB) Reset(root common.Hash) error {
   118  	tr, err := self.db.OpenTrie(root)
   119  	if err != nil {
   120  		return err
   121  	}
   122  	self.trie = tr
   123  	self.stateObjects = make(map[common.Address]*stateObject)
   124  	self.stateObjectsDirty = make(map[common.Address]struct{})
   125  	self.thash = common.Hash{}
   126  	self.bhash = common.Hash{}
   127  	self.txIndex = 0
   128  	self.logs = make(map[common.Hash][]*types.Log)
   129  	self.logSize = 0
   130  	self.preimages = make(map[common.Hash][]byte)
   131  	self.clearJournalAndRefund()
   132  	return nil
   133  }
   134  
   135  func (self *StateDB) AddLog(log *types.Log) {
   136  	self.journal.append(addLogChange{txhash: self.thash})
   137  
   138  	log.TxHash = self.thash
   139  	log.BlockHash = self.bhash
   140  	log.TxIndex = uint(self.txIndex)
   141  	log.Index = self.logSize
   142  	self.logs[self.thash] = append(self.logs[self.thash], log)
   143  	self.logSize++
   144  }
   145  
   146  func (self *StateDB) GetLogs(hash common.Hash) []*types.Log {
   147  	return self.logs[hash]
   148  }
   149  
   150  func (self *StateDB) Logs() []*types.Log {
   151  	var logs []*types.Log
   152  	for _, lgs := range self.logs {
   153  		logs = append(logs, lgs...)
   154  	}
   155  	return logs
   156  }
   157  
   158  //AdvPrimI图记录由VM看到的Sa3预图像。
   159  func (self *StateDB) AddPreimage(hash common.Hash, preimage []byte) {
   160  	if _, ok := self.preimages[hash]; !ok {
   161  		self.journal.append(addPreimageChange{hash: hash})
   162  		pi := make([]byte, len(preimage))
   163  		copy(pi, preimage)
   164  		self.preimages[hash] = pi
   165  	}
   166  }
   167  
   168  //preimages返回已提交的sha3 preimages列表。
   169  func (self *StateDB) Preimages() map[common.Hash][]byte {
   170  	return self.preimages
   171  }
   172  
   173  //添加退款将汽油添加到退款柜台
   174  func (self *StateDB) AddRefund(gas uint64) {
   175  	self.journal.append(refundChange{prev: self.refund})
   176  	self.refund += gas
   177  }
   178  
   179  //从退款柜台取出汽油。
   180  //如果退款计数器低于零,此方法将死机
   181  func (self *StateDB) SubRefund(gas uint64) {
   182  	self.journal.append(refundChange{prev: self.refund})
   183  	if gas > self.refund {
   184  		panic("Refund counter below zero")
   185  	}
   186  	self.refund -= gas
   187  }
   188  
   189  //exist报告给定帐户地址是否存在于状态中。
   190  //值得注意的是,对于自杀账户,这也会返回真值。
   191  func (self *StateDB) Exist(addr common.Address) bool {
   192  	return self.getStateObject(addr) != nil
   193  }
   194  
   195  //空返回状态对象是否不存在
   196  //或根据EIP161规范为空(余额=nonce=代码=0)
   197  func (self *StateDB) Empty(addr common.Address) bool {
   198  	so := self.getStateObject(addr)
   199  	return so == nil || so.empty()
   200  }
   201  
   202  //从给定地址检索余额,如果找不到对象,则检索0
   203  func (self *StateDB) GetBalance(addr common.Address) *big.Int {
   204  	stateObject := self.getStateObject(addr)
   205  	if stateObject != nil {
   206  		return stateObject.Balance()
   207  	}
   208  	return common.Big0
   209  }
   210  
   211  func (self *StateDB) GetNonce(addr common.Address) uint64 {
   212  	stateObject := self.getStateObject(addr)
   213  	if stateObject != nil {
   214  		return stateObject.Nonce()
   215  	}
   216  
   217  	return 0
   218  }
   219  
   220  func (self *StateDB) GetCode(addr common.Address) []byte {
   221  	stateObject := self.getStateObject(addr)
   222  	if stateObject != nil {
   223  		return stateObject.Code(self.db)
   224  	}
   225  	return nil
   226  }
   227  
   228  func (self *StateDB) GetCodeSize(addr common.Address) int {
   229  	stateObject := self.getStateObject(addr)
   230  	if stateObject == nil {
   231  		return 0
   232  	}
   233  	if stateObject.code != nil {
   234  		return len(stateObject.code)
   235  	}
   236  	size, err := self.db.ContractCodeSize(stateObject.addrHash, common.BytesToHash(stateObject.CodeHash()))
   237  	if err != nil {
   238  		self.setError(err)
   239  	}
   240  	return size
   241  }
   242  
   243  func (self *StateDB) GetCodeHash(addr common.Address) common.Hash {
   244  	stateObject := self.getStateObject(addr)
   245  	if stateObject == nil {
   246  		return common.Hash{}
   247  	}
   248  	return common.BytesToHash(stateObject.CodeHash())
   249  }
   250  
   251  //GetState从给定帐户的存储检索值。
   252  func (self *StateDB) GetState(addr common.Address, hash common.Hash) common.Hash {
   253  	stateObject := self.getStateObject(addr)
   254  	if stateObject != nil {
   255  		return stateObject.GetState(self.db, hash)
   256  	}
   257  	return common.Hash{}
   258  }
   259  
   260  //getProof返回给定帐户的merkleproof
   261  func (self *StateDB) GetProof(a common.Address) ([][]byte, error) {
   262  	var proof proofList
   263  	err := self.trie.Prove(crypto.Keccak256(a.Bytes()), 0, &proof)
   264  	return [][]byte(proof), err
   265  }
   266  
   267  //GetProof返回给定密钥的StorageProof
   268  func (self *StateDB) GetStorageProof(a common.Address, key common.Hash) ([][]byte, error) {
   269  	var proof proofList
   270  	trie := self.StorageTrie(a)
   271  	if trie == nil {
   272  		return proof, errors.New("storage trie for requested address does not exist")
   273  	}
   274  	err := trie.Prove(crypto.Keccak256(key.Bytes()), 0, &proof)
   275  	return [][]byte(proof), err
   276  }
   277  
   278  //getcommittedState从给定帐户的已提交存储trie中检索值。
   279  func (self *StateDB) GetCommittedState(addr common.Address, hash common.Hash) common.Hash {
   280  	stateObject := self.getStateObject(addr)
   281  	if stateObject != nil {
   282  		return stateObject.GetCommittedState(self.db, hash)
   283  	}
   284  	return common.Hash{}
   285  }
   286  
   287  //数据库检索支持低级trie操作的低级数据库。
   288  func (self *StateDB) Database() Database {
   289  	return self.db
   290  }
   291  
   292  //storage trie返回帐户的存储trie。
   293  //返回值是副本,对于不存在的帐户为零。
   294  func (self *StateDB) StorageTrie(addr common.Address) Trie {
   295  	stateObject := self.getStateObject(addr)
   296  	if stateObject == nil {
   297  		return nil
   298  	}
   299  	cpy := stateObject.deepCopy(self)
   300  	return cpy.updateTrie(self.db)
   301  }
   302  
   303  func (self *StateDB) HasSuicided(addr common.Address) bool {
   304  	stateObject := self.getStateObject(addr)
   305  	if stateObject != nil {
   306  		return stateObject.suicided
   307  	}
   308  	return false
   309  }
   310  
   311  /*
   312   *设定器
   313   **/
   314  
   315  
   316  //AddBalance adds amount to the account associated with addr.
   317  func (self *StateDB) AddBalance(addr common.Address, amount *big.Int) {
   318  	stateObject := self.GetOrNewStateObject(addr)
   319  	if stateObject != nil {
   320  		stateObject.AddBalance(amount)
   321  	}
   322  }
   323  
   324  //子余额从与addr关联的帐户中减去金额。
   325  func (self *StateDB) SubBalance(addr common.Address, amount *big.Int) {
   326  	stateObject := self.GetOrNewStateObject(addr)
   327  	if stateObject != nil {
   328  		stateObject.SubBalance(amount)
   329  	}
   330  }
   331  
   332  func (self *StateDB) SetBalance(addr common.Address, amount *big.Int) {
   333  	stateObject := self.GetOrNewStateObject(addr)
   334  	if stateObject != nil {
   335  		stateObject.SetBalance(amount)
   336  	}
   337  }
   338  
   339  func (self *StateDB) SetNonce(addr common.Address, nonce uint64) {
   340  	stateObject := self.GetOrNewStateObject(addr)
   341  	if stateObject != nil {
   342  		stateObject.SetNonce(nonce)
   343  	}
   344  }
   345  
   346  func (self *StateDB) SetCode(addr common.Address, code []byte) {
   347  	stateObject := self.GetOrNewStateObject(addr)
   348  	if stateObject != nil {
   349  		stateObject.SetCode(crypto.Keccak256Hash(code), code)
   350  	}
   351  }
   352  
   353  func (self *StateDB) SetState(addr common.Address, key, value common.Hash) {
   354  	stateObject := self.GetOrNewStateObject(addr)
   355  	if stateObject != nil {
   356  		stateObject.SetState(self.db, key, value)
   357  	}
   358  }
   359  
   360  //自杀将指定帐户标记为自杀。
   361  //这将清除帐户余额。
   362  //
   363  //在提交状态之前,帐户的状态对象仍然可用,
   364  //GetStateObject将在自杀后返回非零帐户。
   365  func (self *StateDB) Suicide(addr common.Address) bool {
   366  	stateObject := self.getStateObject(addr)
   367  	if stateObject == nil {
   368  		return false
   369  	}
   370  	self.journal.append(suicideChange{
   371  		account:     &addr,
   372  		prev:        stateObject.suicided,
   373  		prevbalance: new(big.Int).Set(stateObject.Balance()),
   374  	})
   375  	stateObject.markSuicided()
   376  	stateObject.data.Balance = new(big.Int)
   377  
   378  	return true
   379  }
   380  
   381  //
   382  //设置、更新和删除状态对象方法。
   383  //
   384  
   385  //updateStateObject writes the given object to the trie.
   386  func (self *StateDB) updateStateObject(stateObject *stateObject) {
   387  	addr := stateObject.Address()
   388  	data, err := rlp.EncodeToBytes(stateObject)
   389  	if err != nil {
   390  		panic(fmt.Errorf("can't encode object at %x: %v", addr[:], err))
   391  	}
   392  	self.setError(self.trie.TryUpdate(addr[:], data))
   393  }
   394  
   395  //DeleteStateObject从状态trie中删除给定的对象。
   396  func (self *StateDB) deleteStateObject(stateObject *stateObject) {
   397  	stateObject.deleted = true
   398  	addr := stateObject.Address()
   399  	self.setError(self.trie.TryDelete(addr[:]))
   400  }
   401  
   402  //检索由地址给定的状态对象。如果未找到,则返回nil。
   403  func (self *StateDB) getStateObject(addr common.Address) (stateObject *stateObject) {
   404  //喜欢“活”的对象。
   405  	if obj := self.stateObjects[addr]; obj != nil {
   406  		if obj.deleted {
   407  			return nil
   408  		}
   409  		return obj
   410  	}
   411  
   412  //从数据库加载对象。
   413  	enc, err := self.trie.TryGet(addr[:])
   414  	if len(enc) == 0 {
   415  		self.setError(err)
   416  		return nil
   417  	}
   418  	var data Account
   419  	if err := rlp.DecodeBytes(enc, &data); err != nil {
   420  		log.Error("Failed to decode state object", "addr", addr, "err", err)
   421  		return nil
   422  	}
   423  //插入到实况集。
   424  	obj := newObject(self, addr, data)
   425  	self.setStateObject(obj)
   426  	return obj
   427  }
   428  
   429  func (self *StateDB) setStateObject(object *stateObject) {
   430  	self.stateObjects[object.Address()] = object
   431  }
   432  
   433  //检索状态对象或创建新的状态对象(如果为零)。
   434  func (self *StateDB) GetOrNewStateObject(addr common.Address) *stateObject {
   435  	stateObject := self.getStateObject(addr)
   436  	if stateObject == nil || stateObject.deleted {
   437  		stateObject, _ = self.createObject(addr)
   438  	}
   439  	return stateObject
   440  }
   441  
   442  //CreateObject创建新的状态对象。如果有现有帐户
   443  //给定的地址,将被覆盖并作为第二个返回值返回。
   444  func (self *StateDB) createObject(addr common.Address) (newobj, prev *stateObject) {
   445  	prev = self.getStateObject(addr)
   446  	newobj = newObject(self, addr, Account{})
   447  newobj.setNonce(0) //将对象设置为脏
   448  	if prev == nil {
   449  		self.journal.append(createObjectChange{account: &addr})
   450  	} else {
   451  		self.journal.append(resetObjectChange{prev: prev})
   452  	}
   453  	self.setStateObject(newobj)
   454  	return newobj, prev
   455  }
   456  
   457  //CreateCount显式创建状态对象。如果有地址的状态对象
   458  //已存在余额转入新账户。
   459  //
   460  //在EVM创建操作期间调用CreateCount。可能出现的情况是
   461  //合同执行以下操作:
   462  //
   463  //1。将资金发送到sha(account++(nonce+1))。
   464  //2。tx_create(sha(account++nonce))(注意,这会得到1的地址)
   465  //
   466  //保持平衡可确保乙醚不会消失。
   467  func (self *StateDB) CreateAccount(addr common.Address) {
   468  	newObj, prev := self.createObject(addr)
   469  	if prev != nil {
   470  		newObj.setBalance(prev.data.Balance)
   471  	}
   472  }
   473  
   474  func (db *StateDB) ForEachStorage(addr common.Address, cb func(key, value common.Hash) bool) {
   475  	so := db.getStateObject(addr)
   476  	if so == nil {
   477  		return
   478  	}
   479  	it := trie.NewIterator(so.getTrie(db.db).NodeIterator(nil))
   480  	for it.Next() {
   481  		key := common.BytesToHash(db.trie.GetKey(it.Key))
   482  		if value, dirty := so.dirtyStorage[key]; dirty {
   483  			cb(key, value)
   484  			continue
   485  		}
   486  		cb(key, common.BytesToHash(it.Value))
   487  	}
   488  }
   489  
   490  //复制创建状态的深度独立副本。
   491  //复制状态的快照无法应用于该副本。
   492  func (self *StateDB) Copy() *StateDB {
   493  //复制所有基本字段,初始化内存字段
   494  	state := &StateDB{
   495  		db:                self.db,
   496  		trie:              self.db.CopyTrie(self.trie),
   497  		stateObjects:      make(map[common.Address]*stateObject, len(self.journal.dirties)),
   498  		stateObjectsDirty: make(map[common.Address]struct{}, len(self.journal.dirties)),
   499  		refund:            self.refund,
   500  		logs:              make(map[common.Hash][]*types.Log, len(self.logs)),
   501  		logSize:           self.logSize,
   502  		preimages:         make(map[common.Hash][]byte),
   503  		journal:           newJournal(),
   504  	}
   505  //复制脏状态、日志和预映像
   506  	for addr := range self.journal.dirties {
   507  //如文件所述[此处](https://github.com/ethereum/go-ethereum/pull/16485 issuecomment-380438527)
   508  //在定稿方法中,有一种情况是对象在日志中,而不是
   509  //在StateObjects中:oog在拜占庭之前接触到ripemd。因此,我们需要检查
   510  //零
   511  		if object, exist := self.stateObjects[addr]; exist {
   512  			state.stateObjects[addr] = object.deepCopy(state)
   513  			state.stateObjectsDirty[addr] = struct{}{}
   514  		}
   515  	}
   516  //上面,我们不复制实际的日记。这意味着,如果复制副本,
   517  //上面的循环将是无操作,因为副本的日志是空的。
   518  //因此,这里我们迭代StateObjects,以启用副本的副本
   519  	for addr := range self.stateObjectsDirty {
   520  		if _, exist := state.stateObjects[addr]; !exist {
   521  			state.stateObjects[addr] = self.stateObjects[addr].deepCopy(state)
   522  			state.stateObjectsDirty[addr] = struct{}{}
   523  		}
   524  	}
   525  	for hash, logs := range self.logs {
   526  		cpy := make([]*types.Log, len(logs))
   527  		for i, l := range logs {
   528  			cpy[i] = new(types.Log)
   529  			*cpy[i] = *l
   530  		}
   531  		state.logs[hash] = cpy
   532  	}
   533  	for hash, preimage := range self.preimages {
   534  		state.preimages[hash] = preimage
   535  	}
   536  	return state
   537  }
   538  
   539  //Snapshot returns an identifier for the current revision of the state.
   540  func (self *StateDB) Snapshot() int {
   541  	id := self.nextRevisionId
   542  	self.nextRevisionId++
   543  	self.validRevisions = append(self.validRevisions, revision{id, self.journal.length()})
   544  	return id
   545  }
   546  
   547  //RevertToSnapshot恢复自给定修订之后所做的所有状态更改。
   548  func (self *StateDB) RevertToSnapshot(revid int) {
   549  //在有效快照的堆栈中查找快照。
   550  	idx := sort.Search(len(self.validRevisions), func(i int) bool {
   551  		return self.validRevisions[i].id >= revid
   552  	})
   553  	if idx == len(self.validRevisions) || self.validRevisions[idx].id != revid {
   554  		panic(fmt.Errorf("revision id %v cannot be reverted", revid))
   555  	}
   556  	snapshot := self.validRevisions[idx].journalIndex
   557  
   558  //重播日志以撤消更改并删除失效的快照
   559  	self.journal.revert(self, snapshot)
   560  	self.validRevisions = self.validRevisions[:idx]
   561  }
   562  
   563  //GetRefund返回退款计数器的当前值。
   564  func (self *StateDB) GetRefund() uint64 {
   565  	return self.refund
   566  }
   567  
   568  //通过移除自毁对象最终确定状态
   569  //清除日记账和退款。
   570  func (s *StateDB) Finalise(deleteEmptyObjects bool) {
   571  	for addr := range s.journal.dirties {
   572  		stateObject, exist := s.stateObjects[addr]
   573  		if !exist {
   574  //ripemd在德克萨斯州的1714175号区块“接触”,邮编:0x1237F737031E40BCDE4A8B7E717B2D15E3ECADFE49BB1BC71EE9DEB09C6FCF2
   575  //Tx耗尽了气体,尽管“触摸”的概念在那里并不存在,但是
   576  //touch-event will still be recorded in the journal. Since ripeMD is a special snowflake,
   577  //即使日志被还原,它仍将在日志中保留。在这种特殊情况下,
   578  //它可能存在于's.journal.dirties'中,但不存在于's.stateobjects'中。
   579  //因此,我们可以在这里安全地忽略它
   580  			continue
   581  		}
   582  
   583  		if stateObject.suicided || (deleteEmptyObjects && stateObject.empty()) {
   584  			s.deleteStateObject(stateObject)
   585  		} else {
   586  			stateObject.updateRoot(s.db)
   587  			s.updateStateObject(stateObject)
   588  		}
   589  		s.stateObjectsDirty[addr] = struct{}{}
   590  	}
   591  //使日记帐无效,因为不允许跨交易记录还原。
   592  	s.clearJournalAndRefund()
   593  }
   594  
   595  //IntermediateRoot计算状态trie的当前根哈希。
   596  //它在事务之间调用,以获取
   597  //进入交易记录收据。
   598  func (s *StateDB) IntermediateRoot(deleteEmptyObjects bool) common.Hash {
   599  	s.Finalise(deleteEmptyObjects)
   600  	return s.trie.Hash()
   601  }
   602  
   603  //准备设置当前事务哈希、索引和块哈希,即
   604  //在EVM发出新状态日志时使用。
   605  func (self *StateDB) Prepare(thash, bhash common.Hash, ti int) {
   606  	self.thash = thash
   607  	self.bhash = bhash
   608  	self.txIndex = ti
   609  }
   610  
   611  func (s *StateDB) clearJournalAndRefund() {
   612  	s.journal = newJournal()
   613  	s.validRevisions = s.validRevisions[:0]
   614  	s.refund = 0
   615  }
   616  
   617  //commit将状态写入内存中的基础trie数据库。
   618  func (s *StateDB) Commit(deleteEmptyObjects bool) (root common.Hash, err error) {
   619  	defer s.clearJournalAndRefund()
   620  
   621  	for addr := range s.journal.dirties {
   622  		s.stateObjectsDirty[addr] = struct{}{}
   623  	}
   624  //将对象提交到trie。
   625  	for addr, stateObject := range s.stateObjects {
   626  		_, isDirty := s.stateObjectsDirty[addr]
   627  		switch {
   628  		case stateObject.suicided || (isDirty && deleteEmptyObjects && stateObject.empty()):
   629  //如果对象已被删除,请不要麻烦同步它。
   630  //只需在trie中标记为删除即可。
   631  			s.deleteStateObject(stateObject)
   632  		case isDirty:
   633  //编写与状态对象关联的任何合同代码
   634  			if stateObject.code != nil && stateObject.dirtyCode {
   635  				s.db.TrieDB().InsertBlob(common.BytesToHash(stateObject.CodeHash()), stateObject.code)
   636  				stateObject.dirtyCode = false
   637  			}
   638  //将状态对象中的任何存储更改写入其存储trie。
   639  			if err := stateObject.CommitTrie(s.db); err != nil {
   640  				return common.Hash{}, err
   641  			}
   642  //更新主帐户trie中的对象。
   643  			s.updateStateObject(stateObject)
   644  		}
   645  		delete(s.stateObjectsDirty, addr)
   646  	}
   647  //写入trie更改。
   648  	root, err = s.trie.Commit(func(leaf []byte, parent common.Hash) error {
   649  		var account Account
   650  		if err := rlp.DecodeBytes(leaf, &account); err != nil {
   651  			return nil
   652  		}
   653  		if account.Root != emptyState {
   654  			s.db.TrieDB().Reference(account.Root, parent)
   655  		}
   656  		code := common.BytesToHash(account.CodeHash)
   657  		if code != emptyCode {
   658  			s.db.TrieDB().Reference(code, parent)
   659  		}
   660  		return nil
   661  	})
   662  	log.Debug("Trie cache stats after commit", "misses", trie.CacheMisses(), "unloads", trie.CacheUnloads())
   663  	return root, err
   664  }
   665