github.com/klaytn/klaytn@v1.12.1/blockchain/state/dump.go (about) 1 // Modifications Copyright 2018 The klaytn Authors 2 // Copyright 2014 The go-ethereum Authors 3 // This file is part of the go-ethereum library. 4 // 5 // The go-ethereum library is free software: you can redistribute it and/or modify 6 // it under the terms of the GNU Lesser General Public License as published by 7 // the Free Software Foundation, either version 3 of the License, or 8 // (at your option) any later version. 9 // 10 // The go-ethereum library is distributed in the hope that it will be useful, 11 // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 // GNU Lesser General Public License for more details. 14 // 15 // You should have received a copy of the GNU Lesser General Public License 16 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 17 // 18 // This file is derived from core/state/dump.go (2018/06/04). 19 // Modified and improved for the klaytn development. 20 21 package state 22 23 import ( 24 "encoding/json" 25 "fmt" 26 27 "github.com/klaytn/klaytn/blockchain/types/account" 28 "github.com/klaytn/klaytn/common" 29 "github.com/klaytn/klaytn/rlp" 30 "github.com/klaytn/klaytn/storage/statedb" 31 ) 32 33 // emptyRoot is the known root hash of an empty trie. 34 var emptyRoot = common.HexToHash("56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421") 35 36 type DumpAccount struct { 37 Balance string `json:"balance"` 38 Nonce uint64 `json:"nonce"` 39 Root string `json:"root"` 40 CodeHash string `json:"codeHash"` 41 Code string `json:"code"` 42 Storage map[string]string `json:"storage"` 43 } 44 45 type Dump struct { 46 Root string `json:"root"` 47 Accounts map[string]DumpAccount `json:"accounts"` 48 } 49 50 func (self *StateDB) RawDump() Dump { 51 dump := Dump{ 52 Root: fmt.Sprintf("%x", self.trie.Hash()), 53 Accounts: make(map[string]DumpAccount), 54 } 55 56 it := statedb.NewIterator(self.trie.NodeIterator(nil)) 57 for it.Next() { 58 addr := self.trie.GetKey(it.Key) 59 serializer := account.NewAccountSerializer() 60 if err := rlp.DecodeBytes(it.Value, serializer); err != nil { 61 panic(err) 62 } 63 data := serializer.GetAccount() 64 65 obj := self.getStateObject(common.BytesToAddress(addr)) 66 acc := DumpAccount{ 67 Balance: data.GetBalance().String(), 68 Nonce: data.GetNonce(), 69 Root: common.Bytes2Hex([]byte{}), 70 CodeHash: common.Bytes2Hex([]byte{}), 71 Code: common.Bytes2Hex([]byte{}), 72 Storage: make(map[string]string), 73 } 74 if pa := account.GetProgramAccount(data); pa != nil { 75 acc.Root = common.Bytes2Hex(pa.GetStorageRoot().Unextend().Bytes()) 76 acc.CodeHash = common.Bytes2Hex(pa.GetCodeHash()) 77 acc.Code = common.Bytes2Hex(obj.Code(self.db)) 78 } else { 79 acc.Root = common.Bytes2Hex(emptyRoot.Bytes()) 80 acc.CodeHash = common.Bytes2Hex(emptyCodeHash) 81 } 82 storageTrie := obj.getStorageTrie(self.db) 83 storageIt := statedb.NewIterator(storageTrie.NodeIterator(nil)) 84 for storageIt.Next() { 85 acc.Storage[common.Bytes2Hex(storageTrie.GetKey(storageIt.Key))] = common.Bytes2Hex(storageIt.Value) 86 } 87 dump.Accounts[common.Bytes2Hex(addr)] = acc 88 } 89 return dump 90 } 91 92 func (self *StateDB) Dump() []byte { 93 json, err := json.MarshalIndent(self.RawDump(), "", " ") 94 if err != nil { 95 fmt.Println("dump err", err) 96 } 97 98 return json 99 }