diff --git a/wallet/cli/cli.go b/wallet/cli/cli.go index 95f950e..c50c13d 100644 --- a/wallet/cli/cli.go +++ b/wallet/cli/cli.go @@ -2,9 +2,9 @@ package cli import ( "fmt" - "github.com/manifoldco/promptui" "goXdagWallet/components" "goXdagWallet/config" + "goXdagWallet/fileutils" "goXdagWallet/xdago/base58" "goXdagWallet/xdago/common" "goXdagWallet/xdago/cryptography" @@ -12,6 +12,8 @@ import ( "goXdagWallet/xlog" "os" "path" + + "github.com/manifoldco/promptui" ) var WalletAccount components.WalletState @@ -118,7 +120,7 @@ func registerWallet() { if err := os.RemoveAll(pathDest); err != nil { fmt.Println("Clear dir failed", err) } - if err := os.MkdirAll(pathDest, 0666); err != nil { + if err := fileutils.MkdirAll(pathDest); err != nil { fmt.Println("Make dir failed", err) } components.PwdStr = WalletAccount.Password diff --git a/wallet/cli/run.go b/wallet/cli/run.go index b447a8e..0c7d3ff 100644 --- a/wallet/cli/run.go +++ b/wallet/cli/run.go @@ -161,11 +161,9 @@ func RunWallet(walletExists int) { fmt.Println("Get balance failed", errBlc) continue } - balance, _ := strconv.ParseFloat(fromValue, 64) - value, _ := strconv.ParseFloat(items[1], 64) - if balance < value { + + if !checkInput(fromValue, items[2], items[1], items[3], fromAddress) { spin.Stop() - fmt.Println("Insufficient amount") continue } errTx := components.TransferRpc(fromAddress, items[2], items[1], items[3], fromKey) @@ -192,3 +190,28 @@ func RunWallet(walletExists int) { } } } + +func checkInput(fromValue, toAddr, amount, remark, fromAddress string) bool { + if len(toAddr) == 0 || !components.ValidateBipAddress(toAddr) || fromAddress == toAddr { + fmt.Println("Receive Address format is incorrect.") + return false + } + + value, err := strconv.ParseFloat(amount, 64) + if err != nil || value <= 0.0 { + fmt.Println("Amount should be a positive number.") + return false + } + + balance, _ := strconv.ParseFloat(fromValue, 64) + if balance < value { + fmt.Println("Insufficient amount") + return false + } + + if len(remark) > 0 && !components.ValidateRemark(remark) { + fmt.Println("Remark format is incorrect") + return false + } + return true +} diff --git a/wallet/components/logon_win.go b/wallet/components/logon_win.go index 44dca3b..21cd645 100644 --- a/wallet/components/logon_win.go +++ b/wallet/components/logon_win.go @@ -6,6 +6,7 @@ import ( "errors" "fmt" "goXdagWallet/config" + "goXdagWallet/fileutils" "goXdagWallet/i18n" "goXdagWallet/xdago/common" "goXdagWallet/xlog" @@ -314,7 +315,7 @@ func CopyOldWallet(walletDir string) error { if err := os.RemoveAll(pathDest); err != nil { return err } - if err := os.MkdirAll(pathDest, 0666); err != nil { + if err := fileutils.MkdirAll(pathDest); err != nil { return err } if err := copyFile(walletDir, pathDest, "dnet_key.dat", 2048); err != nil { @@ -339,7 +340,7 @@ func (l *LogonWin) ImportMnemonic(data []byte) error { if err := os.RemoveAll(pathDest); err != nil { return err } - if err := os.MkdirAll(pathDest, 0666); err != nil { + if err := fileutils.MkdirAll(pathDest); err != nil { return err } @@ -496,7 +497,7 @@ func (l *LogonWin) CreateOrImport(pwd string) { i18n.GetString("WalletCreate_FilesFailed"), l.Win) return } - if err := os.MkdirAll(pathDest, 0666); err != nil { + if err := fileutils.MkdirAll(pathDest); err != nil { dialog.ShowInformation(i18n.GetString("Common_MessageTitle"), i18n.GetString("WalletCreate_FilesFailed"), l.Win) return diff --git a/wallet/components/rpc.go b/wallet/components/rpc.go index 6f7f66e..d05de70 100644 --- a/wallet/components/rpc.go +++ b/wallet/components/rpc.go @@ -73,7 +73,7 @@ func TransferRpc(from, to, amount, remark string, key *secp256k1.PrivateKey) err if hash != blockHash(blockHexStr) { return errors.New("transaction block hash error") } - xlog.Info("from:", from, ", to:", to, ", amount:", amount, ", transaction:", hash) + xlog.Info(from, "to", to, amount, "transaction:", hash) return nil } diff --git a/wallet/fileutils/mkdir_unix.go b/wallet/fileutils/mkdir_unix.go new file mode 100644 index 0000000..f9a7b62 --- /dev/null +++ b/wallet/fileutils/mkdir_unix.go @@ -0,0 +1,21 @@ +//go:build !windows + +package fileutils + +import ( + "os" + + "golang.org/x/sys/unix" +) + +func MkdirAll(p string) error { + mask := unix.Umask(0) // umask 0000 + defer unix.Umask(mask) // recover umask + return os.MkdirAll(p, 0777) +} + +func WriteFile(p string, data []byte) error { + mask := unix.Umask(0) // umask 0000 + defer unix.Umask(mask) // recover umask + return os.WriteFile(p, data, 0777) +} diff --git a/wallet/fileutils/mkdir_windows.go b/wallet/fileutils/mkdir_windows.go new file mode 100644 index 0000000..f5742e1 --- /dev/null +++ b/wallet/fileutils/mkdir_windows.go @@ -0,0 +1,13 @@ +//go:build windows + +package fileutils + +import "os" + +func MkdirAll(p string) error { + return os.MkdirAll(p, 0666) +} + +func WriteFile(p string, data []byte) error { + return os.WriteFile(p, data, 0666) +} diff --git a/wallet/go.mod b/wallet/go.mod index b2903b9..b89e726 100644 --- a/wallet/go.mod +++ b/wallet/go.mod @@ -14,6 +14,7 @@ require ( github.com/tyler-smith/go-bip39 v1.1.0 golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 golang.org/x/exp v0.0.0-20230127130021-4ca2cb1a16b7 + golang.org/x/sys v0.1.0 ) require ( @@ -37,7 +38,6 @@ require ( github.com/yuin/goldmark v1.3.8 // indirect golang.org/x/image v0.0.0-20200430140353-33d19683fad8 // indirect golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4 // indirect - golang.org/x/sys v0.1.0 // indirect golang.org/x/term v0.1.0 // indirect golang.org/x/text v0.3.3 // indirect gopkg.in/yaml.v2 v2.2.8 // indirect diff --git a/wallet/server/import_wallet.go b/wallet/server/import_wallet.go index a165deb..2a832bb 100644 --- a/wallet/server/import_wallet.go +++ b/wallet/server/import_wallet.go @@ -4,6 +4,7 @@ import ( "fmt" "goXdagWallet/cli" "goXdagWallet/components" + "goXdagWallet/fileutils" "goXdagWallet/xdago/common" bip "goXdagWallet/xdago/wallet" "os" @@ -23,7 +24,7 @@ func ImportServWallet() error { fmt.Println("Clear dir failed", err) return err } - if err = os.MkdirAll(pathDest, 0666); err != nil { + if err = fileutils.MkdirAll(pathDest); err != nil { fmt.Println("Make dir failed", err) return err } diff --git a/wallet/xdago/wallet/wallet.go b/wallet/xdago/wallet/wallet.go index a034c14..9e42a01 100644 --- a/wallet/xdago/wallet/wallet.go +++ b/wallet/xdago/wallet/wallet.go @@ -4,6 +4,7 @@ import ( "crypto/rand" "encoding/binary" "errors" + "goXdagWallet/fileutils" "goXdagWallet/xdago/common" "goXdagWallet/xdago/cryptography" "goXdagWallet/xdago/secp256k1" @@ -16,6 +17,8 @@ import ( "github.com/tyler-smith/go-bip32" "github.com/tyler-smith/go-bip39" + "github.com/tyler-smith/go-bip39/wordlists" + "golang.org/x/exp/slices" ) const ( @@ -230,11 +233,11 @@ func (w *Wallet) Flush() bool { dir := path.Dir(w.file) if _, err = os.Stat(dir); os.IsNotExist(err) { - if err = os.MkdirAll(dir, 0666); err != nil { + if err = fileutils.MkdirAll(dir); err != nil { xlog.Fatal("create wallet dir failed," + err.Error()) } } - err = os.WriteFile(w.file, wr.BytesUncheck(), 0666) + err = fileutils.WriteFile(w.file, wr.BytesUncheck()) if err != nil { xlog.Fatal("flush wallet data failed," + err.Error()) } @@ -481,7 +484,7 @@ func (w *Wallet) ExportDefKey(path string) error { return errors.New("no key to export") } b := key.Key.Bytes() - return os.WriteFile(path, b[:], 0666) + return fileutils.WriteFile(path, b[:]) } @@ -496,7 +499,7 @@ func (w *Wallet) ExportMnemonic(path string) error { if w.mnemonicPhrase == "" { return errors.New("no mnemonic to export") } - return os.WriteFile(path, []byte(w.mnemonicPhrase), 0666) + return fileutils.WriteFile(path, []byte(w.mnemonicPhrase)) } func ImportWalletFromDefKey(pathSrc, dirDest, pwd string) (*Wallet, error) { @@ -525,7 +528,12 @@ func ImportWalletFromMnemonicFile(pathSrc, dirDest, pwd string) (*Wallet, error) func ImportWalletFromMnemonicStr(mnemonic, dirDest, pwd string) (*Wallet, error) { words := strings.Fields(mnemonic) if len(words) < 12 || len(words) > 24 || len(words)%3 != 0 { - return nil, errors.New("mnemonic words count is not 15") + return nil, errors.New("mnemonic words count error") + } + for _, v := range words { + if !slices.Contains(wordlists.English, v) { + return nil, errors.New("unknown mnemonic words") + } } w := NewWallet(path.Join(dirDest, common.BIP32_WALLET_FOLDER, common.BIP32_WALLET_FILE_NAME)) w.password = pwd