github.com/klaytn/klaytn@v1.12.1/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  }