func TestEncodeDecodePrivateKey(t *testing.T) { for x, test := range encodePrivateKeyTests { wif, err := btcutil.EncodePrivateKey(test.in, test.net, test.compressed) if err != nil { t.Errorf("%x: %v", x, err) continue } if wif != test.out { t.Errorf("TestEncodeDecodePrivateKey failed: want '%s', got '%s'", test.out, wif) continue } key, _, compressed, err := btcutil.DecodePrivateKey(test.out) if err != nil { t.Error(err) continue } if !bytes.Equal(key, test.in) || compressed != test.compressed { t.Errorf("TestEncodeDecodePrivateKey failed: want '%x', got '%x'", test.out, key) } } }
// ImportWIFPrivateKey takes a WIF-encoded private key and adds it to the // wallet. If the import is successful, the payment address string is // returned. func (a *Account) ImportWIFPrivateKey(wif string, bs *wallet.BlockStamp) (string, error) { // Decode WIF private key and perform sanity checking. privkey, net, compressed, err := btcutil.DecodePrivateKey(wif) if err != nil { return "", err } if net != a.Net() { return "", errors.New("wrong network") } // Attempt to import private key into wallet. a.mtx.Lock() addr, err := a.Wallet.ImportPrivateKey(privkey, compressed, bs) a.mtx.Unlock() if err != nil { return "", err } addrStr := addr.String() // Immediately write wallet to disk. a.ScheduleWalletWrite() if err := a.WriteScheduledToDisk(); err != nil { return "", fmt.Errorf("cannot write account: %v", err) } // Associate the imported address with this account. MarkAddressForAccount(addrStr, a.Name()) log.Infof("Imported payment address %v", addrStr) // Return the payment address string of the imported private key. return addrStr, nil }
// ImportPrivKey handles an importprivkey request by parsing // a WIF-encoded private key and adding it to an account. func ImportPrivKey(icmd btcjson.Cmd) (interface{}, *btcjson.Error) { // Type assert icmd to access parameters. cmd, ok := icmd.(*btcjson.ImportPrivKeyCmd) if !ok { return nil, &btcjson.ErrInternal } // Get the acount included in the request. Yes, Label is the // account name... a, err := AcctMgr.Account(cmd.Label) switch err { case nil: break case ErrNotFound: return nil, &btcjson.ErrWalletInvalidAccountName default: e := btcjson.Error{ Code: btcjson.ErrWallet.Code, Message: err.Error(), } return nil, &e } pk, net, compressed, err := btcutil.DecodePrivateKey(cmd.PrivKey) if err != nil || net != a.Net() { return nil, &btcjson.ErrInvalidAddressOrKey } // Import the private key, handling any errors. bs := &wallet.BlockStamp{} switch _, err := a.ImportPrivateKey(pk, compressed, bs); err { case nil: // If the import was successful, reply with nil. return nil, nil case wallet.ErrDuplicate: // Do not return duplicate key errors to the client. return nil, nil case wallet.ErrWalletLocked: return nil, &btcjson.ErrWalletUnlockNeeded default: e := btcjson.Error{ Code: btcjson.ErrWallet.Code, Message: err.Error(), } return nil, &e } }