github.com/klaytn/klaytn@v1.12.1/accounts/keystore/keyv4.go (about)

     1  // Copyright 2020 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 keystore
    18  
    19  import (
    20  	"crypto/ecdsa"
    21  	"encoding/hex"
    22  	"encoding/json"
    23  
    24  	"github.com/klaytn/klaytn/common"
    25  	"github.com/klaytn/klaytn/crypto"
    26  	"github.com/pborman/uuid"
    27  )
    28  
    29  type KeyV4 struct {
    30  	Id uuid.UUID // Version 4 "random" for unique id not derived from key data
    31  	// to simplify lookups we also store the address
    32  	Address common.Address
    33  	// We only store privkey as pubkey/address can be derived from it.
    34  	PrivateKeys [][]*ecdsa.PrivateKey
    35  }
    36  
    37  type plainKeyJSONV4 struct {
    38  	Address     string     `json:"address"`
    39  	PrivateKeys [][]string `json:"privatekeys"`
    40  	Id          string     `json:"id"`
    41  	Version     int        `json:"version"`
    42  }
    43  
    44  type encryptedKeyJSONV4 struct {
    45  	Address string         `json:"address"`
    46  	Keyring [][]cryptoJSON `json:"keyring"`
    47  	Id      string         `json:"id"`
    48  	Version int            `json:"version"`
    49  }
    50  
    51  type encryptedKeyJSONV4Single struct {
    52  	Address string       `json:"address"`
    53  	Keyring []cryptoJSON `json:"keyring"`
    54  	Id      string       `json:"id"`
    55  	Version int          `json:"version"`
    56  }
    57  
    58  func (k *KeyV4) MarshalJSON() (j []byte, err error) {
    59  	privateKeys := make([][]string, len(k.PrivateKeys))
    60  
    61  	for i, keys := range k.PrivateKeys {
    62  		privateKeys[i] = make([]string, len(keys))
    63  		for j, key := range keys {
    64  			privateKeys[i][j] = common.Bytes2Hex(crypto.FromECDSA(key))
    65  		}
    66  	}
    67  
    68  	jStruct := plainKeyJSONV4{
    69  		Address:     hex.EncodeToString(k.Address.Bytes()),
    70  		PrivateKeys: privateKeys,
    71  		Id:          k.Id.String(),
    72  		Version:     4,
    73  	}
    74  	j, err = json.Marshal(jStruct)
    75  	return j, err
    76  }
    77  
    78  func (k *KeyV4) UnmarshalJSON(j []byte) (err error) {
    79  	keyJSON := new(plainKeyJSONV4)
    80  	if err := json.Unmarshal(j, keyJSON); err != nil {
    81  		return err
    82  	}
    83  
    84  	k.Id = uuid.Parse(keyJSON.Id)
    85  
    86  	addr, err := hex.DecodeString(keyJSON.Address)
    87  	if err != nil {
    88  		return err
    89  	}
    90  
    91  	k.PrivateKeys = make([][]*ecdsa.PrivateKey, len(keyJSON.PrivateKeys))
    92  	for i, keys := range keyJSON.PrivateKeys {
    93  		k.PrivateKeys[i] = make([]*ecdsa.PrivateKey, len(keys))
    94  		for j, key := range keys {
    95  			k.PrivateKeys[i][j], err = crypto.HexToECDSA(key)
    96  			if err != nil {
    97  				return err
    98  			}
    99  		}
   100  	}
   101  
   102  	k.Address = common.BytesToAddress(addr)
   103  
   104  	return nil
   105  }
   106  
   107  func (k *KeyV4) GetId() uuid.UUID {
   108  	return k.Id
   109  }
   110  
   111  func (k *KeyV4) GetAddress() common.Address {
   112  	return k.Address
   113  }
   114  
   115  func (k *KeyV4) GetPrivateKey() *ecdsa.PrivateKey {
   116  	if len(k.PrivateKeys) == 0 || len(k.PrivateKeys[0]) == 0 {
   117  		return nil
   118  	}
   119  
   120  	return k.PrivateKeys[0][0]
   121  }
   122  
   123  func (k *KeyV4) GetPrivateKeys() [][]*ecdsa.PrivateKey {
   124  	return k.PrivateKeys
   125  }
   126  
   127  func (k *KeyV4) GetPrivateKeysWithRole(role int) []*ecdsa.PrivateKey {
   128  	if len(k.PrivateKeys) <= role {
   129  		return nil
   130  	}
   131  	return k.PrivateKeys[role]
   132  }
   133  
   134  func (k *KeyV4) ResetPrivateKey() {
   135  	for _, keys := range k.PrivateKeys {
   136  		for _, key := range keys {
   137  			zeroKey(key)
   138  		}
   139  	}
   140  }