Skip to content Search Apps Documentation Source Content File Folder Download Copy Actions State String Boolean Number Struct Map Slice Pointer Function Closure Reference Nil Package Type Interface Unknown

address.gno

2.20 Kb · 54 lines
 1package connect4
 2
 3// The chain decodes four texts to the same address: the bech32 form it gives
 4// a caller, that form in capitals, and the bech32m checksum in either case.
 5// An address argument stored as text and later compared with a caller's
 6// address must be that first form. canonical reads the text itself, which
 7// costs far less gas than decoding and re-encoding it. It is the check of
 8// gno.land/p/samcrew/launchpad/meta/v1 (ValidAddress), copied so this realm
 9// does not depend on that package being published.
10
11// bech32Value holds, for each character of the bech32 alphabet
12// "qpzry9x8gf2tvdw0s3jn54khce6mua7l", its 5-bit value plus one. Zero marks
13// every other byte, capitals included.
14var bech32Value = [256]byte{
15	'q': 1, 'p': 2, 'z': 3, 'r': 4, 'y': 5, '9': 6, 'x': 7, '8': 8,
16	'g': 9, 'f': 10, '2': 11, 't': 12, 'v': 13, 'd': 14, 'w': 15, '0': 16,
17	's': 17, '3': 18, 'j': 19, 'n': 20, '5': 21, '4': 22, 'k': 23, 'h': 24,
18	'c': 25, 'e': 26, '6': 27, 'm': 28, 'u': 29, 'a': 30, '7': 31, 'l': 32,
19}
20
21// bech32Gen[t] is the XOR of the BIP-173 generators selected by the five
22// bits of t: one table read per character instead of five tests.
23var bech32Gen = [32]uint32{
24	0x00000000, 0x3b6a57b2, 0x26508e6d, 0x1d3ad9df,
25	0x1ea119fa, 0x25cb4e48, 0x38f19797, 0x039bc025,
26	0x3d4233dd, 0x0628646f, 0x1b12bdb0, 0x2078ea02,
27	0x23e32a27, 0x18897d95, 0x05b3a44a, 0x3ed9f3f8,
28	0x2a1462b3, 0x117e3501, 0x0c44ecde, 0x372ebb6c,
29	0x34b57b49, 0x0fdf2cfb, 0x12e5f524, 0x298fa296,
30	0x1756516e, 0x2c3c06dc, 0x3106df03, 0x0a6c88b1,
31	0x09f74894, 0x329d1f26, 0x2fa7c6f9, 0x14cd914b,
32}
33
34// The checksum state once the address prefix "g" has been absorbed, which
35// BIP-173 expands to the values 3, 0, 7.
36const bech32PrefixState uint32 = 0x8c07
37
38// canonical reports whether a is "g1", then 38 lowercase bech32 characters
39// whose checksum is the original bech32 one: the form a caller's address has.
40func canonical(a address) bool {
41	s := string(a)
42	if len(s) != 40 || s[0] != 'g' || s[1] != '1' {
43		return false
44	}
45	chk := bech32PrefixState
46	for i := 2; i < 40; i++ {
47		v := bech32Value[s[i]]
48		if v == 0 {
49			return false
50		}
51		chk = (chk&0x1ffffff)<<5 ^ uint32(v-1) ^ bech32Gen[chk>>25]
52	}
53	return chk == 1 // 1 is bech32; bech32m ends on 0x2bc830a3
54}