github.com/yinchengtsinghua/golang-Eos-dpos-Ethereum@v0.0.0-20190121132951-92cc4225ed8e/core/state/state_object.go (about) 1 2 //此源码被清华学神尹成大魔王专业翻译分析并修改 3 //尹成QQ77025077 4 //尹成微信18510341407 5 //尹成所在QQ群721929980 6 //尹成邮箱 yinc13@mails.tsinghua.edu.cn 7 //尹成毕业于清华大学,微软区块链领域全球最有价值专家 8 //https://mvp.microsoft.com/zh-cn/PublicProfile/4033620 9 //版权所有2014 Go Ethereum作者 10 //此文件是Go以太坊库的一部分。 11 // 12 //Go-Ethereum库是免费软件:您可以重新分发它和/或修改 13 //根据GNU发布的较低通用公共许可证的条款 14 //自由软件基金会,或者许可证的第3版,或者 15 //(由您选择)任何更高版本。 16 // 17 //Go以太坊图书馆的发行目的是希望它会有用, 18 //但没有任何保证;甚至没有 19 //适销性或特定用途的适用性。见 20 //GNU较低的通用公共许可证,了解更多详细信息。 21 // 22 //你应该收到一份GNU较低级别的公共许可证副本 23 //以及Go以太坊图书馆。如果没有,请参见<http://www.gnu.org/licenses/>。 24 25 package state 26 27 import ( 28 "bytes" 29 "fmt" 30 "io" 31 "math/big" 32 33 "github.com/ethereum/go-ethereum/common" 34 "github.com/ethereum/go-ethereum/crypto" 35 "github.com/ethereum/go-ethereum/rlp" 36 ) 37 38 var emptyCodeHash = crypto.Keccak256(nil) 39 40 type Code []byte 41 42 func (self Code) String() string { 43 return string(self) //strings.join(反汇编(self),“”) 44 } 45 46 type Storage map[common.Hash]common.Hash 47 48 func (self Storage) String() (str string) { 49 for key, value := range self { 50 str += fmt.Sprintf("%X : %X\n", key, value) 51 } 52 53 return 54 } 55 56 func (self Storage) Copy() Storage { 57 cpy := make(Storage) 58 for key, value := range self { 59 cpy[key] = value 60 } 61 62 return cpy 63 } 64 65 //StateObject表示正在修改的以太坊帐户。 66 // 67 //使用模式如下: 68 //首先需要获取一个状态对象。 69 //可以通过对象访问和修改帐户值。 70 //最后,调用committrie将修改后的存储trie写入数据库。 71 type stateObject struct { 72 address common.Address 73 addrHash common.Hash //帐户的以太坊地址哈希 74 data Account 75 db *StateDB 76 77 //数据库错误。 78 //状态对象由共识核心和虚拟机使用,它们是 79 //无法处理数据库级错误。发生的任何错误 80 //在数据库读取过程中,将在此处记忆并最终返回 81 //按statedb.commit。 82 dbErr error 83 84 //编写高速缓存。 85 trie Trie //存储trie,在第一次访问时变为非nil 86 code Code //契约字节码,在加载代码时设置 87 88 cachedStorage Storage //存储项缓存以避免重复读取 89 dirtyStorage Storage //需要刷新到磁盘的存储项 90 91 //缓存标志。 92 //当一个对象被标记为自杀时,它将从trie中删除。 93 //在状态转换的“更新”阶段。 94 dirtyCode bool //如果代码已更新,则为true 95 suicided bool 96 deleted bool 97 } 98 99 //empty返回帐户是否被视为空。 100 func (s *stateObject) empty() bool { 101 return s.data.Nonce == 0 && s.data.Balance.Sign() == 0 && bytes.Equal(s.data.CodeHash, emptyCodeHash) 102 } 103 104 //账户是账户的以太坊共识代表。 105 //这些对象存储在主帐户trie中。 106 type Account struct { 107 Nonce uint64 108 Balance *big.Int 109 Root common.Hash //存储树的merkle根 110 CodeHash []byte 111 } 112 113 //NewObject创建一个状态对象。 114 func newObject(db *StateDB, address common.Address, data Account) *stateObject { 115 if data.Balance == nil { 116 data.Balance = new(big.Int) 117 } 118 if data.CodeHash == nil { 119 data.CodeHash = emptyCodeHash 120 } 121 return &stateObject{ 122 db: db, 123 address: address, 124 addrHash: crypto.Keccak256Hash(address[:]), 125 data: data, 126 cachedStorage: make(Storage), 127 dirtyStorage: make(Storage), 128 } 129 } 130 131 //encoderlp实现rlp.encoder。 132 func (c *stateObject) EncodeRLP(w io.Writer) error { 133 return rlp.Encode(w, c.data) 134 } 135 136 //setError记住调用它时使用的第一个非零错误。 137 func (self *stateObject) setError(err error) { 138 if self.dbErr == nil { 139 self.dbErr = err 140 } 141 } 142 143 func (self *stateObject) markSuicided() { 144 self.suicided = true 145 } 146 147 func (c *stateObject) touch() { 148 c.db.journal.append(touchChange{ 149 account: &c.address, 150 }) 151 if c.address == ripemd { 152 //显式地将其放入脏缓存中,否则将从 153 //扁平轴颈。 154 c.db.journal.dirty(c.address) 155 } 156 } 157 158 func (c *stateObject) getTrie(db Database) Trie { 159 if c.trie == nil { 160 var err error 161 c.trie, err = db.OpenStorageTrie(c.addrHash, c.data.Root) 162 if err != nil { 163 c.trie, _ = db.OpenStorageTrie(c.addrHash, common.Hash{}) 164 c.setError(fmt.Errorf("can't create storage trie: %v", err)) 165 } 166 } 167 return c.trie 168 } 169 170 //GetState返回帐户存储中的值。 171 func (self *stateObject) GetState(db Database, key common.Hash) common.Hash { 172 value, exists := self.cachedStorage[key] 173 if exists { 174 return value 175 } 176 //从数据库加载以防丢失。 177 enc, err := self.getTrie(db).TryGet(key[:]) 178 if err != nil { 179 self.setError(err) 180 return common.Hash{} 181 } 182 if len(enc) > 0 { 183 _, content, _, err := rlp.Split(enc) 184 if err != nil { 185 self.setError(err) 186 } 187 value.SetBytes(content) 188 } 189 self.cachedStorage[key] = value 190 return value 191 } 192 193 //setstate更新帐户存储中的值。 194 func (self *stateObject) SetState(db Database, key, value common.Hash) { 195 self.db.journal.append(storageChange{ 196 account: &self.address, 197 key: key, 198 prevalue: self.GetState(db, key), 199 }) 200 self.setState(key, value) 201 } 202 203 func (self *stateObject) setState(key, value common.Hash) { 204 self.cachedStorage[key] = value 205 self.dirtyStorage[key] = value 206 } 207 208 //updatetrie将缓存的存储修改写入对象的存储trie。 209 func (self *stateObject) updateTrie(db Database) Trie { 210 tr := self.getTrie(db) 211 for key, value := range self.dirtyStorage { 212 delete(self.dirtyStorage, key) 213 if (value == common.Hash{}) { 214 self.setError(tr.TryDelete(key[:])) 215 continue 216 } 217 //编码[]字节不能失败,可以忽略错误。 218 v, _ := rlp.EncodeToBytes(bytes.TrimLeft(value[:], "\x00")) 219 self.setError(tr.TryUpdate(key[:], v)) 220 } 221 return tr 222 } 223 224 //updateRoot将trie根设置为当前根哈希 225 func (self *stateObject) updateRoot(db Database) { 226 self.updateTrie(db) 227 self.data.Root = self.trie.Hash() 228 } 229 230 //将对象的存储trie提交给db。 231 //这将更新trie根目录。 232 func (self *stateObject) CommitTrie(db Database) error { 233 self.updateTrie(db) 234 if self.dbErr != nil { 235 return self.dbErr 236 } 237 root, err := self.trie.Commit(nil) 238 if err == nil { 239 self.data.Root = root 240 } 241 return err 242 } 243 244 //AddBalance从C的余额中删除金额。 245 //它用于将资金添加到转账的目的地帐户。 246 func (c *stateObject) AddBalance(amount *big.Int) { 247 //EIP158:我们必须检查对象的空性,以便帐户 248 //清除(0,0,0个对象)可以生效。 249 if amount.Sign() == 0 { 250 if c.empty() { 251 c.touch() 252 } 253 254 return 255 } 256 c.SetBalance(new(big.Int).Add(c.Balance(), amount)) 257 } 258 259 //次平衡从C的平衡中除去了数量。 260 //它用于从转账的原始账户中取出资金。 261 func (c *stateObject) SubBalance(amount *big.Int) { 262 if amount.Sign() == 0 { 263 return 264 } 265 c.SetBalance(new(big.Int).Sub(c.Balance(), amount)) 266 } 267 268 func (self *stateObject) SetBalance(amount *big.Int) { 269 self.db.journal.append(balanceChange{ 270 account: &self.address, 271 prev: new(big.Int).Set(self.data.Balance), 272 }) 273 self.setBalance(amount) 274 } 275 276 func (self *stateObject) setBalance(amount *big.Int) { 277 self.data.Balance = amount 278 } 279 280 //将气体返回原点。由虚拟机或闭包使用 281 func (c *stateObject) ReturnGas(gas *big.Int) {} 282 283 func (self *stateObject) deepCopy(db *StateDB) *stateObject { 284 stateObject := newObject(db, self.address, self.data) 285 if self.trie != nil { 286 stateObject.trie = db.db.CopyTrie(self.trie) 287 } 288 stateObject.code = self.code 289 stateObject.dirtyStorage = self.dirtyStorage.Copy() 290 stateObject.cachedStorage = self.dirtyStorage.Copy() 291 stateObject.suicided = self.suicided 292 stateObject.dirtyCode = self.dirtyCode 293 stateObject.deleted = self.deleted 294 return stateObject 295 } 296 297 // 298 //属性访问器 299 // 300 301 //返回合同/帐户的地址 302 func (c *stateObject) Address() common.Address { 303 return c.address 304 } 305 306 //代码返回与此对象关联的合同代码(如果有)。 307 func (self *stateObject) Code(db Database) []byte { 308 if self.code != nil { 309 return self.code 310 } 311 if bytes.Equal(self.CodeHash(), emptyCodeHash) { 312 return nil 313 } 314 code, err := db.ContractCode(self.addrHash, common.BytesToHash(self.CodeHash())) 315 if err != nil { 316 self.setError(fmt.Errorf("can't load code hash %x: %v", self.CodeHash(), err)) 317 } 318 self.code = code 319 return code 320 } 321 322 func (self *stateObject) SetCode(codeHash common.Hash, code []byte) { 323 prevcode := self.Code(self.db.db) 324 self.db.journal.append(codeChange{ 325 account: &self.address, 326 prevhash: self.CodeHash(), 327 prevcode: prevcode, 328 }) 329 self.setCode(codeHash, code) 330 } 331 332 func (self *stateObject) setCode(codeHash common.Hash, code []byte) { 333 self.code = code 334 self.data.CodeHash = codeHash[:] 335 self.dirtyCode = true 336 } 337 338 func (self *stateObject) SetNonce(nonce uint64) { 339 self.db.journal.append(nonceChange{ 340 account: &self.address, 341 prev: self.data.Nonce, 342 }) 343 self.setNonce(nonce) 344 } 345 346 func (self *stateObject) setNonce(nonce uint64) { 347 self.data.Nonce = nonce 348 } 349 350 func (self *stateObject) CodeHash() []byte { 351 return self.data.CodeHash 352 } 353 354 func (self *stateObject) Balance() *big.Int { 355 return self.data.Balance 356 } 357 358 func (self *stateObject) Nonce() uint64 { 359 return self.data.Nonce 360 } 361 362 //从未调用,但必须存在才能使用StateObject 363 //作为一个也满足vm.contractRef的vm.account接口 364 //接口。界面很棒。 365 func (self *stateObject) Value() *big.Int { 366 panic("Value on stateObject should never be called") 367 }