예제 #1
0
func getChangeAddress(wltFile string, a string, c *gcli.Context) (string, error) {
	chgAddr := c.String("c")
	for {
		if chgAddr == "" {
			// get the default wallet's coin base address
			if a != "" {
				// use the from address as change address
				chgAddr = a
				break
			}

			if wltFile != "" {
				wlt, err := wallet.Load(wltFile)
				if err != nil {
					return "", err
				}
				if len(wlt.Entries) > 0 {
					chgAddr = wlt.Entries[0].Address.String()
					break
				}
				return "", errors.New("no change address was found")
			}
			return "", errors.New("both wallet file, from address and change address are empty")
		}
		break
	}

	// validate the address
	_, err := cipher.DecodeBase58Address(chgAddr)
	if err != nil {
		return "", fmt.Errorf("invalid change address: %s", chgAddr)
	}

	return chgAddr, nil
}
예제 #2
0
func getAddresses(f string) ([]string, error) {
	wlt, err := wallet.Load(f)
	if err != nil {
		return nil, err
	}

	addrs := make([]string, len(wlt.Entries))
	for i, entry := range wlt.Entries {
		addrs[i] = entry.Address.String()
	}
	return addrs, nil
}
예제 #3
0
func gatherAddrs(c *gcli.Context) ([]string, error) {
	w := c.String("f")
	var a string
	if c.NArg() > 0 {
		a = c.Args().First()
		if _, err := cipher.DecodeBase58Address(a); err != nil {
			return []string{}, fmt.Errorf("invalid address: %v", a)
		}
	}

	addrs := []string{}
	if w == "" && a == "" {
		// use default wallet
		w = filepath.Join(cfg.WalletDir, cfg.DefaultWalletName)
	}

	if w != "" {
		if !strings.HasSuffix(w, walletExt) {
			return []string{}, fmt.Errorf("error wallet file name, must has %v extension", walletExt)
		}

		if filepath.Base(w) == w {
			w = filepath.Join(cfg.WalletDir, w)
		} else {
			var err error
			w, err = filepath.Abs(w)
			if err != nil {
				return []string{}, err
			}
		}

		wlt, err := wallet.Load(w)
		if err != nil {
			return []string{}, err
		}

		addresses := wlt.GetAddresses()
		for _, a := range addresses {
			addrs = append(addrs, a.String())
		}
	}

	if a != "" {
		addrs = append(addrs, a)
	}

	return addrs, nil
}
예제 #4
0
func listWalletsCMD() gcli.Command {
	name := "listWallets"
	return gcli.Command{
		Name:         name,
		Usage:        "Lists all wallets stored in the default wallet directory",
		ArgsUsage:    " ",
		OnUsageError: onCommandUsageError(name),
		Action: func(c *gcli.Context) error {
			var wlts struct {
				Wallets []walletEntry `json:"wallets"`
			}

			entries, err := ioutil.ReadDir(cfg.WalletDir)
			if err != nil {
				return err
			}

			for _, e := range entries {
				if e.Mode().IsRegular() {
					name := e.Name()
					if !strings.HasSuffix(name, walletExt) {
						continue
					}

					path := filepath.Join(cfg.WalletDir, name)
					w, err := wallet.Load(path)
					if err != nil {
						return err
					}
					wlts.Wallets = append(wlts.Wallets, walletEntry{
						Name:       name,
						Label:      w.GetLabel(),
						AddressNum: len(w.Entries),
					})
				}
			}
			d, err := json.MarshalIndent(wlts, "", "    ")
			if err != nil {
				return errJSONMarshal
			}
			fmt.Println(string(d))
			return nil
		},
	}
	// Commands = append(Commands, cmd)
}
예제 #5
0
func generateAddrs(c *gcli.Context) error {
	// get number of address that are need to be generated.
	num := c.Uint("n")
	if num == 0 {
		return errors.New("-n must > 0")
	}

	jsonFmt := c.Bool("json")

	w := c.String("f")
	if !strings.HasSuffix(w, walletExt) {
		return errWalletName
	}

	// only wallet file name, no path.
	if filepath.Base(w) == w {
		w = filepath.Join(cfg.WalletDir, w)
	}

	wlt, err := wallet.Load(w)
	if err != nil {
		errorWithHelp(c, err)
		return nil
	}

	addrs := wlt.GenerateAddresses(int(num))
	dir, err := filepath.Abs(filepath.Dir(w))
	if err != nil {
		return err
	}

	if err := wlt.Save(dir); err != nil {
		return errors.New("save wallet failed")
	}

	s, err := addrResult(addrs, jsonFmt)
	if err != nil {
		return err
	}
	fmt.Println(s)
	return nil
}
예제 #6
0
func createRawTxFromAddress(addr string, chgAddr string, toAddr string, amt uint64) (string, error) {
	if (amt % 1e6) != 0 {
		return "", errors.New("skycoin coins must be multiple of 1e6")
	}

	// check if the address is in the default wallet.
	wlt, err := wallet.Load(filepath.Join(cfg.WalletDir, cfg.DefaultWalletName))
	if err != nil {
		return "", err
	}
	srcAddr, err := cipher.DecodeBase58Address(addr)
	if err != nil {
		return "", errAddress
	}

	_, ok := wlt.GetEntry(srcAddr)
	if !ok {
		return "", fmt.Errorf("%v address is not in wallet", addr)
	}

	// validate change address
	cAddr, err := cipher.DecodeBase58Address(chgAddr)
	if err != nil {
		return "", errAddress
	}

	// validate to address
	_, err = cipher.DecodeBase58Address(toAddr)
	if err != nil {
		return "", errAddress
	}

	_, ok = wlt.GetEntry(cAddr)
	if !ok {
		return "", fmt.Errorf("change address %v is not in wallet", chgAddr)
	}

	return makeTx([]string{addr}, chgAddr, toAddr, amt, wlt)
}
예제 #7
0
func listAddresses(c *gcli.Context) error {
	// get wallet name
	w := c.Args().First()
	if w == "" {
		w = filepath.Join(cfg.WalletDir, cfg.DefaultWalletName)
	}

	if !strings.HasSuffix(w, walletExt) {
		return errWalletName
	}

	if filepath.Base(w) == w {
		w = filepath.Join(cfg.WalletDir, w)
	}

	wlt, err := wallet.Load(w)
	if err != nil {
		return err
	}

	addrs := wlt.GetAddresses()
	var rlt = struct {
		Addresses []string `json:"addresses"`
	}{
		make([]string, len(addrs)),
	}

	for i, a := range addrs {
		rlt.Addresses[i] = a.String()
	}

	d, err := json.MarshalIndent(rlt, "", "    ")
	if err != nil {
		return errors.New("json marshal failed")
	}
	fmt.Println(string(d))
	return nil
}
예제 #8
0
func createRawTxFromWallet(wltPath string, chgAddr string, toAddr string, amt uint64) (string, error) {
	// validate the amt
	if (amt % 1e6) != 0 {
		return "", errors.New("skycoin coins must be multiple of 1e6")
	}

	// check if the change address is in wallet.
	wlt, err := wallet.Load(wltPath)
	if err != nil {
		return "", err
	}

	// check change address
	cAddr, err := cipher.DecodeBase58Address(chgAddr)
	if err != nil {
		return "", errAddress
	}

	// validate to address
	_, err = cipher.DecodeBase58Address(toAddr)
	if err != nil {
		return "", errAddress
	}

	_, ok := wlt.GetEntry(cAddr)
	if !ok {
		return "", fmt.Errorf("change address %v is not in wallet", chgAddr)
	}

	// get all address in the wallet
	totalAddrs := wlt.GetAddresses()
	addrStrArray := make([]string, len(totalAddrs))
	for i, a := range totalAddrs {
		addrStrArray[i] = a.String()
	}

	return makeTx(addrStrArray, chgAddr, toAddr, amt, wlt)
}
예제 #9
0
func addPrivateKeyCMD() gcli.Command {
	name := "addPrivateKey"
	return gcli.Command{
		Name:      name,
		Usage:     "Add a private key to specific wallet",
		ArgsUsage: "[private key]",
		Description: fmt.Sprintf(`Add a private key to specific wallet, the default
		wallet(%s/%s) will be 
		used if the wallet file or path is not specified`,
			cfg.WalletDir, cfg.DefaultWalletName),
		Flags: []gcli.Flag{
			gcli.StringFlag{
				Name:  "f",
				Usage: "[wallet file or path] private key will be added to this wallet",
			},
		},
		OnUsageError: onCommandUsageError(name),
		Action: func(c *gcli.Context) error {
			// get private key
			skStr := c.Args().First()
			if skStr == "" {
				gcli.ShowSubcommandHelp(c)
				return nil
			}

			// get wallet file path
			w := c.String("f")
			if w == "" {
				w = filepath.Join(cfg.WalletDir, cfg.DefaultWalletName)
			}

			if !strings.HasSuffix(w, walletExt) {
				return errWalletName
			}

			// only wallet file name, no path.
			if filepath.Base(w) == w {
				w = filepath.Join(cfg.WalletDir, w)
			}

			wlt, err := wallet.Load(w)
			if err != nil {
				errorWithHelp(c, err)
				return nil
			}

			sk, err := cipher.SecKeyFromHex(skStr)
			if err != nil {
				return fmt.Errorf("invalid private key: %s, must be an hex string of length 64", skStr)
			}

			pk := cipher.PubKeyFromSecKey(sk)
			addr := cipher.AddressFromPubKey(pk)

			entry := wallet.WalletEntry{
				Address: addr,
				Public:  pk,
				Secret:  sk,
			}

			if err := wlt.AddEntry(entry); err != nil {
				return err
			}

			dir, err := filepath.Abs(filepath.Dir(w))
			if err != nil {
				return err
			}

			if err := wlt.Save(dir); err != nil {
				return errors.New("save wallet failed")
			}

			fmt.Println("success")

			return nil
		},
	}
	// Commands = append(Commands, cmd)
}