github.com/harveynw/blokechain@v0.0.0-20221114193833-615a6ea7bba4/internal/wallet/wallet.go (about) 1 package wallet 2 3 import ( 4 "encoding/json" 5 "fmt" 6 "io/ioutil" 7 "math/big" 8 "os" 9 "github.com/harveynw/blokechain/internal/cryptography" 10 ) 11 12 // Wallet for holding multiple key pairs 13 type Wallet struct { 14 Addresses []Address 15 } 16 17 // Address for a holding a ECDSA public key, private key pair 18 type Address struct { 19 PublicKey cryptography.PublicKey 20 SecretKey *big.Int 21 } 22 23 // Save marshals wallet to file 24 func (wallet *Wallet) Save() { 25 data, marshalErr := json.MarshalIndent(wallet, "", " ") 26 if marshalErr != nil { 27 panic(marshalErr) 28 } 29 30 writeErr := ioutil.WriteFile(getWalletFile(), data, 0777) 31 if writeErr != nil { 32 panic(writeErr) 33 } 34 } 35 36 // Load unmarshals the Wallet after retrieval from file 37 func Load() *Wallet { 38 data, err := getWalletData() 39 40 if err != nil { 41 w := &Wallet{Addresses: make([]Address, 0)} 42 w.Save() 43 44 return w 45 } 46 47 w := &Wallet{} 48 marshalErr := json.Unmarshal(data, w) 49 50 if marshalErr != nil { 51 panic(fmt.Errorf("%v", marshalErr)) 52 } 53 54 return w 55 } 56 57 // Add adds a new keypair to the wallet and saves it 58 func (wallet *Wallet) Add(pubKey cryptography.PublicKey, secretKey *big.Int) { 59 addr := Address{PublicKey: pubKey, SecretKey: secretKey} 60 wallet.Addresses = append(wallet.Addresses, addr) 61 wallet.Save() 62 } 63 64 // GenerateNew creates a new keypair and saves it 65 func (wallet *Wallet) GenerateNew() string { 66 secretKey, pubKey := cryptography.RandomKeyPair() 67 wallet.Add(pubKey, secretKey) 68 return pubKey.ToAddress() 69 } 70 71 // ListAddresses returns a slice of the addresses in the wallet 72 func (wallet *Wallet) ListAddresses() (addresses []string) { 73 addresses = make([]string, 0) 74 for _, addr := range wallet.Addresses { 75 addresses = append(addresses, addr.PublicKey.ToAddress()) 76 } 77 return 78 } 79 80 81 func getWalletData() ([]byte, error) { 82 if _, err := os.Stat(getWalletFolder()); os.IsNotExist(err) { 83 os.Mkdir(getWalletFolder(), 0777) 84 } 85 if _, err := os.Stat(getWalletFile()); os.IsNotExist(err) { 86 return nil, err 87 } 88 return ioutil.ReadFile(getWalletFile()) 89 } 90 91 func getWalletFolder() string { 92 cwd, _ := os.Getwd() 93 return cwd + "/configs" 94 } 95 96 func getWalletFile() string { 97 return getWalletFolder() + "/wallet.json" 98 }