utils.gno
2.72 Kb · 123 lines
1package block
2
3import (
4 "chain"
5 "chain/banker"
6 "net/url"
7 "strconv"
8
9 "gno.land/p/akkadia/v0/grc1155"
10)
11
12func copyStringMap(source map[string]string) map[string]string {
13 result := map[string]string{}
14 for k, v := range source {
15 result[k] = v
16 }
17 return result
18}
19
20func encodeStringMap(values map[string]string) string {
21 query := url.Values{}
22 for key, value := range values {
23 query.Set(key, value)
24 }
25 return query.Encode()
26}
27
28func decodeStringMap(encoded string) map[string]string {
29 values, err := url.ParseQuery(encoded)
30 if err != nil {
31 panic("invalid stored query string")
32 }
33
34 result := map[string]string{}
35 for key, entries := range values {
36 if len(entries) != 1 {
37 panic("invalid stored query string")
38 }
39 result[key] = entries[0]
40 }
41 return result
42}
43
44func blockIDToString(blockID uint32) string {
45 return strconv.FormatUint(uint64(blockID), 10)
46}
47
48func stringToBlockID(blockIDStr string) uint32 {
49 value, err := strconv.ParseUint(blockIDStr, 10, 32)
50 if err != nil {
51 panic("invalid blockID: " + err.Error())
52 }
53 return uint32(value)
54}
55
56func parseBlockID(blockIDStr string) (uint32, bool) {
57 value, err := strconv.ParseUint(blockIDStr, 10, 32)
58 if err != nil {
59 return 0, false
60 }
61 return uint32(value), true
62}
63
64func blockIDToTokenID(blockID uint32) grc1155.TokenID {
65 return grc1155.TokenID(blockIDToString(blockID))
66}
67
68func tokenIDToBlockID(tokenID grc1155.TokenID) uint32 {
69 return stringToBlockID(string(tokenID))
70}
71
72func tokenIDsToBlockIDs(tokenIDs []grc1155.TokenID) []uint32 {
73 blockIDs := make([]uint32, len(tokenIDs))
74 for i, tokenID := range tokenIDs {
75 blockIDs[i] = tokenIDToBlockID(tokenID)
76 }
77 return blockIDs
78}
79
80func calculateBPSShares(amount int64, bps int) (int64, int64) {
81 if amount <= 0 {
82 return 0, 0
83 }
84 if bps <= 0 {
85 return 0, amount
86 }
87 if bps >= 10000 {
88 return amount, 0
89 }
90
91 bps64 := int64(bps)
92 first := (amount/10000)*bps64 + (amount%10000)*bps64/10000
93 return first, amount - first
94}
95
96func distributeShares(cur realm, recipientStr string, feeCollector address, cost int64, bps int) (int64, int64) {
97 if cost <= 0 {
98 return 0, 0
99 }
100
101 recipientShare, feeCollectorShare := calculateBPSShares(cost, bps)
102 if recipientShare > 0 {
103 recipient := mustParseAddress(recipientStr)
104 send(cur, recipient, recipientShare)
105 }
106 if feeCollectorShare > 0 {
107 if !feeCollector.IsValid() {
108 panic("fee collector is invalid: " + feeCollector.String())
109 }
110 send(cur, feeCollector, feeCollectorShare)
111 }
112 return recipientShare, feeCollectorShare
113}
114
115func send(cur realm, to address, amount int64) {
116 if amount <= 0 {
117 panic("amount must be greater than 0")
118 }
119 bnk := banker.NewBanker(banker.BankerTypeRealmSend, cur)
120 realmAddr := cur.Address()
121 coins := chain.Coins{chain.Coin{"ugnot", amount}}
122 bnk.SendCoins(realmAddr, to, coins)
123}