github.com/piotrnar/gocoin@v0.0.0-20240512203912-faa0448c5e96/client/usif/textui/utxo.go (about) 1 package textui 2 3 import ( 4 "fmt" 5 "math" 6 "sort" 7 8 "github.com/piotrnar/gocoin/client/common" 9 "github.com/piotrnar/gocoin/lib/utxo" 10 ) 11 12 // inspired by https://bitcoinmagazine.com/technical/utxoracle-model-could-bring-use-cases-to-bitcoin 13 func wallet_usd(s string) { 14 const MIN_BTC_VALUE = 20e3 // 0.001 BTC (not included) 15 const MAX_BTC_VALUE = 1e6 // 0.01 BTC (not included) 16 const VALUE_MULTIPLIER = 1000.0 17 const TICK_SPAN = 2 18 19 var blocks_back int 20 var most_often_sent_usd_amount float64 21 blocks_back = 144 22 most_often_sent_usd_amount = 50.0 23 fmt.Sscanf(s, "%d %f", &blocks_back, &most_often_sent_usd_amount) 24 25 if blocks_back < 1 { 26 println("Only positiove block values are allowed") 27 return 28 } 29 if most_often_sent_usd_amount < 10 || most_often_sent_usd_amount > 2000 { 30 println("Use USD amount between 10 and 2000") 31 return 32 } 33 34 db := common.BlockChain.Unspent 35 36 min_index := int64(VALUE_MULTIPLIER * (math.Log10(MIN_BTC_VALUE))) 37 max_index := int64(VALUE_MULTIPLIER * (math.Log10(MAX_BTC_VALUE))) 38 39 fmt.Printf("Checking UTXO from the last %d blocks, assuming the most common amount was %.2f USD\n", blocks_back, most_often_sent_usd_amount) 40 41 var rec *utxo.UtxoRec 42 from_block := db.LastBlockHeight - uint32(blocks_back) 43 occ := make([]int64, max_index-min_index) 44 for i := range db.HashMap { 45 for k, v := range db.HashMap[i] { 46 rec = utxo.NewUtxoRecStatic(k, v) 47 if rec.InBlock < from_block { 48 continue 49 } 50 for _, o := range rec.Outs { 51 if o != nil && o.Value > MIN_BTC_VALUE && o.Value < MAX_BTC_VALUE { 52 v10 := int64(VALUE_MULTIPLIER * (math.Log10(float64(o.Value)))) 53 occ[v10-min_index]++ 54 } 55 } 56 } 57 } 58 59 srtd := make([][2]int, len(occ)-2) 60 var ccc int 61 for i := TICK_SPAN; i < len(occ)-TICK_SPAN; i++ { 62 val := occ[i] 63 for ts := 1; ts <= TICK_SPAN; ts++ { 64 val += occ[i-ts] >> ts 65 val += occ[i+ts] >> ts 66 } 67 srtd[ccc][0] = i 68 srtd[ccc][1] = int(val) 69 ccc++ 70 } 71 sort.Slice(srtd, func(i, j int) bool { return srtd[i][1] > srtd[j][1] }) 72 fmt.Println("Most commonly used amounts:") 73 for i := range srtd[:10] { 74 hhi := srtd[i][0] + int(min_index) 75 hhval := srtd[i][1] 76 xxx := math.Pow(10, float64(hhi)/VALUE_MULTIPLIER) 77 fmt.Printf("Found high count (%d) at %d (%d sats). Estimated BTC price: %d USD\n", 78 hhval, hhi, int(xxx), int(most_often_sent_usd_amount*1e8/xxx)) 79 } 80 81 } 82 83 func init() { 84 newUi("usd", true, wallet_usd, "Try to figure out recent BTC/USD price [block_count [most_common_usd]]") 85 }