github.com/avence12/go-ethereum@v1.5.10-0.20170320123548-1dfd65f6d047/mobile/accounts.go (about) 1 // Copyright 2016 The go-ethereum Authors 2 // This file is part of the go-ethereum library. 3 // 4 // The go-ethereum 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 go-ethereum 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 go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 16 17 // Contains all the wrappers from the accounts package to support client side key 18 // management on mobile platforms. 19 20 package geth 21 22 import ( 23 "errors" 24 "time" 25 26 "github.com/ethereum/go-ethereum/accounts" 27 "github.com/ethereum/go-ethereum/accounts/keystore" 28 ) 29 30 const ( 31 // StandardScryptN is the N parameter of Scrypt encryption algorithm, using 256MB 32 // memory and taking approximately 1s CPU time on a modern processor. 33 StandardScryptN = int(keystore.StandardScryptN) 34 35 // StandardScryptP is the P parameter of Scrypt encryption algorithm, using 256MB 36 // memory and taking approximately 1s CPU time on a modern processor. 37 StandardScryptP = int(keystore.StandardScryptP) 38 39 // LightScryptN is the N parameter of Scrypt encryption algorithm, using 4MB 40 // memory and taking approximately 100ms CPU time on a modern processor. 41 LightScryptN = int(keystore.LightScryptN) 42 43 // LightScryptP is the P parameter of Scrypt encryption algorithm, using 4MB 44 // memory and taking approximately 100ms CPU time on a modern processor. 45 LightScryptP = int(keystore.LightScryptP) 46 ) 47 48 // Account represents a stored key. 49 type Account struct{ account accounts.Account } 50 51 // Accounts represents a slice of accounts. 52 type Accounts struct{ accounts []accounts.Account } 53 54 // Size returns the number of accounts in the slice. 55 func (a *Accounts) Size() int { 56 return len(a.accounts) 57 } 58 59 // Get returns the account at the given index from the slice. 60 func (a *Accounts) Get(index int) (account *Account, _ error) { 61 if index < 0 || index >= len(a.accounts) { 62 return nil, errors.New("index out of bounds") 63 } 64 return &Account{a.accounts[index]}, nil 65 } 66 67 // Set sets the account at the given index in the slice. 68 func (a *Accounts) Set(index int, account *Account) error { 69 if index < 0 || index >= len(a.accounts) { 70 return errors.New("index out of bounds") 71 } 72 a.accounts[index] = account.account 73 return nil 74 } 75 76 // GetAddress retrieves the address associated with the account. 77 func (a *Account) GetAddress() *Address { 78 return &Address{a.account.Address} 79 } 80 81 // GetURL retrieves the canonical URL of the account. 82 func (a *Account) GetURL() string { 83 return a.account.URL.String() 84 } 85 86 // KeyStore manages a key storage directory on disk. 87 type KeyStore struct{ keystore *keystore.KeyStore } 88 89 // NewKeyStore creates a keystore for the given directory. 90 func NewKeyStore(keydir string, scryptN, scryptP int) *KeyStore { 91 return &KeyStore{keystore: keystore.NewKeyStore(keydir, scryptN, scryptP)} 92 } 93 94 // HasAddress reports whether a key with the given address is present. 95 func (ks *KeyStore) HasAddress(address *Address) bool { 96 return ks.keystore.HasAddress(address.address) 97 } 98 99 // GetAccounts returns all key files present in the directory. 100 func (ks *KeyStore) GetAccounts() *Accounts { 101 return &Accounts{ks.keystore.Accounts()} 102 } 103 104 // DeleteAccount deletes the key matched by account if the passphrase is correct. 105 // If a contains no filename, the address must match a unique key. 106 func (ks *KeyStore) DeleteAccount(account *Account, passphrase string) error { 107 return ks.keystore.Delete(account.account, passphrase) 108 } 109 110 // SignHash calculates a ECDSA signature for the given hash. The produced signature 111 // is in the [R || S || V] format where V is 0 or 1. 112 func (ks *KeyStore) SignHash(address *Address, hash []byte) (signature []byte, _ error) { 113 return ks.keystore.SignHash(accounts.Account{Address: address.address}, hash) 114 } 115 116 // SignTx signs the given transaction with the requested account. 117 func (ks *KeyStore) SignTx(account *Account, tx *Transaction, chainID *BigInt) (*Transaction, error) { 118 signed, err := ks.keystore.SignTx(account.account, tx.tx, chainID.bigint) 119 if err != nil { 120 return nil, err 121 } 122 return &Transaction{signed}, nil 123 } 124 125 // SignHashPassphrase signs hash if the private key matching the given address can 126 // be decrypted with the given passphrase. The produced signature is in the 127 // [R || S || V] format where V is 0 or 1. 128 func (ks *KeyStore) SignHashPassphrase(account *Account, passphrase string, hash []byte) (signature []byte, _ error) { 129 return ks.keystore.SignHashWithPassphrase(account.account, passphrase, hash) 130 } 131 132 // SignTxPassphrase signs the transaction if the private key matching the 133 // given address can be decrypted with the given passphrase. 134 func (ks *KeyStore) SignTxPassphrase(account *Account, passphrase string, tx *Transaction, chainID *BigInt) (*Transaction, error) { 135 signed, err := ks.keystore.SignTxWithPassphrase(account.account, passphrase, tx.tx, chainID.bigint) 136 if err != nil { 137 return nil, err 138 } 139 return &Transaction{signed}, nil 140 } 141 142 // Unlock unlocks the given account indefinitely. 143 func (ks *KeyStore) Unlock(account *Account, passphrase string) error { 144 return ks.keystore.TimedUnlock(account.account, passphrase, 0) 145 } 146 147 // Lock removes the private key with the given address from memory. 148 func (ks *KeyStore) Lock(address *Address) error { 149 return ks.keystore.Lock(address.address) 150 } 151 152 // TimedUnlock unlocks the given account with the passphrase. The account stays 153 // unlocked for the duration of timeout (nanoseconds). A timeout of 0 unlocks the 154 // account until the program exits. The account must match a unique key file. 155 // 156 // If the account address is already unlocked for a duration, TimedUnlock extends or 157 // shortens the active unlock timeout. If the address was previously unlocked 158 // indefinitely the timeout is not altered. 159 func (ks *KeyStore) TimedUnlock(account *Account, passphrase string, timeout int64) error { 160 return ks.keystore.TimedUnlock(account.account, passphrase, time.Duration(timeout)) 161 } 162 163 // NewAccount generates a new key and stores it into the key directory, 164 // encrypting it with the passphrase. 165 func (ks *KeyStore) NewAccount(passphrase string) (*Account, error) { 166 account, err := ks.keystore.NewAccount(passphrase) 167 if err != nil { 168 return nil, err 169 } 170 return &Account{account}, nil 171 } 172 173 // ExportKey exports as a JSON key, encrypted with newPassphrase. 174 func (ks *KeyStore) ExportKey(account *Account, passphrase, newPassphrase string) (key []byte, _ error) { 175 return ks.keystore.Export(account.account, passphrase, newPassphrase) 176 } 177 178 // ImportKey stores the given encrypted JSON key into the key directory. 179 func (ks *KeyStore) ImportKey(keyJSON []byte, passphrase, newPassphrase string) (account *Account, _ error) { 180 acc, err := ks.keystore.Import(keyJSON, passphrase, newPassphrase) 181 if err != nil { 182 return nil, err 183 } 184 return &Account{acc}, nil 185 } 186 187 // UpdateAccount changes the passphrase of an existing account. 188 func (ks *KeyStore) UpdateAccount(account *Account, passphrase, newPassphrase string) error { 189 return ks.keystore.Update(account.account, passphrase, newPassphrase) 190 } 191 192 // ImportPreSaleKey decrypts the given Ethereum presale wallet and stores 193 // a key file in the key directory. The key file is encrypted with the same passphrase. 194 func (ks *KeyStore) ImportPreSaleKey(keyJSON []byte, passphrase string) (ccount *Account, _ error) { 195 account, err := ks.keystore.ImportPreSaleKey(keyJSON, passphrase) 196 if err != nil { 197 return nil, err 198 } 199 return &Account{account}, nil 200 }