Допис
Діліться своїми знаннями.

The Anatomy of a Secure DAO on Sui: Voting, Roles, and Objects
Decentralized Autonomous Organizations (DAOs) are a natural fit for Sui’s object-centric model. Unlike Ethereum-style smart contracts where governance often relies on storage mappings, Sui encourages structuring governance around Move objects. This leads to gas-efficient, modular, and secure designs.
In this post, we’ll explore how to design a secure DAO on Sui, focusing on voting, role-based permissions, and proposal execution.
Why Objects Instead of Mappings?
On Ethereum, DAOs often store proposals, votes, and roles in mappings (e.g., mapping(uint => Proposal)). This works, but updating global storage can become costly and prone to contention.
On Sui, each proposal and each role can be its own object:
Proposals are owned or shared objects.
Votes can be lightweight objects linked to proposals.
Roles are represented as capabilities — tokens that grant permissions.
This object-based model is inherently parallelizable and minimizes hotspots in shared state.
Core DAO Components
- DAO Root Object
Tracks governance parameters (quorum, proposal threshold, etc.).
Shared object, but kept tiny to reduce conflicts.
- Proposal Objects
Each proposal is a separate object created when a member submits one.
Stores metadata (description, deadline, vote counts).
- Vote Objects
Each vote is an owned object submitted by a member.
Proposal object tallies results by consuming or referencing votes.
- Roles via Capabilities
AdminCap: allows upgrading DAO parameters.
MemberCap: allows creating proposals and voting.
These capabilities are distributed at DAO creation and can later be delegated.
Sample Code: Roles + Proposal Voting
module dao::governance { use sui::object::{Self, UID}; use sui::tx_context::TxContext; use sui::transfer; use std::option;
/// Root DAO object
struct DAO has key {
id: UID,
quorum: u64,
proposal_count: u64,
}
/// Capability for admin operations
struct AdminCap has key, store { id: UID }
/// Capability for members
struct MemberCap has key, store { id: UID }
/// Proposal object
struct Proposal has key {
id: UID,
proposer: address,
description: vector<u8>,
yes_votes: u64,
no_votes: u64,
executed: bool,
}
/// Initialize DAO with one admin
public entry fun init(ctx: &mut TxContext): (DAO, AdminCap) {
let dao = DAO { id: object::new(ctx), quorum: 10, proposal_count: 0 };
let cap = AdminCap { id: object::new(ctx) };
(dao, cap)
}
/// Add a member capability (admin only)
public entry fun add_member(dao: &mut DAO, _admin: &AdminCap, ctx: &mut TxContext): MemberCap {
MemberCap { id: object::new(ctx) }
}
/// Create a proposal
public entry fun propose(
dao: &mut DAO,
_member: &MemberCap,
description: vector<u8>,
ctx: &mut TxContext
): Proposal {
dao.proposal_count = dao.proposal_count + 1;
Proposal {
id: object::new(ctx),
proposer: tx_context::sender(ctx),
description,
yes_votes: 0,
no_votes: 0,
executed: false,
}
}
/// Cast a vote
public entry fun vote(p: &mut Proposal, support: bool) {
if (support) {
p.yes_votes = p.yes_votes + 1;
} else {
p.no_votes = p.no_votes + 1;
}
}
/// Execute a proposal (if quorum met)
public entry fun execute(dao: &DAO, p: &mut Proposal) {
assert!(p.executed == false, 1);
assert!(p.yes_votes >= dao.quorum, 2);
p.executed = true;
// DAO-specific logic (e.g., transfer funds, change params) goes here
}
}
Security Considerations
Resource Safety: Capabilities (AdminCap, MemberCap) enforce who can act — no need to track roles in global storage.
Replay Protection: Ensure votes can’t be double-counted by consuming Vote objects.
Gas Efficiency: Proposals and votes are independent objects, so transactions can run in parallel without clashing.
Upgradability: DAO parameters (e.g., quorum) live in the root DAO object, adjustable only by AdminCap.
Best Practices
-
Keep the DAO root object small — don’t store vectors of all proposals or votes inside it.
-
Use dynamic fields or references only when absolutely necessary.
-
Push heavy analytics (e.g., full voting history) off-chain via events.
-
Build for parallelism: independent proposals and votes should not block each other.
-
Consider capability delegation if your DAO wants sub-committees or role hierarchies.
Conclusion
Sui’s object-based model enables DAOs that are more parallel, gas-efficient, and secure than traditional mapping-based governance. By structuring proposals, votes, and roles as objects, developers can create governance systems that scale gracefully while minimizing contention.
- Sui
- SDKs and Developer Tools
- Transaction Processing
Sui is a Layer 1 protocol blockchain designed as the first internet-scale programmable blockchain platform.
Зароби свою частку з 1000 Sui
Заробляй бали репутації та отримуй винагороди за допомогу в розвитку спільноти Sui.
- Чому BCS вимагає точного порядку полів для десеріалізації, коли структури Move мають названі поля?65
- Як максимізувати прибуток від SUI: Sui Staking проти Liquid Staking514
- Помилки перевірки кількох джерел» у публікаціях модуля Sui Move - автоматичне вирішення помилок55
- Помилка Sui Move - Неможливо обробити транзакцію Не знайдено дійсних газових монет для транзакції419
- Невдала операція Sui: об'єкти, зарезервовані для іншої транзакції49