aboutsummaryrefslogtreecommitdiffstats
path: root/mobile
diff options
context:
space:
mode:
authorPéter Szilágyi <peterke@gmail.com>2017-01-24 17:49:20 +0800
committerPéter Szilágyi <peterke@gmail.com>2017-02-13 20:00:02 +0800
commit833e4d1319336fbb66fd8f1e473c24472d65b17b (patch)
tree74d45d86d0c59c19f0ff67831f04e0cad9776eef /mobile
parent564b60520c68a1f06171abd705c01946b932492f (diff)
downloadgo-tangerine-833e4d1319336fbb66fd8f1e473c24472d65b17b.tar
go-tangerine-833e4d1319336fbb66fd8f1e473c24472d65b17b.tar.gz
go-tangerine-833e4d1319336fbb66fd8f1e473c24472d65b17b.tar.bz2
go-tangerine-833e4d1319336fbb66fd8f1e473c24472d65b17b.tar.lz
go-tangerine-833e4d1319336fbb66fd8f1e473c24472d65b17b.tar.xz
go-tangerine-833e4d1319336fbb66fd8f1e473c24472d65b17b.tar.zst
go-tangerine-833e4d1319336fbb66fd8f1e473c24472d65b17b.zip
accounts, cmd, eth, internal, mobile, node: split account backends
Diffstat (limited to 'mobile')
-rw-r--r--mobile/accounts.go99
-rw-r--r--mobile/android_test.go34
-rw-r--r--mobile/types.go5
3 files changed, 82 insertions, 56 deletions
diff --git a/mobile/accounts.go b/mobile/accounts.go
index 621be4d7a..897549a6b 100644
--- a/mobile/accounts.go
+++ b/mobile/accounts.go
@@ -24,24 +24,25 @@ import (
"time"
"github.com/ethereum/go-ethereum/accounts"
+ "github.com/ethereum/go-ethereum/accounts/keystore"
)
const (
// StandardScryptN is the N parameter of Scrypt encryption algorithm, using 256MB
// memory and taking approximately 1s CPU time on a modern processor.
- StandardScryptN = int(accounts.StandardScryptN)
+ StandardScryptN = int(keystore.StandardScryptN)
// StandardScryptP is the P parameter of Scrypt encryption algorithm, using 256MB
// memory and taking approximately 1s CPU time on a modern processor.
- StandardScryptP = int(accounts.StandardScryptP)
+ StandardScryptP = int(keystore.StandardScryptP)
// LightScryptN is the N parameter of Scrypt encryption algorithm, using 4MB
// memory and taking approximately 100ms CPU time on a modern processor.
- LightScryptN = int(accounts.LightScryptN)
+ LightScryptN = int(keystore.LightScryptN)
// LightScryptP is the P parameter of Scrypt encryption algorithm, using 4MB
// memory and taking approximately 100ms CPU time on a modern processor.
- LightScryptP = int(accounts.LightScryptP)
+ LightScryptP = int(keystore.LightScryptP)
)
// Account represents a stored key.
@@ -79,57 +80,73 @@ func (a *Account) GetAddress() *Address {
// GetFile retrieves the path of the file containing the account key.
func (a *Account) GetFile() string {
- return a.account.File
+ return a.account.URL
}
-// AccountManager manages a key storage directory on disk.
-type AccountManager struct{ manager *accounts.Manager }
+// KeyStore manages a key storage directory on disk.
+type KeyStore struct{ keystore *keystore.KeyStore }
-// NewAccountManager creates a manager for the given directory.
-func NewAccountManager(keydir string, scryptN, scryptP int) *AccountManager {
- return &AccountManager{manager: accounts.NewManager(keydir, scryptN, scryptP)}
+// NewKeyStore creates a keystore for the given directory.
+func NewKeyStore(keydir string, scryptN, scryptP int) *KeyStore {
+ return &KeyStore{keystore: keystore.NewKeyStore(keydir, scryptN, scryptP)}
}
// HasAddress reports whether a key with the given address is present.
-func (am *AccountManager) HasAddress(address *Address) bool {
- return am.manager.HasAddress(address.address)
+func (ks *KeyStore) HasAddress(address *Address) bool {
+ return ks.keystore.HasAddress(address.address)
}
// GetAccounts returns all key files present in the directory.
-func (am *AccountManager) GetAccounts() *Accounts {
- return &Accounts{am.manager.Accounts()}
+func (ks *KeyStore) GetAccounts() *Accounts {
+ return &Accounts{ks.keystore.Accounts()}
}
// DeleteAccount deletes the key matched by account if the passphrase is correct.
// If a contains no filename, the address must match a unique key.
-func (am *AccountManager) DeleteAccount(account *Account, passphrase string) error {
- return am.manager.Delete(accounts.Account{
- Address: account.account.Address,
- File: account.account.File,
- }, passphrase)
+func (ks *KeyStore) DeleteAccount(account *Account, passphrase string) error {
+ return ks.keystore.Delete(account.account, passphrase)
}
-// Sign calculates a ECDSA signature for the given hash. The produced signature
+// SignHash calculates a ECDSA signature for the given hash. The produced signature
// is in the [R || S || V] format where V is 0 or 1.
-func (am *AccountManager) Sign(address *Address, hash []byte) (signature []byte, _ error) {
- return am.manager.Sign(address.address, hash)
+func (ks *KeyStore) SignHash(address *Address, hash []byte) (signature []byte, _ error) {
+ return ks.keystore.SignHash(accounts.Account{Address: address.address}, hash)
}
-// SignPassphrase signs hash if the private key matching the given address can
+// SignTx signs the given transaction with the requested account.
+func (ks *KeyStore) SignTx(account *Account, tx *Transaction, chainID *BigInt) (*Transaction, error) {
+ signed, err := ks.keystore.SignTx(account.account, tx.tx, chainID.bigint)
+ if err != nil {
+ return nil, err
+ }
+ return &Transaction{signed}, nil
+}
+
+// SignHashPassphrase signs hash if the private key matching the given address can
// be decrypted with the given passphrase. The produced signature is in the
// [R || S || V] format where V is 0 or 1.
-func (am *AccountManager) SignPassphrase(account *Account, passphrase string, hash []byte) (signature []byte, _ error) {
- return am.manager.SignWithPassphrase(account.account, passphrase, hash)
+func (ks *KeyStore) SignHashPassphrase(account *Account, passphrase string, hash []byte) (signature []byte, _ error) {
+ return ks.keystore.SignHashWithPassphrase(account.account, passphrase, hash)
+}
+
+// SignTxPassphrase signs the transaction if the private key matching the
+// given address can be decrypted with the given passphrase.
+func (ks *KeyStore) SignTxPassphrase(account *Account, passphrase string, tx *Transaction, chainID *BigInt) (*Transaction, error) {
+ signed, err := ks.keystore.SignTxWithPassphrase(account.account, passphrase, tx.tx, chainID.bigint)
+ if err != nil {
+ return nil, err
+ }
+ return &Transaction{signed}, nil
}
// Unlock unlocks the given account indefinitely.
-func (am *AccountManager) Unlock(account *Account, passphrase string) error {
- return am.manager.TimedUnlock(account.account, passphrase, 0)
+func (ks *KeyStore) Unlock(account *Account, passphrase string) error {
+ return ks.keystore.TimedUnlock(account.account, passphrase, 0)
}
// Lock removes the private key with the given address from memory.
-func (am *AccountManager) Lock(address *Address) error {
- return am.manager.Lock(address.address)
+func (ks *KeyStore) Lock(address *Address) error {
+ return ks.keystore.Lock(address.address)
}
// TimedUnlock unlocks the given account with the passphrase. The account stays
@@ -139,14 +156,14 @@ func (am *AccountManager) Lock(address *Address) error {
// If the account address is already unlocked for a duration, TimedUnlock extends or
// shortens the active unlock timeout. If the address was previously unlocked
// indefinitely the timeout is not altered.
-func (am *AccountManager) TimedUnlock(account *Account, passphrase string, timeout int64) error {
- return am.manager.TimedUnlock(account.account, passphrase, time.Duration(timeout))
+func (ks *KeyStore) TimedUnlock(account *Account, passphrase string, timeout int64) error {
+ return ks.keystore.TimedUnlock(account.account, passphrase, time.Duration(timeout))
}
// NewAccount generates a new key and stores it into the key directory,
// encrypting it with the passphrase.
-func (am *AccountManager) NewAccount(passphrase string) (*Account, error) {
- account, err := am.manager.NewAccount(passphrase)
+func (ks *KeyStore) NewAccount(passphrase string) (*Account, error) {
+ account, err := ks.keystore.NewAccount(passphrase)
if err != nil {
return nil, err
}
@@ -154,13 +171,13 @@ func (am *AccountManager) NewAccount(passphrase string) (*Account, error) {
}
// ExportKey exports as a JSON key, encrypted with newPassphrase.
-func (am *AccountManager) ExportKey(account *Account, passphrase, newPassphrase string) (key []byte, _ error) {
- return am.manager.Export(account.account, passphrase, newPassphrase)
+func (ks *KeyStore) ExportKey(account *Account, passphrase, newPassphrase string) (key []byte, _ error) {
+ return ks.keystore.Export(account.account, passphrase, newPassphrase)
}
// ImportKey stores the given encrypted JSON key into the key directory.
-func (am *AccountManager) ImportKey(keyJSON []byte, passphrase, newPassphrase string) (account *Account, _ error) {
- acc, err := am.manager.Import(keyJSON, passphrase, newPassphrase)
+func (ks *KeyStore) ImportKey(keyJSON []byte, passphrase, newPassphrase string) (account *Account, _ error) {
+ acc, err := ks.keystore.Import(keyJSON, passphrase, newPassphrase)
if err != nil {
return nil, err
}
@@ -168,14 +185,14 @@ func (am *AccountManager) ImportKey(keyJSON []byte, passphrase, newPassphrase st
}
// UpdateAccount changes the passphrase of an existing account.
-func (am *AccountManager) UpdateAccount(account *Account, passphrase, newPassphrase string) error {
- return am.manager.Update(account.account, passphrase, newPassphrase)
+func (ks *KeyStore) UpdateAccount(account *Account, passphrase, newPassphrase string) error {
+ return ks.keystore.Update(account.account, passphrase, newPassphrase)
}
// ImportPreSaleKey decrypts the given Ethereum presale wallet and stores
// a key file in the key directory. The key file is encrypted with the same passphrase.
-func (am *AccountManager) ImportPreSaleKey(keyJSON []byte, passphrase string) (ccount *Account, _ error) {
- account, err := am.manager.ImportPreSaleKey(keyJSON, passphrase)
+func (ks *KeyStore) ImportPreSaleKey(keyJSON []byte, passphrase string) (ccount *Account, _ error) {
+ account, err := ks.keystore.ImportPreSaleKey(keyJSON, passphrase)
if err != nil {
return nil, err
}
diff --git a/mobile/android_test.go b/mobile/android_test.go
index 3776f8291..6f5076d64 100644
--- a/mobile/android_test.go
+++ b/mobile/android_test.go
@@ -43,42 +43,46 @@ public class AndroidTest extends InstrumentationTestCase {
public AndroidTest() {}
public void testAccountManagement() {
- // Create an encrypted keystore manager with light crypto parameters.
- AccountManager am = new AccountManager(getInstrumentation().getContext().getFilesDir() + "/keystore", Geth.LightScryptN, Geth.LightScryptP);
+ // Create an encrypted keystore with light crypto parameters.
+ KeyStore ks = new KeyStore(getInstrumentation().getContext().getFilesDir() + "/keystore", Geth.LightScryptN, Geth.LightScryptP);
try {
// Create a new account with the specified encryption passphrase.
- Account newAcc = am.newAccount("Creation password");
+ Account newAcc = ks.newAccount("Creation password");
// Export the newly created account with a different passphrase. The returned
// data from this method invocation is a JSON encoded, encrypted key-file.
- byte[] jsonAcc = am.exportKey(newAcc, "Creation password", "Export password");
+ byte[] jsonAcc = ks.exportKey(newAcc, "Creation password", "Export password");
// Update the passphrase on the account created above inside the local keystore.
- am.updateAccount(newAcc, "Creation password", "Update password");
+ ks.updateAccount(newAcc, "Creation password", "Update password");
// Delete the account updated above from the local keystore.
- am.deleteAccount(newAcc, "Update password");
+ ks.deleteAccount(newAcc, "Update password");
// Import back the account we've exported (and then deleted) above with yet
// again a fresh passphrase.
- Account impAcc = am.importKey(jsonAcc, "Export password", "Import password");
+ Account impAcc = ks.importKey(jsonAcc, "Export password", "Import password");
// Create a new account to sign transactions with
- Account signer = am.newAccount("Signer password");
- Hash txHash = new Hash("0x0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef");
+ Account signer = ks.newAccount("Signer password");
+
+ Transaction tx = new Transaction(
+ 1, new Address("0x0000000000000000000000000000000000000000"),
+ new BigInt(0), new BigInt(0), new BigInt(1), null); // Random empty transaction
+ BigInt chain = new BigInt(1); // Chain identifier of the main net
// Sign a transaction with a single authorization
- byte[] signature = am.signPassphrase(signer, "Signer password", txHash.getBytes());
+ Transaction signed = ks.signTxPassphrase(signer, "Signer password", tx, chain);
// Sign a transaction with multiple manually cancelled authorizations
- am.unlock(signer, "Signer password");
- signature = am.sign(signer.getAddress(), txHash.getBytes());
- am.lock(signer.getAddress());
+ ks.unlock(signer, "Signer password");
+ signed = ks.signTx(signer, tx, chain);
+ ks.lock(signer.getAddress());
// Sign a transaction with multiple automatically cancelled authorizations
- am.timedUnlock(signer, "Signer password", 1000000000);
- signature = am.sign(signer.getAddress(), txHash.getBytes());
+ ks.timedUnlock(signer, "Signer password", 1000000000);
+ signed = ks.signTx(signer, tx, chain);
} catch (Exception e) {
fail(e.toString());
}
diff --git a/mobile/types.go b/mobile/types.go
index 9ea70ea9b..a9c8cf68c 100644
--- a/mobile/types.go
+++ b/mobile/types.go
@@ -132,6 +132,11 @@ type Transaction struct {
tx *types.Transaction
}
+// NewTransaction creates a new transaction with the given properties.
+func NewTransaction(nonce int64, to *Address, amount, gasLimit, gasPrice *BigInt, data []byte) *Transaction {
+ return &Transaction{types.NewTransaction(uint64(nonce), to.address, amount.bigint, gasLimit.bigint, gasPrice.bigint, data)}
+}
+
func (tx *Transaction) GetData() []byte { return tx.tx.Data() }
func (tx *Transaction) GetGas() int64 { return tx.tx.Gas().Int64() }
func (tx *Transaction) GetGasPrice() *BigInt { return &BigInt{tx.tx.GasPrice()} }