package main import ( "bytes" "crypto/elliptic" "encoding/gob" "fmt" "io/ioutil" "os" ) const version = byte(0x00) const walletFile = "wallet.dat" const addressChecksumLen = 4 // Wallets is pretty self-explanatory type Wallets struct { Wallets map[string]*Wallet } // NewWallets creates Wallets and fills it from a file if it exists func NewWallets() (*Wallets, error) { wallets := Wallets{} wallets.Wallets = make(map[string]*Wallet) err := wallets.LoadFromFile() return &wallets, err } // CreateWallet adds a Wallet to Wallets func (ws *Wallets) CreateWallet() string { wallet := NewWallet() address := fmt.Sprintf("%s", wallet.GetAddress()) ws.Wallets[address] = wallet return address } // GetAddresses returns an array of addresses stored in the wallet file func (ws *Wallets) GetAddresses() []string { var addresses []string for address := range ws.Wallets { addresses = append(addresses, address) } return addresses } // GetWallet returns a wallet by its address func (ws Wallets) GetWallet(address string) Wallet { return *ws.Wallets[address] } // LoadFromFile loads wallets from the file func (ws *Wallets) LoadFromFile() error { if _, err := os.Stat(walletFile); os.IsNotExist(err) { return err } fileContent, err := ioutil.ReadFile(walletFile) if err != nil { exitWithError(err) } var wallets Wallets gob.Register(elliptic.P256()) decoder := gob.NewDecoder(bytes.NewReader(fileContent)) err = decoder.Decode(&wallets) if err != nil { exitWithError(err) } ws.Wallets = wallets.Wallets return nil } // SaveToFile saves the wallets to a file func (ws Wallets) SaveToFile() { var content bytes.Buffer gob.Register(elliptic.P256()) encoder := gob.NewEncoder(&content) err := encoder.Encode(ws) if err != nil { exitWithError(err) } err = ioutil.WriteFile(walletFile, content.Bytes(), 0644) if err != nil { exitWithError(err) } }