github.com/dim4egster/coreth@v0.10.2/plugin/evm/user.go (about) 1 // (c) 2019-2020, Ava Labs, Inc. All rights reserved. 2 // See the file LICENSE for licensing terms. 3 4 package evm 5 6 import ( 7 "errors" 8 "fmt" 9 10 "github.com/dim4egster/qmallgo/database/encdb" 11 "github.com/dim4egster/qmallgo/ids" 12 "github.com/dim4egster/qmallgo/utils/crypto" 13 "github.com/ethereum/go-ethereum/common" 14 ) 15 16 // Key in the database whose corresponding value is the list of 17 // addresses this user controls 18 var addressesKey = ids.Empty[:] 19 20 var ( 21 errDBNil = errors.New("db uninitialized") 22 errKeyNil = errors.New("key uninitialized") 23 ) 24 25 type user struct { 26 secpFactory *crypto.FactorySECP256K1R 27 // This user's database, acquired from the keystore 28 db *encdb.Database 29 } 30 31 // Get the addresses controlled by this user 32 func (u *user) getAddresses() ([]common.Address, error) { 33 if u.db == nil { 34 return nil, errDBNil 35 } 36 37 // If user has no addresses, return empty list 38 hasAddresses, err := u.db.Has(addressesKey) 39 if err != nil { 40 return nil, err 41 } 42 if !hasAddresses { 43 return nil, nil 44 } 45 46 // User has addresses. Get them. 47 bytes, err := u.db.Get(addressesKey) 48 if err != nil { 49 return nil, err 50 } 51 addresses := []common.Address{} 52 if _, err := Codec.Unmarshal(bytes, &addresses); err != nil { 53 return nil, err 54 } 55 return addresses, nil 56 } 57 58 // controlsAddress returns true iff this user controls the given address 59 func (u *user) controlsAddress(address common.Address) (bool, error) { 60 if u.db == nil { 61 return false, errDBNil 62 //} else if address.IsZero() { 63 // return false, errEmptyAddress 64 } 65 return u.db.Has(address.Bytes()) 66 } 67 68 // putAddress persists that this user controls address controlled by [privKey] 69 func (u *user) putAddress(privKey *crypto.PrivateKeySECP256K1R) error { 70 if privKey == nil { 71 return errKeyNil 72 } 73 74 address := GetEthAddress(privKey) // address the privKey controls 75 controlsAddress, err := u.controlsAddress(address) 76 if err != nil { 77 return err 78 } 79 if controlsAddress { // user already controls this address. Do nothing. 80 return nil 81 } 82 83 if err := u.db.Put(address.Bytes(), privKey.Bytes()); err != nil { // Address --> private key 84 return err 85 } 86 87 addresses := make([]common.Address, 0) // Add address to list of addresses user controls 88 userHasAddresses, err := u.db.Has(addressesKey) 89 if err != nil { 90 return err 91 } 92 if userHasAddresses { // Get addresses this user already controls, if they exist 93 if addresses, err = u.getAddresses(); err != nil { 94 return err 95 } 96 } 97 addresses = append(addresses, address) 98 bytes, err := Codec.Marshal(codecVersion, addresses) 99 if err != nil { 100 return err 101 } 102 if err := u.db.Put(addressesKey, bytes); err != nil { 103 return err 104 } 105 return nil 106 } 107 108 // Key returns the private key that controls the given address 109 func (u *user) getKey(address common.Address) (*crypto.PrivateKeySECP256K1R, error) { 110 if u.db == nil { 111 return nil, errDBNil 112 //} else if address.IsZero() { 113 // return nil, errEmptyAddress 114 } 115 116 bytes, err := u.db.Get(address.Bytes()) 117 if err != nil { 118 return nil, err 119 } 120 sk, err := u.secpFactory.ToPrivateKey(bytes) 121 if err != nil { 122 return nil, err 123 } 124 if sk, ok := sk.(*crypto.PrivateKeySECP256K1R); ok { 125 return sk, nil 126 } 127 return nil, fmt.Errorf("expected private key to be type *crypto.PrivateKeySECP256K1R but is type %T", sk) 128 } 129 130 // Return all private keys controlled by this user 131 func (u *user) getKeys() ([]*crypto.PrivateKeySECP256K1R, error) { 132 addrs, err := u.getAddresses() 133 if err != nil { 134 return nil, err 135 } 136 keys := make([]*crypto.PrivateKeySECP256K1R, len(addrs)) 137 for i, addr := range addrs { 138 key, err := u.getKey(addr) 139 if err != nil { 140 return nil, err 141 } 142 keys[i] = key 143 } 144 return keys, nil 145 }