github.com/klaytn/klaytn@v1.10.2/blockchain/types/account/account_common.go (about) 1 // Copyright 2019 The klaytn Authors 2 // This file is part of the klaytn library. 3 // 4 // The klaytn library is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Lesser General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // The klaytn library is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU Lesser General Public License for more details. 13 // 14 // You should have received a copy of the GNU Lesser General Public License 15 // along with the klaytn library. If not, see <http://www.gnu.org/licenses/>. 16 17 package account 18 19 import ( 20 "encoding/json" 21 "fmt" 22 "io" 23 "math/big" 24 25 "github.com/klaytn/klaytn/blockchain/types/accountkey" 26 "github.com/klaytn/klaytn/common/hexutil" 27 "github.com/klaytn/klaytn/rlp" 28 ) 29 30 // AccountCommon represents the common data structure of a Klaytn account. 31 type AccountCommon struct { 32 nonce uint64 33 balance *big.Int 34 humanReadable bool 35 key accountkey.AccountKey 36 } 37 38 // accountCommonSerializable is an internal data structure for RLP serialization. 39 // This object is required due to AccountKey. 40 // AccountKey is an interface and it requires to use AccountKeySerializer for serialization. 41 type accountCommonSerializable struct { 42 Nonce uint64 43 Balance *big.Int 44 HumanReadable bool 45 Key *accountkey.AccountKeySerializer 46 } 47 48 type accountCommonSerializableJSON struct { 49 Nonce uint64 `json:"nonce"` 50 Balance *hexutil.Big `json:"balance"` 51 HumanReadable bool `json:"humanReadable"` 52 Key *accountkey.AccountKeySerializer `json:"key"` 53 } 54 55 // newAccountCommon creates an AccountCommon object with default values. 56 func newAccountCommon() *AccountCommon { 57 return &AccountCommon{ 58 nonce: 0, 59 balance: new(big.Int), 60 humanReadable: false, 61 key: accountkey.NewAccountKeyLegacy(), 62 } 63 } 64 65 // newAccountCommonWithMap creates an AccountCommon object initialized with the given values. 66 func newAccountCommonWithMap(values map[AccountValueKeyType]interface{}) *AccountCommon { 67 acc := newAccountCommon() 68 69 if v, ok := values[AccountValueKeyNonce].(uint64); ok { 70 acc.nonce = v 71 } 72 73 if v, ok := values[AccountValueKeyBalance].(*big.Int); ok { 74 acc.balance.Set(v) 75 } 76 77 if v, ok := values[AccountValueKeyHumanReadable].(bool); ok { 78 acc.humanReadable = v 79 } 80 81 if v, ok := values[AccountValueKeyAccountKey].(accountkey.AccountKey); ok { 82 acc.key = v 83 } 84 85 return acc 86 } 87 88 func newAccountCommonSerializable() *accountCommonSerializable { 89 return &accountCommonSerializable{ 90 Balance: new(big.Int), 91 Key: accountkey.NewAccountKeySerializer(), 92 } 93 } 94 95 // toSerializable converts an AccountCommon object to an accountCommonSerializable object. 96 func (e *AccountCommon) toSerializable() *accountCommonSerializable { 97 return &accountCommonSerializable{ 98 e.nonce, 99 e.balance, 100 e.humanReadable, 101 accountkey.NewAccountKeySerializerWithAccountKey(e.key), 102 } 103 } 104 105 // fromSerializable updates its values from the given accountCommonSerializable object. 106 func (e *AccountCommon) fromSerializable(o *accountCommonSerializable) { 107 e.nonce = o.Nonce 108 e.balance = o.Balance 109 e.humanReadable = o.HumanReadable 110 e.key = o.Key.GetKey() 111 } 112 113 func (e *AccountCommon) EncodeRLP(w io.Writer) error { 114 return rlp.Encode(w, e.toSerializable()) 115 } 116 117 func (e *AccountCommon) DecodeRLP(s *rlp.Stream) error { 118 serialized := newAccountCommonSerializable() 119 120 if err := s.Decode(serialized); err != nil { 121 return err 122 } 123 e.fromSerializable(serialized) 124 return nil 125 } 126 127 func (e *AccountCommon) MarshalJSON() ([]byte, error) { 128 return json.Marshal(&accountCommonSerializableJSON{ 129 Nonce: e.nonce, 130 Balance: (*hexutil.Big)(e.balance), 131 HumanReadable: e.humanReadable, 132 Key: accountkey.NewAccountKeySerializerWithAccountKey(e.key), 133 }) 134 } 135 136 func (e *AccountCommon) UnmarshalJSON(b []byte) error { 137 serialized := &accountCommonSerializableJSON{} 138 139 if err := json.Unmarshal(b, serialized); err != nil { 140 return err 141 } 142 143 e.nonce = serialized.Nonce 144 e.balance = (*big.Int)(serialized.Balance) 145 e.humanReadable = serialized.HumanReadable 146 e.key = serialized.Key.GetKey() 147 148 return nil 149 } 150 151 func (e *AccountCommon) GetNonce() uint64 { 152 return e.nonce 153 } 154 155 func (e *AccountCommon) GetBalance() *big.Int { 156 return e.balance 157 } 158 159 func (e *AccountCommon) GetHumanReadable() bool { 160 return e.humanReadable 161 } 162 163 func (e *AccountCommon) GetKey() accountkey.AccountKey { 164 return e.key 165 } 166 167 func (e *AccountCommon) SetNonce(n uint64) { 168 e.nonce = n 169 } 170 171 func (e *AccountCommon) SetBalance(b *big.Int) { 172 e.balance = b 173 } 174 175 func (e *AccountCommon) SetHumanReadable(h bool) { 176 e.humanReadable = h 177 } 178 179 func (e *AccountCommon) SetKey(k accountkey.AccountKey) { 180 e.key = k 181 } 182 183 func (e *AccountCommon) ReplaceKey(newKey accountkey.AccountKey, currentBlockNumber uint64) error { 184 if err := newKey.CheckInstallable(currentBlockNumber); err != nil { 185 return err 186 } 187 e.SetKey(newKey) 188 return nil 189 } 190 191 func (e *AccountCommon) Empty() bool { 192 return e.nonce == 0 && e.balance.Sign() == 0 && e.key == accountkey.NewAccountKeyLegacy() 193 } 194 195 func (e *AccountCommon) DeepCopy() *AccountCommon { 196 return &AccountCommon{ 197 nonce: e.nonce, 198 balance: new(big.Int).Set(e.balance), 199 humanReadable: e.humanReadable, 200 key: e.key.DeepCopy(), 201 } 202 } 203 204 func (e *AccountCommon) UpdateKey(newKey accountkey.AccountKey, currentBlockNumber uint64) error { 205 newKey = newKey.DeepCopy() 206 if e.key.Type() == newKey.Type() { 207 return e.key.Update(newKey, currentBlockNumber) 208 } 209 return e.ReplaceKey(newKey, currentBlockNumber) 210 } 211 212 func (e *AccountCommon) Equal(ta *AccountCommon) bool { 213 return e.nonce == ta.nonce && 214 e.balance.Cmp(ta.balance) == 0 && 215 e.humanReadable == ta.humanReadable && 216 e.key.Equal(ta.key) 217 } 218 219 func (e *AccountCommon) String() string { 220 return fmt.Sprintf("{Nonce:%d, Balance:%s, HumanReadable:%t key:%s}\n", e.nonce, e.balance.String(), e.humanReadable, 221 e.key.String()) 222 }