github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/x/evm/types/storage.go (about) 1 package types 2 3 import ( 4 "bytes" 5 "encoding/json" 6 "fmt" 7 8 ethcmn "github.com/ethereum/go-ethereum/common" 9 sdkerrors "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types/errors" 10 ) 11 12 // Storage represents the account Storage map as a slice of single key value 13 // State pairs. This is to prevent non determinism at genesis initialization or export. 14 type Storage []State 15 16 // Validate performs a basic validation of the Storage fields. 17 func (s Storage) Validate() error { 18 seenStorage := make(map[string]bool) 19 for i, state := range s { 20 if seenStorage[state.Key.String()] { 21 return sdkerrors.Wrapf(ErrInvalidState, "duplicate state key %d", i) 22 } 23 24 if err := state.Validate(); err != nil { 25 return err 26 } 27 28 seenStorage[state.Key.String()] = true 29 } 30 return nil 31 } 32 33 // String implements the stringer interface 34 func (s Storage) String() string { 35 var str string 36 for _, state := range s { 37 str += fmt.Sprintf("%s: %s\n", state.Key.String(), state.Value.String()) 38 } 39 40 return str 41 } 42 43 // Copy returns a copy of storage. 44 func (s Storage) Copy() Storage { 45 cpy := make(Storage, len(s)) 46 copy(cpy, s) 47 48 return cpy 49 } 50 51 // State represents a single Storage key value pair item. 52 type State struct { 53 Key ethcmn.Hash `json:"key"` 54 Value ethcmn.Hash `json:"value"` 55 } 56 57 // Validate performs a basic validation of the State fields. 58 func (s State) Validate() error { 59 if bytes.Equal(s.Key.Bytes(), ethcmn.Hash{}.Bytes()) { 60 return sdkerrors.Wrap(ErrInvalidState, "state key hash cannot be empty") 61 } 62 // NOTE: state value can be empty 63 return nil 64 } 65 66 // NewState creates a new State instance 67 func NewState(key, value ethcmn.Hash) State { 68 return State{ 69 Key: key, 70 Value: value, 71 } 72 } 73 74 func (s State) MarshalJSON() ([]byte, error) { 75 formatState := &struct { 76 Key string `json:"key"` 77 Value string `json:"value"` 78 }{ 79 Key: s.Key.Hex(), 80 Value: s.Value.Hex(), 81 } 82 83 return json.Marshal(formatState) 84 } 85 86 func (s *State) UnmarshalJSON(input []byte) error { 87 formatState := &struct { 88 Key string `json:"key"` 89 Value string `json:"value"` 90 }{} 91 if err := json.Unmarshal(input, &formatState); err != nil { 92 return err 93 } 94 95 s.Key = ethcmn.HexToHash(formatState.Key) 96 s.Value = ethcmn.HexToHash(formatState.Value) 97 return nil 98 }