func ComputePrivateKeyForAddress(addr *bitcoin.Address) string { mpk := bitcoin.LoadMPK(addr.MPKId) if mpk == nil { panic(NewError("Failed to find mpk %v", addr.MPKId)) } masterPrivKey, _ := masterPrivKeys.Get(mpk.PubKey).(string) if masterPrivKey == "" { panic(NewError("Failed to find privkey for mpk %v", mpk.PubKey)) } privKey := bitcoin.ComputePrivateKey(masterPrivKey, mpk.Chain, addr.ChainPath, addr.ChainIdx) derivedAddr := bitcoin.ComputeAddressForPrivKey(addr.Coin, privKey) if addr.Address != derivedAddr { panic(NewError("Computed invalid private key for address. addr: %v, derivedAddr: %v", addr.Address, derivedAddr)) } return privKey }
func computeAssets() { Info("Computing Assets...") // TODO: filter results by blockheight. coinAddressBalances := map[string]map[string]*AddressBalance{} rows, err := db.Query( `SELECT p.coin, p.address, p.amount, p.mpk_id, a.chain_path, a.chain_idx FROM payment AS p INNER JOIN address AS a ON p.address=a.address WHERE p.spent=0 AND p.orphaned=0`) if err != nil { panic(err) } for rows.Next() { var coin, address string var amount uint64 var mpkId int64 var chainPath string var chainIdx int32 err := rows.Scan(&coin, &address, &amount, &mpkId, &chainPath, &chainIdx) if err != nil { panic(err) } if coinAddressBalances[coin] == nil { coinAddressBalances[coin] = map[string]*AddressBalance{} } if coinAddressBalances[coin][address] == nil { coinAddressBalances[coin][address] = &AddressBalance{ Address: address, Amount: amount, ChainPath: fmt.Sprintf("%v/%v", chainPath, chainIdx), MPKId: mpkId, } } else { coinAddressBalances[coin][address].Amount += amount } } for coin, addressBalances := range coinAddressBalances { // Group addresses by MPK. var mpkBalances = map[int64][]*AddressBalance{} var sum uint64 for _, addrBalance := range addressBalances { sum += addrBalance.Amount mpkBalances[addrBalance.MPKId] = append(mpkBalances[addrBalance.MPKId], addrBalance) //fmt.Printf("[%v] %v\t%v\t%v\n", coin, address, addrBalance.ChainPath, addrBalance.Amount) } fmt.Printf("Total %v:\t%v\n", coin, sum) // Write to assets.json var mpkAssets = []interface{}{} for mpkId, addrBalances := range mpkBalances { mpk := bitcoin.LoadMPK(mpkId) mpkAsset := map[string]interface{}{ "public_key": mpk.PubKey, "chain": mpk.Chain, "assets": addrBalances, } mpkAssets = append(mpkAssets, mpkAsset) } dirPath := os.Getenv("HOME") + "/.ftnox.com/solvency/" + coin filePath := dirPath + "/assets.json" writeToFile(filePath, mpkAssets) } }