PathrockNetwork Gno Explorer
HomeBlocksTransactionsTokensRealmsPackagesValidatorsAnalytics

PathrockNetwork Gno Explorer — an independent explorer for Gno.land Mainnet (gnoland-1), operated by PathrockNetwork. Not an official Gno.land service.

gnowebarchive RPC

gno.land/p/samcrew/daoauth

Package
Open in gnoweb ↗

Overview

Kind
Pure package
Name
daoauth
Namespace
samcrew
Files
2 (gnomod.toml)
Exported functions
n/a — not supported for pure packages by the node (vm/qfuncs)
Module
gno.land/p/samcrew/daoauth
gno
0.9

Files (2)

  • gnomod.tomltoml
  • daoauth.gnogno
daoauth.gnogno
1// Package daoauth writes the arguments of a governed action as one typed,2// canonical string. memba_gov stores that string with the proposal and the3// target realm rebuilds it from its real arguments when it consumes the4// approval: the two must be equal byte for byte. Each value has exactly one5// spelling, so equal actions always encode to equal strings.6//7// Fields are joined by "|":8//9//	u:<uint64>        decimal, no sign, no leading zero10//	i:<int64>         decimal, "-" only when negative, no leading zero11//	b:0 or b:1        bool12//	a:<address>       the lowercase bech32 text the chain gives a caller13//	s:<len>:<text>    length-prefixed printable ASCII (0x20-0x7E)14//15// Strings are compared as raw bytes, with no Unicode normalisation; text is16// printable ASCII so that what a voter reads is exactly what executes.17package daoauth1819import (20	"errors"21	"strconv"22	"strings"23)2425const (26	MaxArgs = 1024 // bytes of one encoded argument string27	MaxText = 512  // bytes of one string field28)2930var (31	ErrSyntax  = errors.New("daoauth: malformed argument string")32	ErrAddress = errors.New("daoauth: address is not lowercase bech32")33	ErrText    = errors.New("daoauth: text must be printable ASCII of at most 512 bytes")34	ErrLength  = errors.New("daoauth: arguments exceed 1024 bytes")35)3637// Args accumulates fields in order. Methods panic on a value that has no38// canonical form, so a realm can never build an approval nobody can match.39type Args struct{ fields []string }4041func New() *Args { return &Args{} }4243func (a *Args) Uint(v uint64) *Args { return a.add("u:" + strconv.FormatUint(v, 10)) }44func (a *Args) Int(v int64) *Args   { return a.add("i:" + strconv.FormatInt(v, 10)) }4546func (a *Args) Bool(v bool) *Args {47	if v {48		return a.add("b:1")49	}50	return a.add("b:0")51}5253func (a *Args) Addr(v address) *Args {54	if !ValidAddress(v) {55		panic(ErrAddress.Error())56	}57	return a.add("a:" + string(v))58}5960func (a *Args) Str(v string) *Args {61	if !ValidText(v) {62		panic(ErrText.Error())63	}64	return a.add("s:" + strconv.Itoa(len(v)) + ":" + v)65}6667func (a *Args) add(f string) *Args {68	a.fields = append(a.fields, f)69	return a70}7172// String returns the encoding. It panics past MaxArgs.73func (a *Args) String() string {74	s := strings.Join(a.fields, "|")75	if len(s) > MaxArgs {76		panic(ErrLength.Error())77	}78	return s79}8081// Field is one decoded value: Tag is 'u', 'i', 'b', 'a' or 's', and Value82// is its text, without the length prefix for strings.83type Field struct {84	Tag   byte85	Value string86}8788// Parse decodes s and refuses any text that is not the canonical encoding of89// its own fields. The empty string is the encoding of no fields.90func Parse(s string) ([]Field, error) {91	if len(s) > MaxArgs {92		return nil, ErrLength93	}94	var out []Field95	for len(s) > 0 {96		if len(s) < 2 || s[1] != ':' {97			return nil, ErrSyntax98		}99		tag, rest := s[0], s[2:]100		var v string101		if tag == 's' {102			i := strings.IndexByte(rest, ':')103			if i < 1 {104				return nil, ErrSyntax105			}106			n, err := strconv.Atoi(rest[:i])107			if err != nil || n < 0 || strconv.Itoa(n) != rest[:i] || n > len(rest)-i-1 {108				return nil, ErrSyntax109			}110			v, rest = rest[i+1:i+1+n], rest[i+1+n:]111			if !ValidText(v) {112				return nil, ErrText113			}114		} else {115			i := strings.IndexByte(rest, '|')116			if i < 0 {117				i = len(rest)118			}119			v, rest = rest[:i], rest[i:]120			if err := checkScalar(tag, v); err != nil {121				return nil, err122			}123		}124		out = append(out, Field{Tag: tag, Value: v})125		if len(rest) > 0 {126			if rest[0] != '|' || len(rest) == 1 {127				return nil, ErrSyntax128			}129			rest = rest[1:]130		}131		s = rest132	}133	return out, nil134}135136func checkScalar(tag byte, v string) error {137	switch tag {138	case 'u':139		n, err := strconv.ParseUint(v, 10, 64)140		if err != nil || strconv.FormatUint(n, 10) != v {141			return ErrSyntax142		}143	case 'i':144		n, err := strconv.ParseInt(v, 10, 64)145		if err != nil || strconv.FormatInt(n, 10) != v {146			return ErrSyntax147		}148	case 'b':149		if v != "0" && v != "1" {150			return ErrSyntax151		}152	case 'a':153		if !ValidAddress(address(v)) {154			return ErrAddress155		}156	default:157		return ErrSyntax158	}159	return nil160}161162// ValidText reports whether s is at most MaxText bytes of printable ASCII163// (0x20 to 0x7E): no control, invisible, combining or direction-changing164// character can make a value read differently from what executes.165func ValidText(s string) bool {166	if len(s) > MaxText {167		return false168	}169	for i := 0; i < len(s); i++ {170		if s[i] < 0x20 || s[i] > 0x7e {171			return false172		}173	}174	return true175}176177// The chain decodes four texts to one address: the lowercase bech32 text it178// gives a caller, that text in capitals, and the bech32m checksum in either179// case. Only the first ever equals cur.Previous().Address(). The check below180// is the one of launchpad meta/v1, copied rather than imported so governance181// does not depend on the Launchpad release. It reads the text instead of182// decoding it.183184// bech32Value holds, for each character of the bech32 alphabet, its 5-bit185// value plus one. Zero marks every other byte, capitals included.186var bech32Value = [256]byte{187	'q': 1, 'p': 2, 'z': 3, 'r': 4, 'y': 5, '9': 6, 'x': 7, '8': 8,188	'g': 9, 'f': 10, '2': 11, 't': 12, 'v': 13, 'd': 14, 'w': 15, '0': 16,189	's': 17, '3': 18, 'j': 19, 'n': 20, '5': 21, '4': 22, 'k': 23, 'h': 24,190	'c': 25, 'e': 26, '6': 27, 'm': 28, 'u': 29, 'a': 30, '7': 31, 'l': 32,191}192193// bech32Gen[t] is the XOR of the BIP-173 generators selected by the bits of t.194var bech32Gen = [32]uint32{195	0x00000000, 0x3b6a57b2, 0x26508e6d, 0x1d3ad9df,196	0x1ea119fa, 0x25cb4e48, 0x38f19797, 0x039bc025,197	0x3d4233dd, 0x0628646f, 0x1b12bdb0, 0x2078ea02,198	0x23e32a27, 0x18897d95, 0x05b3a44a, 0x3ed9f3f8,199	0x2a1462b3, 0x117e3501, 0x0c44ecde, 0x372ebb6c,200	0x34b57b49, 0x0fdf2cfb, 0x12e5f524, 0x298fa296,201	0x1756516e, 0x2c3c06dc, 0x3106df03, 0x0a6c88b1,202	0x09f74894, 0x329d1f26, 0x2fa7c6f9, 0x14cd914b,203}204205// bech32PrefixState is the checksum state after the prefix "g" (3, 0, 7).206const bech32PrefixState uint32 = 0x8c07207208// ValidAddress reports whether a is "g1" and 38 lowercase bech32 characters209// whose checksum is the original bech32 one.210func ValidAddress(a address) bool {211	s := string(a)212	if len(s) != 40 || s[0] != 'g' || s[1] != '1' {213		return false214	}215	chk := bech32PrefixState216	for i := 2; i < 40; i++ {217		v := bech32Value[s[i]]218		if v == 0 {219			return false220		}221		chk = (chk&0x1ffffff)<<5 ^ uint32(v-1) ^ bech32Gen[chk>>25]222	}223	return chk == 1224}225

Functions

not supported for pure packages by the node (vm/qfuncs)

Signatures reconstructed verbatim from vm/qfuncs — interface params keep their inline definitions.