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