Realm detail
test2
gno.land/r/nym-encapsulate001/test2
Indexed deployment identity with independently loaded latest RPC source, functions, and Render.
Indexed deployment
Identity
- Package path
- gno.land/r/nym-encapsulate001/test2
- Block
- 269613
- Deployed (UTC)
- Transaction
- 3z6fPt14gsQkEilEw7TgLy5phTumQvJGuweoToFioEI=
Latest RPC state
Source
package test2
import (
"chain"
"chain/runtime"
"strconv"
"strings"
)
// Submit records a response to a form. Answers a1..a8 align with the form's
// fields in order; slots beyond the form's field count must be empty.
//
// gnoweb builds this call from the rendered form: each input is named after
// the parameter it fills, and parameters with no input arrive as "".
//
// The respondent pays the storage deposit for their own answers, and gets it
// back on Withdraw.
func Submit(cur realm, id string, a1, a2, a3, a4, a5, a6, a7, a8 string) {
author := mustUserCaller(cur)
f := mustGetForm(id)
height := runtime.ChainHeight()
if !f.IsOpen(height) {
if f.Deadline > 0 && height >= f.Deadline {
panic(ErrDeadlinePassed)
}
panic(ErrFormClosed)
}
if f.OnePerAddr && f.byAddr.Has(author.String()) {
panic(ErrAlreadyResponded)
}
answers := validateAnswers(f, []string{a1, a2, a3, a4, a5, a6, a7, a8})
rid := nextRespID.Next()
r := &Response{
ID: rid,
Form: f.ID,
Author: author,
Height: height,
Answers: answers,
}
f.responses.Set(rid.String(), r)
f.byAddr.Set(author.String(), rid.String())
chain.Emit("ResponseSubmitted", "form", id, "response", rid.String(), "author", author.String())
}
// Withdraw deletes the caller's response to a form. The storage deposit the
// answers were holding is refunded to the caller by the chain.
//
// Only the author can withdraw. Owners cannot delete responses: the refund
// goes to whoever deletes, which would hand the owner the respondent's
// deposit.
func Withdraw(cur realm, id string) {
author := mustUserCaller(cur)
f := mustGetForm(id)
raw := f.byAddr.Get(author.String())
if raw == nil {
panic(ErrNoResponse)
}
rid := raw.(string)
f.responses.Remove(rid)
f.byAddr.Remove(author.String())
chain.Emit("ResponseWithdrawn", "form", id, "response", rid, "author", author.String())
}
// validateAnswers checks every answer against its field and returns the
// trimmed answers, exactly len(f.Fields) long. Nothing is written before it
// returns, so a rejected submission leaves no trace.
func validateAnswers(f *Form, raw []string) []string {
n := len(f.Fields)
for i := n; i < len(raw); i++ {
if strings.TrimSpace(raw[i]) != "" {
panic(ErrTooManyAnswers)
}
}
answers := make([]string, n)
for i, field := range f.Fields {
a := strings.TrimSpace(raw[i])
if a == "" {
if field.Required {
panic(fieldErr(i, ErrRequired))
}
answers[i] = ""
continue
}
if len(a) > field.MaxLen() {
panic(fieldErr(i, ErrAnswerTooLong))
}
switch field.Kind {
case KindNumber:
if _, err := strconv.ParseFloat(a, 64); err != nil {
panic(fieldErr(i, ErrNotANumber))
}
case KindSelect:
if !contains(field.Options, a) {
panic(fieldErr(i, ErrNotAnOption))
}
}
answers[i] = a
}
return answers
}
func fieldErr(i int, err error) string {
return "field " + strconv.Itoa(i+1) + ": " + err.Error()
}
func contains(list []string, s string) bool {
for _, v := range list {
if v == s {
return true
}
}
return false
}
Latest RPC state
Exported functions
- Create(cur interface {.seal func(); Address func() .uverse.address; IsCode func() bool; IsCurrent func() bool; IsEphemeral func() bool; IsUser func() bool; IsUserCall func() bool; IsUserRun func() bool; PkgPath func() string; Previous func() .uverse.realm; String func() string; Sub func(string) .uverse.realm; Subpath func() string}, slug string, title string, description string, labels string, kinds string, required string, options string, onePerAddr bool, deadline int64) string
- CreateForm(cur interface {.seal func(); Address func() .uverse.address; IsCode func() bool; IsCurrent func() bool; IsEphemeral func() bool; IsUser func() bool; IsUserCall func() bool; IsUserRun func() bool; PkgPath func() string; Previous func() .uverse.realm; String func() string; Sub func(string) .uverse.realm; Subpath func() string}, slug string, title string, description string, l1 string, k1 string, r1 string, o1 string, l2 string, k2 string, r2 string, o2 string, l3 string, k3 string, r3 string, o3 string, l4 string, k4 string, r4 string, o4 string, l5 string, k5 string, r5 string, o5 string, l6 string, k6 string, r6 string, o6 string, l7 string, k7 string, r7 string, o7 string, l8 string, k8 string, r8 string, o8 string, onePerAddr string, deadline string) string
- Close(cur interface {.seal func(); Address func() .uverse.address; IsCode func() bool; IsCurrent func() bool; IsEphemeral func() bool; IsUser func() bool; IsUserCall func() bool; IsUserRun func() bool; PkgPath func() string; Previous func() .uverse.realm; String func() string; Sub func(string) .uverse.realm; Subpath func() string}, id string)
- Reopen(cur interface {.seal func(); Address func() .uverse.address; IsCode func() bool; IsCurrent func() bool; IsEphemeral func() bool; IsUser func() bool; IsUserCall func() bool; IsUserRun func() bool; PkgPath func() string; Previous func() .uverse.realm; String func() string; Sub func(string) .uverse.realm; Subpath func() string}, id string)
- TransferOwnership(cur interface {.seal func(); Address func() .uverse.address; IsCode func() bool; IsCurrent func() bool; IsEphemeral func() bool; IsUser func() bool; IsUserCall func() bool; IsUserRun func() bool; PkgPath func() string; Previous func() .uverse.realm; String func() string; Sub func(string) .uverse.realm; Subpath func() string}, id string, to string)
- GetForm(id string) (*gno.land/r/nym-encapsulate001/test2.Form, bool)
- ResponseCount(id string) int
- FormCount() int
- Render(path string) string
Forms
Publish a form, collect responses on chain, read them back here. Respondents fill it in on this page and pay their own storage deposit; withdrawing a response refunds it.
| Form | Status | Responses | Fields | Owner | | --- | --- | --- | --- | --- | | Boss Donkey | open | 1 | 1 | g1eyr3hf…x2v0 | | ss | expired | 1 | 1 | g1lyj99a…6u5q | | dwefewfw | closed | 0 | 2 | g1eyr3hf…x2v0 | | The big bad donkey | open | 2 | 5 | g1eyr3hf…x2v0 |
Create a form
Up to 8 fields. Blank rows are skipped. Submitting opens your wallet with the call already filled in.
From a terminal, Create takes the same thing as pipe-separated field specs — see the realm source.