github.com/klaytn/klaytn@v1.10.2/blockchain/types/account/account.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  	"errors"
    21  	"math/big"
    22  
    23  	"github.com/klaytn/klaytn/blockchain/types/accountkey"
    24  	"github.com/klaytn/klaytn/common"
    25  	"github.com/klaytn/klaytn/crypto"
    26  	"github.com/klaytn/klaytn/log"
    27  	"github.com/klaytn/klaytn/params"
    28  )
    29  
    30  type AccountType uint8
    31  
    32  const (
    33  	LegacyAccountType AccountType = iota
    34  	ExternallyOwnedAccountType
    35  	SmartContractAccountType
    36  )
    37  
    38  type AccountValueKeyType uint
    39  
    40  const (
    41  	AccountValueKeyNonce AccountValueKeyType = iota
    42  	AccountValueKeyBalance
    43  	AccountValueKeyStorageRoot
    44  	AccountValueKeyCodeHash
    45  	AccountValueKeyHumanReadable
    46  	AccountValueKeyAccountKey
    47  	AccountValueKeyCodeInfo
    48  )
    49  
    50  func (a AccountType) String() string {
    51  	switch a {
    52  	case LegacyAccountType:
    53  		return "LegacyAccountType"
    54  	case ExternallyOwnedAccountType:
    55  		return "ExternallyOwnedAccount"
    56  	case SmartContractAccountType:
    57  		return "SmartContractAccount"
    58  	}
    59  	return "UndefinedAccountType"
    60  }
    61  
    62  var (
    63  	ErrUndefinedAccountType    = errors.New("undefined account type")
    64  	ErrAccountKeyNotModifiable = errors.New("account key is not modifiable")
    65  )
    66  
    67  var (
    68  	// TODO-Klaytn-Accounts: make one single instance emptyCodeHash. It is placed in several locations for now.
    69  	emptyCodeHash = crypto.Keccak256(nil)
    70  
    71  	logger = log.NewModuleLogger(log.BlockchainState)
    72  )
    73  
    74  // Account is the Klaytn consensus representation of accounts.
    75  // These objects are stored in the main account trie.
    76  type Account interface {
    77  	Type() AccountType
    78  
    79  	GetNonce() uint64
    80  	GetBalance() *big.Int
    81  	GetHumanReadable() bool
    82  
    83  	SetNonce(n uint64)
    84  	SetBalance(b *big.Int)
    85  	SetHumanReadable(b bool)
    86  
    87  	// UpdateKey updates the account's key with the given key.
    88  	UpdateKey(newKey accountkey.AccountKey, currentBlockNumber uint64) error
    89  
    90  	// Empty returns whether the account is considered empty.
    91  	// The "empty" account may be defined differently depending on the actual account type.
    92  	// An example of an empty account could be described as the one that satisfies the following conditions:
    93  	// - nonce is zero
    94  	// - balance is zero
    95  	// - codeHash is the same as emptyCodeHash
    96  	Empty() bool
    97  
    98  	// Equal returns true if all the attributes are exactly same. Otherwise, returns false.
    99  	Equal(Account) bool
   100  
   101  	// DeepCopy copies all the attributes.
   102  	DeepCopy() Account
   103  
   104  	// String returns all attributes of this object as a string.
   105  	String() string
   106  }
   107  
   108  // ProgramAccount is an interface of an account having a program (code + storage).
   109  // This interface is implemented by LegacyAccount and SmartContractAccount.
   110  type ProgramAccount interface {
   111  	Account
   112  
   113  	GetStorageRoot() common.Hash
   114  	GetCodeHash() []byte
   115  	GetCodeFormat() params.CodeFormat
   116  	GetVmVersion() params.VmVersion
   117  
   118  	SetStorageRoot(h common.Hash)
   119  	SetCodeHash(h []byte)
   120  	SetCodeInfo(codeInfo params.CodeInfo)
   121  }
   122  
   123  type AccountWithKey interface {
   124  	Account
   125  
   126  	GetKey() accountkey.AccountKey
   127  	SetKey(key accountkey.AccountKey)
   128  }
   129  
   130  // NewAccountWithType creates an Account object with the given type.
   131  func NewAccountWithType(t AccountType) (Account, error) {
   132  	switch t {
   133  	case LegacyAccountType:
   134  		return newLegacyAccount(), nil
   135  	case ExternallyOwnedAccountType:
   136  		return newExternallyOwnedAccount(), nil
   137  	case SmartContractAccountType:
   138  		return newSmartContractAccount(), nil
   139  	}
   140  
   141  	return nil, ErrUndefinedAccountType
   142  }
   143  
   144  // NewAccountWithType creates an Account object initialized with the given map.
   145  func NewAccountWithMap(t AccountType, values map[AccountValueKeyType]interface{}) (Account, error) {
   146  	switch t {
   147  	case LegacyAccountType:
   148  		return newLegacyAccountWithMap(values), nil
   149  	case ExternallyOwnedAccountType:
   150  		return newExternallyOwnedAccountWithMap(values), nil
   151  	case SmartContractAccountType:
   152  		return newSmartContractAccountWithMap(values), nil
   153  	}
   154  
   155  	return nil, ErrUndefinedAccountType
   156  }
   157  
   158  func GetProgramAccount(a Account) ProgramAccount {
   159  	if pa, ok := a.(ProgramAccount); ok {
   160  		return pa
   161  	}
   162  
   163  	return nil
   164  }
   165  
   166  func GetAccountWithKey(a Account) AccountWithKey {
   167  	if ak, ok := a.(AccountWithKey); ok {
   168  		return ak
   169  	}
   170  
   171  	return nil
   172  }