v0 source pure
v0 - Unaudited: This is an initial version that has not yet been formally audited. A fully audited version will be pu...
View source
v0 - Unaudited This is an initial version of this package that has not yet been formally audited. A fully audited version will be published as a subsequent release. Use in production at your own risk.
CommonDAO Package
CommonDAO is a general-purpose package that provides support to implement custom Decentralized Autonomous Organizations (DAO) on Gno.land.
It offers a minimal and flexible framework for building DAOs, with customizable options that adapt across multiple use cases.
Core Types
Package contains some core types which are important in any DAO implementation, these are CommonDAO, ProposalDefinition, Proposal and Vote.
1. CommonDAO Type
CommonDAO type is the main type used to define DAOs, allowing standalone DAO creation or hierarchical tree based ones.
During creation, it accepts many optional arguments some of which are handy depending on the DAO type. For example, standalone DAOs might use IDs, a name and description to uniquely identify individual DAOs; Hierarchical ones might choose to use slugs instead of IDs, or even a mix of both.
DAO Creation Examples
Standalone DAO:
1import "gno.land/p/nt/commondao/v0"
2
3dao := commondao.New(
4 commondao.WithID(1),
5 commondao.WithName("MyDAO"),
6 commondao.WithDescription("An example DAO"),
7 commondao.WithMember("g1jg8mtutu9khhfwc4nxmuhcpftf0pajdhfvsqf5"),
8 commondao.WithMember("g1hy6zry03hg5d8le9s2w4fxme6236hkgd928dun"),
9)
Hierarchical DAO:
1import "gno.land/p/nt/commondao/v0"
2
3dao := commondao.New(
4 commondao.WithSlug("parent"),
5 commondao.WithName("ParentDAO"),
6 commondao.WithMember("g1jg8mtutu9khhfwc4nxmuhcpftf0pajdhfvsqf5"),
7)
8
9subDAO := commondao.New(
10 commondao.WithSlug("child"),
11 commondao.WithName("ChildDAO"),
12 commondao.WithParent(dao),
13)
2. ProposalDefinition Type
Proposal definitions are the way proposal types are implemented in commondao.
Definitions are required when creating a new proposal because they define the
behavior of the proposal.
Generally speaking, proposals can be divided in two types, one are the general (a.k.a. text proposals), and the other are the executable ones. The difference is that executable ones modify the blockchain state when they are executed after they have been approved, while general ones don't, they are usually used to signal or measure sentiment, for example regarding a relevant issue.
Creating a new proposal type requires implementing the following interface:
1type ProposalDefinition interface {
2 // Title returns proposal title.
3 Title() string
4
5 // Body returns proposal's body.
6 // It usually contains description or values that are specific to
7 // the proposal, like a description of the proposal's motivation
8 // or the list of values that would be applied when the proposal
9 // is approved.
10 Body() string
11
12 // VotingPeriod returns the period where votes are allowed after
13 // proposal creation. It's used to calculate the voting deadline
14 // from the proposal's creationd date.
15 VotingPeriod() time.Duration
16
17 // Tally counts the number of votes and verifies if proposal passes.
18 // It receives a voting context containing a readonly record with the votes
19 // that has been submitted for the proposal and also the list of DAO members.
20 Tally(VotingContext) (passes bool, _ error)
21}
This minimal interface is the one required for general proposal types. Here
the most important method is the Tally() one. It's used to check whether a
proposal passes or not.
Within Tally() votes can be counted using different rules depending on the
proposal type, some proposal types might decide if there is consensus by using
super majority while others might decide using plurality for example, or even
just counting that a minimum number of certain positive votes have been
submitted to approve a proposal.
CommonDAO provides a couple of helpers for this, to cover some cases:
SelectChoiceByAbsoluteMajority()SelectChoiceBySuperMajority()(using a 2/3s threshold)SelectChoiceByPlurality()
2.1. Executable Proposals
Proposal definitions have optional features that could be implemented to extend the proposal type behaviour. One of those is required to enable execution support.
A proposal can be executable implementing the Executable interface as part of the new proposal definition:
1type Executable interface {
2 // Executor returns a function to execute the proposal.
3 Executor() func(realm) error
4}
The crossing function returned by the Executor() method is where the realm
changes are made once the proposal is executed.
Other features can be enabled by implementing the Validable interface and the CustomizableVoteChoices one, as a way to separate pre-execution validation and to support proposal voting choices different than the default ones (YES, NO and ABSTAIN).
3. Proposal Type
Proposals are key for governance, they are the main mechanic that allows DAO members to engage on governance.
They are usually not created directly but though CommonDAO instances, by
calling the CommonDAO.Propose() or CommonDAO.MustPropose() methods. Though,
alternatively, proposals could be added to CommonDAO's active proposals storage
using CommonDAO.ActiveProposals().Add().
1import (
2 "gno.land/p/nt/commondao/v0"
3 "gno.land/r/example/mydao"
4)
5
6dao := commondao.New()
7creator := address("g1jg8mtutu9khhfwc4nxmuhcpftf0pajdhfvsqf5")
8propDef := mydao.NewGeneralProposalDefinition("Title", "Description")
9proposal := dao.MustPropose(creator, propDef)
3.1. Voting on Proposals
The preferred way to submit a vote, once a proposal is created, is by calling
the CommonDAO.Vote() method because it performs sanity checks before a vote
is considered valid; Alternatively votes can be directly added without sanity
checks to the proposal's voting record by calling
Proposal.VotingRecord().AddVote().
3.2. Voting Record
Each proposal keeps track of their submitted votes within an internal voting record. CommonDAO package defines it as a VotingRecord type.
The voting record of a proposal can be getted by calling its
Proposal.VotingRecord() method.
Right now proposals have a single voting record but the plan is to support multiple voting records per proposal as an optional feature, which could be used in cases where a proposal must track votes in multiple independent records, for example in cases where a proposal could be promoted to a different DAO with a different set of members.
4. Vote Type
Vote type defines the structure to store information for individual proposal
votes. Apart from the normally mandatory Address and voting Choice fields,
there are two optional fields that can be useful in different use cases; These
fields are Reason which can store a string with the reason for the vote, and
Context which can be used to store generic values related to the vote, for
example vote weight information.
It's very important to be careful when using the Context field, in case
references/pointers are assigned to it because they could potentially be
accessed anywhere, which could lead to unwanted indirect modifications.
Vote type is defined as:
1type Vote struct {
2 // Address is the address of the user that this vote belons to.
3 Address address
4
5 // Choice contains the voted choice.
6 Choice VoteChoice
7
8 // Reason contains an optional reason for the vote.
9 Reason string
10
11 // Context can store any custom voting values related to the vote.
12 Context any
13}
Secondary Types
There are other types which can be handy for some implementations which might require to store DAO members or proposals in a custom location, or that might need member grouping support.
1. MemberStorage and ProposalStorage Types
These two types allows storing and iterating DAO members and proposals. They support DAO implementations that might require storing either members or proposals in an external realm other than the DAO realm.
CommonDAO package provides implementations that use AVL trees under the hood for storage and lookup.
Custom implementations are supported though the MemberStorage and ProposalStorage interfaces:
1type MemberStorage interface {
2 // Size returns the number of members in the storage.
3 Size() int
4
5 // Has checks if a member exists in the storage.
6 Has(address) bool
7
8 // Add adds a member to the storage.
9 Add(address) bool
10
11 // Remove removes a member from the storage.
12 Remove(address) bool
13
14 // Grouping returns member groups when supported.
15 Grouping() MemberGrouping
16
17 // IterateByOffset iterates members starting at the given offset.
18 IterateByOffset(offset, count int, fn func(address) bool)
19}
20
21type ProposalStorage interface {
22 // Has checks if a proposal exists.
23 Has(id uint64) bool
24
25 // Get returns a proposal or nil when proposal doesn't exist.
26 Get(id uint64) *Proposal
27
28 // Add adds a proposal to the storage.
29 Add(*Proposal)
30
31 // Remove removes a proposal from the storage.
32 Remove(id uint64)
33
34 // Size returns the number of proposals that the storage contains.
35 Size() int
36
37 // Iterate iterates proposals.
38 Iterate(offset, count int, reverse bool, fn func(*Proposal) bool) bool
39}
2. MemberGrouping and MemberGroup Types
Members grouping is an optional feature that provides support for DAO members grouping.
Grouping can be useful for DAOs that require grouping users by roles or tiers for example.
The MemberGrouping type is a collection of member groups, while the MemberGroup is a group of members with metadata.
Grouping by Role Example
1import "gno.land/p/nt/commondao/v0"
2
3storage := commondao.NewMemberStorageWithGrouping()
4
5// Add a member that doesn't belong to any group
6storage.Add("g1...a")
7
8// Create a member group for owners
9owners, err := storage.Grouping().Add("owners")
10if err != nil {
11 panic(err)
12}
13
14// Add a member to the owners group
15owners.Members().Add("g1...b")
16
17// Add voting power to owners group metadata
18owners.SetMeta(3)
19
20// Create a member group for moderators
21moderators, err := storage.Grouping().Add("moderators")
22if err != nil {
23 panic(err)
24}
25
26// Add voting power to moderators group metadata
27moderators.SetMeta(1)
28
29// Add members to the moderators group
30moderators.Members().Add("g1...c")
31moderators.Members().Add("g1...d")
v0 - Unaudited: This is an initial version that has not yet been formally audited. A fully audited version will be published as a subsequent release. Use in production at your own risk.
Package provides support to implement custom Decentralized Autonomous Organizations (DAO). It aims to be minimal and flexible, allowing the implementation of multiple DAO use cases, like standalone or hierarchical tree based DAOs.
5
const ChoiceNone, ChoiceYes, ChoiceNo, ChoiceNoWithVeto, ChoiceAbstain
const QuorumOneThird, QuorumMoreThanHalf, QuorumTwoThirds, QuorumThreeFourths, QuorumFull
const MaxCustomVoteChoices
MaxCustomVoteChoices defines the maximum number of custom vote choices that a proposal definition can define.
const PathSeparator
PathSeparator is the separator character used in DAO paths.
3
var ErrExecutionNotAllowed, ErrInvalidVoteChoice, ErrNotMember, ErrOverflow, ErrProposalNotFound, ErrVotingDeadlineNotMet, ErrVotingDeadlinePassed, ErrWithdrawalNotAllowed
1var (
2 ErrExecutionNotAllowed = errors.New("proposal must pass before execution")
3 ErrInvalidVoteChoice = errors.New("invalid vote choice")
4 ErrNotMember = errors.New("account is not a member of the DAO")
5 ErrOverflow = errors.New("next ID overflows uint64")
6 ErrProposalNotFound = errors.New("proposal not found")
7 ErrVotingDeadlineNotMet = errors.New("voting deadline not met")
8 ErrVotingDeadlinePassed = errors.New("voting deadline has passed")
9 ErrWithdrawalNotAllowed = errors.New("withdrawal not allowed for proposals with votes")
10)var ErrInvalidCreatorAddress, ErrMaxCustomVoteChoices, ErrProposalDefinitionRequired, ErrNoQuorum, ErrStatusIsNotActive
1var (
2 ErrInvalidCreatorAddress = errors.New("invalid proposal creator address")
3 ErrMaxCustomVoteChoices = errors.New("max number of custom vote choices exceeded")
4 ErrProposalDefinitionRequired = errors.New("proposal definition is required")
5 ErrNoQuorum = errors.New("no quorum")
6 ErrStatusIsNotActive = errors.New("proposal status is not active")
7)var ErrVoteExists
ErrVoteExists indicates that a user already voted.
38
func CountStorageMembers
CountStorageMembers returns the total number of members in the storage. It counts all members in each group and the ones without group.
func IsQuorumReached
1func IsQuorumReached(quorum float64, r ReadonlyVotingRecord, members ReadonlyMemberStorage) boolIsQuorumReached checks if a participation quorum is reach.
func MustExecute
MustExecute executes an executable proposal or panics on error.
rlm is the realm authority threaded into the executor via cross(rlm). MustExecute itself is not a crossing function (rlm sits in a non-first parameter slot) because /p/ production code cannot declare crossing functions — callers pass `cur` directly as the rlm argument.
func MustValidate
MustValidate validates that a proposal is valid for the current state or panics on error.
func New
New creates a new common DAO.
func MustNewMemberGroup
MustNewMemberGroup creates a new group of members or panics on error.
func NewMemberGroup
NewMemberGroup creates a new group of members.
func NewMemberGrouping
NewMemberGrouping creates a new members grouping.
func UseStorageFactory
SECURITY XXX: UseStorageFactory captures a caller-supplied factory that returns the MemberStorage used to track who is a DAO member. A malicious factory can return a MemberStorage impl that lies about membership — always-true (everyone is a member, votes pass trivially) or always-false (legitimate members are locked out). This isn't a cur-leak; it's a behavior-substitution risk on the data layer the DAO's voting and proposal logic depends on. Fix: document that the factory must come from trusted code (a hardcoded constructor in the DAO realm itself), and never accept a UseStorageFactory option from external-realm input. Or restrict to a canonical-impl allowlist (type-switch on known MemberStorage types) in commondao itself.
UseStorageFactory assigns a custom member storage creation function to the grouping. Creation function is called each time a member group is added, with the name of the group as the only argument, to create a storage where the new group stores its members.
func WithGroups
WithGroups creates multiple members groups. To use a custom member storage factory to create the groups make sure that this option comes after the `UseStorageFactory()` option, otherwise groups are created using the default factory which is `commondao.NewMemberStorage()`.
func NewMemberStorage
NewMemberStorage creates a new member storage. Function returns a new member storage that doesn't support member groups. This type of storage is useful when there is no need to group members.
func NewMemberStorageWithGrouping
NewMemberStorageWithGrouping a new member storage with support for member groups. Member groups can be used by implementations that require grouping users by roles or by tiers for example.
func DisableVotingDeadlineCheck
DisableVotingDeadlineCheck disables voting deadline check when voting or executing proposals. By default CommonDAO checks that the proposal voting deadline has not been met when a new vote is submitted, before registering the vote, and on proposal execution it also checks that voting deadline has been met before executing a proposal.
Disabling these checks can be useful in different use cases, moving the responsibility to check the deadline to the commondao package caller. One example where this could be useful would be in case where 100% or a required number of members of a DAO vote on a proposal and reach consensus before the deadline is met, otherwise proposal would have to wait until deadline to be executed.
func WithActiveProposalStorage
WithActiveProposalStorage assigns a custom storage for active proposals. A default empty proposal storage is used when the custopm storage is nil. Custom storage implementations can be used to store proposals in a different location.
func WithChildren
WithChildren assigns one or more direct child SubDAOs to the DAO.
func WithDescription
WithDescription assigns a description to the DAO.
func WithFinishedProposalStorage
WithFinishedProposalStorage assigns a custom storage for finished proposals. A default empty proposal storage is used when the custopm storage is nil. Custom storage implementations can be used to store proposals in a different location.
func WithID
WithID assigns a unique identifier to the DAO.
func WithMember
WithMember assigns a member to the DAO.
func WithMemberStorage
WithMemberStorage assigns a custom member storage to the DAO. An empty member storage is used by default if the specified storage is nil.
func WithName
WithName assigns a name to the DAO.
func WithParent
WithParent assigns a parent DAO.
func WithSlug
WithSlug assigns a URL slug to the DAO.
func NewProposal
NewProposal creates a new DAO proposal.
func NewProposalStorage
NewProposalStorage creates a new proposal storage.
func MustNewReadonlyMemberGroup
MustNewReadonlyMemberGroup creates a new readonly member group or panics on error.
func NewReadonlyMemberGroup
NewReadonlyMemberGroup creates a new readonly member group.
func MustNewReadonlyMemberGrouping
MustNewReadonlyMemberGrouping creates a new grouping if member or panics on error.
func NewReadonlyMemberGrouping
NewReadonlyMemberGrouping creates a new grouping if member.
func MustNewReadonlyMemberStorage
MustNewReadonlyMemberStorage creates a new readonly member storage or panics on error.
func NewReadonlyMemberStorage
NewReadonlyMemberStorage creates a new readonly member storage.
func FindMostVotedChoice
FindMostVotedChoice returns the most voted choice. ChoiceNone is returned when there is a tie between different voting choices or when the voting record has are no votes.
func SelectChoiceByAbsoluteMajority
1func SelectChoiceByAbsoluteMajority(r ReadonlyVotingRecord, membersCount int) (VoteChoice, bool)SelectChoiceByAbsoluteMajority select the vote choice by absolute majority. Vote choice is a majority when chosen by more than half of the votes. Absolute majority considers abstentions when counting votes.
func SelectChoiceByPlurality
SelectChoiceByPlurality selects the vote choice by plurality. The choice will be considered a majority if it has votes and if there is no other choice with the same number of votes. A tie won't be considered majority.
func SelectChoiceBySuperMajority
1func SelectChoiceBySuperMajority(r ReadonlyVotingRecord, membersCount int) (VoteChoice, bool)SelectChoiceBySuperMajority select the vote choice by super majority using a 2/3s threshold. Abstentions are considered when calculating the super majority choice.
func MustNewVotingContext
MustNewVotingContext creates a new voting context or panics on error.
func NewVotingContext
NewVotingContext creates a new voting context.
func CollectVotes
CollectVotes returns an voting record containing votes of members from one or more groups. Returned tree uses member account address as key and `commondao.Vote` as value.
26
type CommonDAO
struct 1type CommonDAO struct {
2 id uint64
3 slug string
4 name string
5 description string
6 parent *CommonDAO
7 children list.IList
8 members MemberStorage
9 genID seqid.ID
10 activeProposals ProposalStorage
11 finishedProposals ProposalStorage
12 deleted bool // Soft delete
13 disableVotingDeadlineCheck bool
14}CommonDAO defines a DAO.
Methods on CommonDAO
func ActiveProposals
method on CommonDAOActiveProposals returns active DAO proposals.
func Children
method on CommonDAOChildren returns a list with the direct DAO children. Each item in the list is a reference to a CommonDAO instance.
func Description
method on CommonDAODescription returns DAO's description.
func Execute
method on CommonDAOExecute executes a proposal.
By default active proposals can only be executed after their voting deadline passes. DAO deadline checks can optionally be disabled using the `DisableVotingDeadlineCheck` option.
rlm is the realm authority threaded into the executor via cross(rlm). Execute itself is not a crossing function (rlm sits in a non-first parameter slot) because /p/ production code cannot declare crossing functions — callers pass `cur` directly as the rlm argument.
func FinishedProposals
method on CommonDAOFinishedProposalsi returns finished DAO proposals.
func GetProposal
method on CommonDAOGetProposal returns a proposal or nil when proposal is not found.
func ID
method on CommonDAOID returns DAO's unique identifier.
func IsDeleted
method on CommonDAOIsDeleted returns true when DAO has been soft deleted.
func Members
method on CommonDAOMembers returns the list of DAO members.
func MustPropose
method on CommonDAOMustPropose creates a new DAO proposal or panics on error.
func Name
method on CommonDAOName returns DAO's name.
func Parent
method on CommonDAOParent returns the parent DAO. Null can be returned when DAO has no parent assigned.
func Path
method on CommonDAOPath returns the full path to the DAO. Paths are normally used when working with hierarchical DAOs and is created by concatenating DAO slugs.
func Propose
method on CommonDAOPropose creates a new DAO proposal.
func SetDeleted
method on CommonDAOSetDeleted changes DAO's soft delete flag.
func Slug
method on CommonDAOSlug returns DAO's URL slug.
func TopParent
method on CommonDAOTopParent returns the topmost parent DAO. The top parent is the root of the DAO tree.
func Vote
method on CommonDAO1func (dao *CommonDAO) Vote(member address, proposalID uint64, c VoteChoice, reason string) errorVote submits a new vote for a proposal.
By default votes are only allowed to members of the DAO when the proposal is active, and within the voting period. No votes are allowed once the voting deadline passes. DAO deadline checks can optionally be disabled using the `DisableVotingDeadlineCheck` option.
func Withdraw
method on CommonDAOWithdraw withdraws a proposal that has no votes. Only proposals without votes can be withdrawn, and once withdrawn they are considered finished.
type CustomizableVoteChoices
interface1type CustomizableVoteChoices interface {
2 // CustomVoteChoices returns a list of valid voting choices.
3 // Choices are considered valid only when there are at least two possible choices
4 // otherwise proposal defaults to using YES, NO and ABSTAIN as valid choices.
5 CustomVoteChoices() []VoteChoice
6}CustomizableVoteChoices defines an interface for proposal definitions that want to customize the list of allowed voting choices.
type ExecFunc
funcExecFunc defines a type for functions that executes proposals.
type Executable
interfaceExecutable defines an interface for proposal definitions that modify state on approval. Once proposals are executed they are archived and considered finished.
type MemberGroup
interface 1type MemberGroup interface {
2 // Name returns the name of the group.
3 Name() string
4
5 // Members returns the members that belong to the group.
6 Members() MemberStorage
7
8 // SetMeta sets any metadata relevant to the group.
9 // Metadata can be used to store data which is specific to the group.
10 // Usually can be used to store parameter values which would be useful
11 // during proposal voting or tallying to resolve things like voting
12 // weights or rights for example.
13 SetMeta(any)
14
15 // GetMeta returns the group metadata.
16 GetMeta() any
17}MemberGroup defines an interface for a group of members.
type MemberGroupIterFn
funcMemberGroupIterFn defines a callback to iterate DAO members groups.
type MemberGrouping
interface 1type MemberGrouping interface {
2 // Size returns the number of groups that grouping contains.
3 Size() int
4
5 // Has checks if a group exists.
6 Has(name string) bool
7
8 // Add adds an new member group if it doesn't exists.
9 Add(name string) (MemberGroup, error)
10
11 // Get returns a member group.
12 Get(name string) (_ MemberGroup, found bool)
13
14 // Delete deletes a member group.
15 Delete(name string) error
16
17 // IterateByOffset iterates all member groups.
18 // The callback can return true to stop iteration.
19 IterateByOffset(offset, count int, fn MemberGroupIterFn) (stopped bool)
20}MemberGrouping defines an interface for storing multiple member groups. Member grouping can be used by implementations that require grouping users by roles or by tiers for example.
type MemberGroupingOption
funcMemberGroupingOption configures member groupings.
type MemberIterFn
funcMemberIterFn defines a callback to iterate DAO members.
type MemberStorage
interface 1type MemberStorage interface {
2 // Size returns the number of members in the storage.
3 Size() int
4
5 // Has checks if a member exists in the storage.
6 Has(address) bool
7
8 // Add adds a member to the storage.
9 // Returns true if the member is added, or false if it already existed.
10 Add(address) bool
11
12 // Remove removes a member from the storage.
13 // Returns true if member was removed, or false if it was not found.
14 Remove(address) bool
15
16 // Grouping returns member groups when supported.
17 // When nil is returned it means that grouping of members is not supported.
18 // Member groups can be used by implementations that require grouping users
19 // by roles or by tiers for example.
20 Grouping() MemberGrouping
21
22 // IterateByOffset iterates members starting at the given offset.
23 // The callback can return true to stop iteration.
24 IterateByOffset(offset, count int, fn MemberIterFn) (stopped bool)
25}MemberStorage defines an interface for member storages.
type Option
funcOption configures the CommonDAO.
type Proposal
struct 1type Proposal struct {
2 id uint64
3 status ProposalStatus
4 definition ProposalDefinition
5 creator address
6 record *VotingRecord // TODO: Add support for multiple voting records
7 statusReason string
8 voteChoices *bptree.BPTree // string(VoteChoice) -> struct{}
9 votingDeadline time.Time
10 createdAt time.Time
11}Proposal defines a DAO proposal.
Methods on Proposal
func CreatedAt
method on ProposalCreatedAt returns the time that proposal was created.
func Creator
method on ProposalCreator returns the address of the account that created the proposal.
func Definition
method on ProposalDefinition returns the proposal definition. Proposal definitions define proposal content and behavior.
func HasVotingDeadlinePassed
method on ProposalHasVotingDeadlinePassed checks if the voting deadline has been met.
func ID
method on ProposalID returns the unique proposal identifies.
func IsVoteChoiceValid
method on ProposalIsVoteChoiceValid checks if a vote choice is valid for the proposal.
func Status
method on ProposalStatus returns the current proposal status.
func StatusReason
method on ProposalStatusReason returns an optional reason that lead to the current proposal status. Reason is mostyl useful when a proposal fails.
func Tally
method on ProposalTally counts votes and updates proposal status with the current outcome. Proposal status is updated to "passed" when proposal is approved or to "rejected" if proposal doesn't pass.
func Validate
method on ProposalValidate validates that a proposal is valid for the current state. Validation is done when proposal status is active and when the definition supports validation.
func VoteChoices
method on ProposalVoteChoices returns the list of vote choices allowed for the proposal.
func VotingDeadline
method on ProposalVotingDeadline returns the deadline after which no more votes should be allowed.
func VotingRecord
method on ProposalVotingRecord returns a record that contains all the votes submitted for the proposal.
type ProposalDefinition
interface 1type ProposalDefinition interface {
2 // Title returns the proposal title.
3 Title() string
4
5 // Body returns proposal's body.
6 // It usually contains description or values that are specific to the proposal,
7 // like a description of the proposal's motivation or the list of values that
8 // would be applied when the proposal is approved.
9 Body() string
10
11 // VotingPeriod returns the period where votes are allowed after proposal creation.
12 // It is used to calculate the voting deadline from the proposal's creationd date.
13 VotingPeriod() time.Duration
14
15 // Tally counts the number of votes and verifies if proposal passes.
16 // It receives a voting context containing a readonly record with the votes
17 // that has been submitted for the proposal and also the list of DAO members.
18 Tally(VotingContext) (passes bool, _ error)
19}ProposalDefinition defines an interface for custom proposal definitions. These definitions define proposal content and behavior, they esentially allow the definition for different proposal types.
type ProposalStatus
identProposalStatus defines a type for different proposal states.
type ProposalStorage
interface 1type ProposalStorage interface {
2 // Has checks if a proposal exists.
3 Has(id uint64) bool
4
5 // Get returns a proposal or nil when proposal doesn't exist.
6 Get(id uint64) *Proposal
7
8 // Add adds a proposal to the storage.
9 Add(*Proposal)
10
11 // Remove removes a proposal from the storage.
12 Remove(id uint64)
13
14 // Size returns the number of proposals that the storage contains.
15 Size() int
16
17 // Iterate iterates proposals.
18 Iterate(offset, count int, reverse bool, fn func(*Proposal) bool) bool
19}ProposalStorage defines an interface for proposal storages.
type ReadonlyMemberGroup
structReadonlyMemberGroup defines a readonly member group.
type ReadonlyMemberGrouping
structReadonlyMemberGrouping defines a type for storing multiple readonly member groups.
Methods on ReadonlyMemberGrouping
func Get
method on ReadonlyMemberGroupingGet returns a member group.
func Has
method on ReadonlyMemberGroupingHas checks if a group exists.
func IterateByOffset
method on ReadonlyMemberGrouping1func (g ReadonlyMemberGrouping) IterateByOffset(offset, count int, fn func(*ReadonlyMemberGroup) bool) boolIterateByOffset iterates all member groups.
func Size
method on ReadonlyMemberGroupingSize returns the number of groups that grouping contains.
type ReadonlyMemberStorage
structReadonlyMemberStorage defines a readonly member storage.
Methods on ReadonlyMemberStorage
func Grouping
method on ReadonlyMemberStorageGrouping returns member groups.
func Has
method on ReadonlyMemberStorageHas checks if a member exists in the storage.
func IterateByOffset
method on ReadonlyMemberStorageIterateByOffset iterates members starting at the given offset. The callback can return true to stop iteration.
func Size
method on ReadonlyMemberStorageSize returns the number of members in the storage.
type ReadonlyVotingRecord
structReadonlyVotingRecord defines an read only voting record.
Methods on ReadonlyVotingRecord
func GetVote
method on ReadonlyVotingRecordGetVote returns a vote.
func HasVoted
method on ReadonlyVotingRecordHasVoted checks if an account already voted.
func Iterate
method on ReadonlyVotingRecordIterate iterates voting record votes.
func IterateVotesCount
method on ReadonlyVotingRecordIterateVotesCount iterates voted choices with the amount of votes submited for each.
func Size
method on ReadonlyVotingRecordSize returns the total number of votes that record contains.
func VoteCount
method on ReadonlyVotingRecordVoteCount returns the number of votes for a single voting choice.
type Validable
interfaceValidable defines an interface for proposal definitions that require state validation. Validation is done before execution and normally also during proposal rendering.
type Vote
struct 1type Vote struct {
2 // Address is the address of the user that this vote belons to.
3 Address address
4
5 // Choice contains the voted choice.
6 Choice VoteChoice
7
8 // Reason contains an optional reason for the vote.
9 Reason string
10
11 // Context can store any custom voting values related to the vote.
12 //
13 // Warning: When using context be careful if references/pointers are
14 // assigned to it because they could potentially be accessed anywhere,
15 // which could lead to unwanted indirect modifications.
16 Context any
17}Vote defines a single vote.
type VoteChoice
identVoteChoice defines a type for proposal vote choices.
type VoteIterFn
funcVoteIterFn defines a callback to iterate votes.
type VotesCountIterFn
funcVotesCountIterFn defines a callback to iterate voted choices.
type VotingContext
structVotingContext contains current voting context, which includes a voting record for the votes that has been submitted for a proposal and also the list of DAO members.
type VotingRecord
structVotingRecord stores accounts that voted and vote choices.
8
- errors stdlib
- gno.land/p/moul/addrset package
- gno.land/p/nt/bptree/v0 package
- gno.land/p/nt/bptree/v0/list package
- gno.land/p/nt/seqid/v0 package
- math stdlib
- strings stdlib
- time stdlib