3

I am trying to generate multiple wallet addresses using single keystore file. Can someone please advise me if it is possible? OR one keystore can only have one wallet address?

I generate keystore and account simply by using following code

ks      := keystore.NewKeyStore("./dir", keystore.StandardScryptN, keystore.StandardScryptP)

// Create a new account with the specified encryption passphrase
newAcc, err     := ks.NewAccount(password)

// Return address & array
return newAcc.Address.String(), err

Issue that I am facing is that each time a new file is created due to function NewKeyStore. I am unable to find a suitable function in keystore.go that takes filename as path

Please help.

Thanks

1 Answer 1

1

Keystores from go-ethereum can only contain one wallet key pair per file. To generate keystores first you must invoke NewKeyStore giving it the directory path to save the keystores. After you may generate a new wallet by calling the method NewAccount passing it a password for encryption. Every time you call NewAccount it will generate a new keystore file on disk.

Here's a full example of generating a new keystore account:

package main

import (
    "fmt"
    "log"

    "github.com/ethereum/go-ethereum/accounts/keystore"
)

func main() {
    ks := keystore.NewKeyStore("./wallets", keystore.StandardScryptN, keystore.StandardScryptP)
    password := "secret"
    account, err := ks.NewAccount(password)
    if err != nil {
        log.Fatal(err)
    }

    fmt.Println(account.Address.Hex()) // 0x20F8D42FB0F667F2E53930fed426f225752453b3
}

Now to import your keystore is not really intuitive and I'm hoping someone can change the flow of this, or if someone knows of a better way, but basically you need to invoke NewKeyStore again as usual and then call the Import method which accepts the keystore JSON data as bytes. The second argument is the password used to encrypt it in order to decrypt it. The third argument is to specify a new encryption password but we'll use the same one in the example. Importing the account will give you access to the account as expected but it'll generate a new keystore file! There's no point in having two of the same thing so we'll delete the old one.

Here's a full example of importing a keystore and accessing the account.

package main

import (
    "fmt"
    "io/ioutil"
    "log"
    "os"

    "github.com/ethereum/go-ethereum/accounts/keystore"
)

func main() {
    file := "./wallets/UTC--2018-07-04T09-58-30.122808598Z--20f8d42fb0f667f2e53930fed426f225752453b3"
    ks := keystore.NewKeyStore("./tmp", keystore.StandardScryptN, keystore.StandardScryptP)
    jsonBytes, err := ioutil.ReadFile(file)
    if err != nil {
        log.Fatal(err)
    }

    password := "secret"
    account, err := ks.Import(jsonBytes, password, password)
    if err != nil {
        log.Fatal(err)
    }

    fmt.Println(account.Address.Hex()) // 0x20F8D42FB0F667F2E53930fed426f225752453b3

    if err := os.Remove(file); err != nil {
        log.Fatal(err)
    }
}

This is the way I'm able to restore the keystore but I'm hoping someone can shine some light on a cleaner way.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.