implement key import and export

This commit is contained in:
whyrusleeping 2019-10-08 18:17:03 +09:00
parent 49e8b5d334
commit b40de6995b
5 changed files with 113 additions and 4 deletions

View File

@ -89,6 +89,8 @@ type FullNode interface {
WalletSign(context.Context, address.Address, []byte) (*types.Signature, error) WalletSign(context.Context, address.Address, []byte) (*types.Signature, error)
WalletSignMessage(context.Context, address.Address, *types.Message) (*types.SignedMessage, error) WalletSignMessage(context.Context, address.Address, *types.Message) (*types.SignedMessage, error)
WalletDefaultAddress(context.Context) (address.Address, error) WalletDefaultAddress(context.Context) (address.Address, error)
WalletExport(context.Context, address.Address) ([]byte, error)
WalletImport(context.Context, []byte) (address.Address, error)
// Other // Other

View File

@ -67,6 +67,9 @@ type FullNodeStruct struct {
WalletSign func(context.Context, address.Address, []byte) (*types.Signature, error) `perm:"sign"` WalletSign func(context.Context, address.Address, []byte) (*types.Signature, error) `perm:"sign"`
WalletSignMessage func(context.Context, address.Address, *types.Message) (*types.SignedMessage, error) `perm:"sign"` WalletSignMessage func(context.Context, address.Address, *types.Message) (*types.SignedMessage, error) `perm:"sign"`
WalletDefaultAddress func(context.Context) (address.Address, error) `perm:"write"` WalletDefaultAddress func(context.Context) (address.Address, error) `perm:"write"`
WalletExport func(context.Context, address.Address) ([]byte, error) `perm:"admin"`
WalletImport func(context.Context, []byte) (address.Address, error) `perm:"admin"`
MpoolGetNonce func(context.Context, address.Address) (uint64, error) `perm:"read"` MpoolGetNonce func(context.Context, address.Address) (uint64, error) `perm:"read"`
ClientImport func(ctx context.Context, path string) (cid.Cid, error) `perm:"write"` ClientImport func(ctx context.Context, path string) (cid.Cid, error) `perm:"write"`
@ -268,6 +271,14 @@ func (c *FullNodeStruct) WalletDefaultAddress(ctx context.Context) (address.Addr
return c.Internal.WalletDefaultAddress(ctx) return c.Internal.WalletDefaultAddress(ctx)
} }
func (c *FullNodeStruct) WalletExport(ctx context.Context, a address.Address) ([]byte, error) {
return c.Internal.WalletExport(ctx, a)
}
func (c *FullNodeStruct) WalletImport(ctx context.Context, b []byte) (address.Address, error) {
return c.Internal.WalletImport(ctx, b)
}
func (c *FullNodeStruct) MpoolGetNonce(ctx context.Context, addr address.Address) (uint64, error) { func (c *FullNodeStruct) MpoolGetNonce(ctx context.Context, addr address.Address) (uint64, error) {
return c.Internal.MpoolGetNonce(ctx, addr) return c.Internal.MpoolGetNonce(ctx, addr)
} }

View File

@ -2,8 +2,10 @@ package wallet
import ( import (
"context" "context"
"encoding/json"
"sort" "sort"
"strings" "strings"
"sync"
"github.com/filecoin-project/go-bls-sigs" "github.com/filecoin-project/go-bls-sigs"
"github.com/filecoin-project/go-lotus/node/repo" "github.com/filecoin-project/go-lotus/node/repo"
@ -23,6 +25,8 @@ const (
type Wallet struct { type Wallet struct {
keys map[address.Address]*Key keys map[address.Address]*Key
keystore types.KeyStore keystore types.KeyStore
lk sync.Mutex
} }
func NewWallet(keystore types.KeyStore) (*Wallet, error) { func NewWallet(keystore types.KeyStore) (*Wallet, error) {
@ -71,6 +75,9 @@ func (w *Wallet) Sign(ctx context.Context, addr address.Address, msg []byte) (*t
} }
func (w *Wallet) findKey(addr address.Address) (*Key, error) { func (w *Wallet) findKey(addr address.Address) (*Key, error) {
w.lk.Lock()
defer w.lk.Unlock()
k, ok := w.keys[addr] k, ok := w.keys[addr]
if ok { if ok {
return k, nil return k, nil
@ -91,11 +98,26 @@ func (w *Wallet) findKey(addr address.Address) (*Key, error) {
} }
func (w *Wallet) Export(addr address.Address) ([]byte, error) { func (w *Wallet) Export(addr address.Address) ([]byte, error) {
panic("nyi") k, err := w.findKey(addr)
if err != nil {
return nil, xerrors.Errorf("failed to find key to export: %w", err)
}
return json.Marshal(k)
} }
func (w *Wallet) Import(kdata []byte) (address.Address, error) { func (w *Wallet) Import(kdata []byte) (address.Address, error) {
panic("nyi") var ki types.KeyInfo
if err := json.Unmarshal(kdata, &ki); err != nil {
return address.Undef, xerrors.Errorf("failed to unmarshal input data: %w", err)
}
k, err := NewKey(ki)
if err != nil {
return address.Undef, xerrors.Errorf("failed to make key: %w", err)
}
return k.Address, nil
} }
func (w *Wallet) ListAddrs() ([]address.Address, error) { func (w *Wallet) ListAddrs() ([]address.Address, error) {
@ -148,6 +170,9 @@ func GenerateKey(typ string) (*Key, error) {
} }
func (w *Wallet) GenerateKey(typ string) (address.Address, error) { func (w *Wallet) GenerateKey(typ string) (address.Address, error) {
w.lk.Lock()
defer w.lk.Unlock()
k, err := GenerateKey(typ) k, err := GenerateKey(typ)
if err != nil { if err != nil {
return address.Undef, err return address.Undef, err

View File

@ -1,6 +1,7 @@
package cli package cli
import ( import (
"encoding/hex"
"fmt" "fmt"
"github.com/filecoin-project/go-lotus/chain/address" "github.com/filecoin-project/go-lotus/chain/address"
@ -14,6 +15,8 @@ var walletCmd = &cli.Command{
walletNew, walletNew,
walletList, walletList,
walletBalance, walletBalance,
walletExport,
walletImport,
}, },
} }
@ -97,3 +100,63 @@ var walletBalance = &cli.Command{
return nil return nil
}, },
} }
var walletExport = &cli.Command{
Name: "export",
Usage: "export keys",
Action: func(cctx *cli.Context) error {
api, closer, err := GetFullNodeAPI(cctx)
if err != nil {
return err
}
defer closer()
ctx := ReqContext(cctx)
if !cctx.Args().Present() {
return fmt.Errorf("must specify key to export")
}
addr, err := address.NewFromString(cctx.Args().First())
if err != nil {
return err
}
b, err := api.WalletExport(ctx, addr)
if err != nil {
return err
}
fmt.Println(hex.EncodeToString(b))
return nil
},
}
var walletImport = &cli.Command{
Name: "import",
Usage: "import keys",
Action: func(cctx *cli.Context) error {
api, closer, err := GetFullNodeAPI(cctx)
if err != nil {
return err
}
defer closer()
ctx := ReqContext(cctx)
if !cctx.Args().Present() {
return fmt.Errorf("must specify key import data")
}
data, err := hex.DecodeString(cctx.Args().First())
if err != nil {
return err
}
addr, err := api.WalletImport(ctx, data)
if err != nil {
return err
}
fmt.Printf("imported key %s successfully!", addr)
return nil
},
}

View File

@ -68,3 +68,11 @@ func (a *WalletAPI) WalletDefaultAddress(ctx context.Context) (address.Address,
// TODO: store a default address in the config or 'wallet' portion of the repo // TODO: store a default address in the config or 'wallet' portion of the repo
return addrs[0], nil return addrs[0], nil
} }
func (a *WalletAPI) WalletExport(ctx context.Context, addr address.Address) ([]byte, error) {
return a.Wallet.Export(addr)
}
func (a *WalletAPI) WalletImport(ctx context.Context, b []byte) (address.Address, error) {
return a.Wallet.Import(b)
}