From 988a366a185a1171f54d893c0a4deb0cbd22f2d8 Mon Sep 17 00:00:00 2001 From: Gustav Simonsson Date: Fri, 13 Feb 2015 14:28:46 +0100 Subject: [PATCH] Add accounts association and use address to refer to accounts --- accounts/account_manager.go | 82 +++++++++++++++++++------------------ accounts/accounts_test.go | 7 +++- 2 files changed, 49 insertions(+), 40 deletions(-) diff --git a/accounts/account_manager.go b/accounts/account_manager.go index da0bd89004..a42a846a9b 100644 --- a/accounts/account_manager.go +++ b/accounts/account_manager.go @@ -35,61 +35,65 @@ package accounts import ( crand "crypto/rand" "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/ethdb" + "github.com/syndtr/goleveldb/leveldb" ) -// TODO: better name for this struct? +/* type Account struct { - Address []byte + Address []byte + AssociatedAddress []byte // e.g. a wallet contract "owned" by the account } +*/ type AccountManager struct { - keyStore crypto.KeyStore2 + keyStore crypto.KeyStore2 + accountsDb *ethdb.LDBDatabase } // TODO: get key by addr - modify KeyStore2 GetKey to work with addr // TODO: pass through passphrase for APIs which require access to private key? -func NewAccountManager(keyStore crypto.KeyStore2) AccountManager { - am := &AccountManager{ - keyStore: keyStore, +func NewAccountManager(keyStore crypto.KeyStore2) (AccountManager, error) { + db, err := ethdb.NewLDBDatabase("accounts") + if err != nil { + panic(err) } - return *am + am := &AccountManager{ + keyStore: keyStore, + accountsDb: db, + } + return *am, nil } -func (am *AccountManager) Sign(fromAccount *Account, keyAuth string, toSign []byte) (signature []byte, err error) { - key, err := am.keyStore.GetKey(fromAccount.Address, keyAuth) +func (am AccountManager) NewAccount(auth string) ([]byte, error) { + newKey, err := am.keyStore.GenerateNewKey(crand.Reader, auth) if err != nil { return nil, err } - signature, err = crypto.Sign(toSign, key.PrivateKey) + return newKey.Address, err +} + +func (am AccountManager) AssociateContract(ownerAddr []byte, associateAddr []byte) error { + am.accountsDb.Put(ownerAddr, associateAddr) + am.accountsDb.Put(associateAddr, ownerAddr) + return nil +} + +func (am *AccountManager) GetAssociatedAddr(addr []byte) ([]byte, error) { + res, err := am.accountsDb.Get(addr) + if err == leveldb.ErrNotFound { + return []byte{}, nil + } else { + return res, nil + } +} + +func (am *AccountManager) Sign(fromAddr []byte, keyAuth string, toSign []byte) ([]byte, error) { + key, err := am.keyStore.GetKey(fromAddr, keyAuth) + if err != nil { + return nil, err + } + signature, err := crypto.Sign(toSign, key.PrivateKey) return signature, err } - -func (am AccountManager) NewAccount(auth string) (*Account, error) { - key, err := am.keyStore.GenerateNewKey(crand.Reader, auth) - if err != nil { - return nil, err - } - ua := &Account{ - Address: key.Address, - } - return ua, err -} - -// set of accounts == set of keys in given key store -// TODO: do we need persistence of accounts as well? -func (am *AccountManager) Accounts() ([]Account, error) { - addresses, err := am.keyStore.GetKeyAddresses() - if err != nil { - return nil, err - } - - accounts := make([]Account, len(addresses)) - - for i, addr := range addresses { - accounts[i] = Account{ - Address: addr, - } - } - return accounts, err -} diff --git a/accounts/accounts_test.go b/accounts/accounts_test.go index da9406ebe8..52ef1fb16d 100644 --- a/accounts/accounts_test.go +++ b/accounts/accounts_test.go @@ -2,12 +2,17 @@ package accounts import ( "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/ethutil" "testing" ) +func init() { + ethutil.ReadConfig("/tmp/ethtest", "/tmp", "ETH") +} + func TestAccountManager(t *testing.T) { ks := crypto.NewKeyStorePlain(crypto.DefaultDataDir()) - am := NewAccountManager(ks) + am, _ := NewAccountManager(ks) pass := "" // not used but required by API a1, err := am.NewAccount(pass) toSign := crypto.GetEntropyCSPRNG(32)