💞 #Gate Square Qixi Celebration# 💞
Couples showcase love / Singles celebrate self-love — gifts for everyone this Qixi!
📅 Event Period
August 26 — August 31, 2025
✨ How to Participate
Romantic Teams 💑
Form a “Heartbeat Squad” with one friend and submit the registration form 👉 https://www.gate.com/questionnaire/7012
Post original content on Gate Square (images, videos, hand-drawn art, digital creations, or copywriting) featuring Qixi romance + Gate elements. Include the hashtag #GateSquareQixiCelebration#
The top 5 squads with the highest total posts will win a Valentine's Day Gift Box + $1
A New Chapter in the NEAR Ecosystem: In-depth Analysis of the Sputnik DAO Proposal Mechanism
Rust smart contracts Development Diary (10-3): Sputnik DAO Core Concepts - Proposal ( Analysis
Sputnik-DAO, as the infrastructure provided by the NEAR Protocol, is effectively driving the NEAR ecosystem towards a "decentralized" direction. Currently, the platform has facilitated the establishment of numerous "decentralized" autonomous communities for NEAR projects, while also providing a complete, flexible, and efficient community decision-making governance solution.
Sputnikdaov2 is a smart contract used for governance voting in the Sputnik-DAO community. This article will introduce the core concepts of this contract: Proposal ), and subsequent articles will introduce related DAO community governance models around "Proposal" ( Policy ).
1. Proposal Initiation ( Add Proposal )
Every member of the Sputnik-DAO community can express opinions or submit proposals regarding the governance or management of the project. Subsequently, each community member holding shares in the DAO can review and vote on the proposal. In other words, every member in the Sputnik-DAO can influence the future direction of the project by voting on others' proposals or initiating new management proposals themselves.
At the contract level, DAO community members can invoke the add_proposal() method provided by the sputnikdaov2 contract to initiate a new proposal.
rust u64
The proposer must provide detailed information for the proposal (ProposalInput):
The textual description of the proposal (Description). This information will be publicly displayed on the front end of the Sputnik-DAO homepage to help community members understand the purpose and significance of the proposal.
Type of proposal ( kind ). The proposer needs to select the type of opinion based on project management (, such as selecting FunctionCall type for calls to critical privilege functions of the smart contracts, selecting Transfer type for contract project fund transfers, and selecting ChangePolicyAddOrUpdateRole type for settings/changes in governance authority control levels, etc. )
The ProposalInput information will be passed as parameters to the add_proposal() method, which will further perform relevant checks and processing, and generate a proposal(Proposal) with complete initialization information. Ultimately, this proposal will be bound to a unique proposal_id and added to the Contract.proposals mapping maintained globally by the Sputnik-DAO smart contracts in the form of <key, value=""> in the proposal pool(.
The proposals defined by Sputnik-DAO have the following complete attribute information:
rust pub struct Proposal { pub id: u64, pub proposer: AccountId, pub description: String, pub kind: ProposalKind, pub status: ProposalStatus, pub vote_period_end: BlockHeight, pub vote_counts: HashMap<votepolicy, hashmap<accountid,="" balance="">>, pub votes: HashMap<accountid, vote="">, pub submission_time: Timestamp, }
In this proposal, the description and kind attributes will be extracted from the ProposalInput information provided by the proposer when creating the proposal. Specifically, the contract implements the type conversion from ProposalInput to Proposal using the From trait in Rust.
This conversion process binds more proposal status information:
The proposer in the newly added proposal )proposer( attribute will be automatically assigned to the caller of the add_proposal)( method, which is env::predecessor_account_id)(. This attribute is real and not under user control;
The newly added proposal status )status( is initialized by default as ProposalStatus::InProgress, which means it is still in the voting phase;
The initiation time of the newly added proposal )submission_time( is set to the timestamp of this block env::block_timestamp)(;
Since no one voted at the time the new proposal was submitted, the voting status )vote_counts, votes( are both initialized as empty HashMap::default)(.
It is important to note that there is a concept of proposal deposit )proposal_bond( in Sputnik-DAO, which will be managed according to the specific governance model of the Sputnik-DAO community )Policy(.
According to the relevant code, the contract requires the proposer to stake a certain amount of NEAR tokens as a deposit for the new proposal when calling the add_proposal)( method. This deposit will be refunded to the proposer by calling the contract's internal function internal_return_bonds)( when the proposal ends normally ) with community voting in favor ProposalStatus::Approved | community voting against ProposalStatus::Rejected(.
However, BlockSec previously found when interpreting the contract code at this point:
Sputnik-DAO does not maintain the historical proposal deposit amounts separately for each user when processing proposal deposits. When a user initiates a transaction and calls the contract method add_proposal)( to add a new proposal, they may attach more NEAR tokens than the policy.bounty_bond defined by the DAO governance strategy )Policy(. This will result in an excess deposit that will not be refunded to the proposer during the subsequent internal_return_bonds function execution.
After the BlockSec Team promptly contacted the project party, the issue )160 was ultimately resolved.
More verification and processing strategies related to the proposals executed within Sputnik-DAO will be detailed in the forthcoming "Rust smart contracts Development Diary (10-4) Sputnik DAO:: Community Governance Model Analysis."
2. Proposal Status(Proposal Status)
Any standard proposal in Sputnik-DAO may go through the following multiple states #158被确认并及时在PR# The new proposal state is initialized as: InProgress (
rust pub enum ProposalStatus { InProgress, Approved, Rejected, Removed, Expired, Moved, Failed, }
The proposal status changes in the proposal pool are driven by another method of the contract act_proposal)(.
Sputnik-DAO members can call the act_proposal)( method to perform the following operations on the specific proposal ) specified by the id (:
rust pub enum Action { AddProposal, RemoveProposal, VoteApprove, VoteReject, VoteRemove, Finalize, MoveToHub, }
Typically, for proposals in the InProgress state, DAO community members can call act_proposal)( to execute specific voting actions:
According to the implementation above, after the internal function update_votes)( is called, the program will actively call policy.proposal_status)( to carry out the voting work. For proposals that meet the voting threshold, the status of the proposal will be correspondingly changed.
After change:
If the proposal status is Approved, the proposal will be executed by calling internal_execute_proposal)(;
If the proposal status is Rejected or Removed, the proposal will perform subsequent closure operations by calling internal_reject_proposal)(.
It is worth mentioning that the difference between the Rejected and Removed states is that proposals ultimately determined to be in the Removed state will be directly removed from the proposal pool, and ) will be used as a penalty, meaning that the deposit originally staked will not be refunded to the proposer. In contrast, for proposals in the Rejected state, the proposal will remain in the proposal pool, and the corresponding deposit will be refunded.
3. Execute Proposal (
If a proposal is matched as Approved after the voting ends, at this point, the contract method act_proposal)( will continue to call the internal_execute_proposal)( function to execute the decision content contained in the proposal.
The types of proposals supported by Sputnik-DAO are listed as follows ) Most types of proposals involve updates to the configuration of the DAO governance model (:
Each type of proposal mentioned above has implemented the corresponding processing branch in the function internal_execute_proposal)(. This section will provide an in-depth introduction to two typical proposal processing workflows:
) 3.1 Contract function execution proposal execution ( ProposalKind::FunctionCall )
The function internal_execute_proposal() implements the following processing entry for proposals with ProposalKind as FunctionCall:
rust ProposalKind::FunctionCall { receiver_id, actions } => { let mut promise = Promise::new(receiver_id.clone)###(; for action in actions { promise = promise.function_call) action.method_name, action.args, action.deposit, action.gas, ( } promise.into)( }
When a proposal of the FunctionCall type is submitted, the specific function operation that the proposal is intended to execute has already been passed through the ProposalInput parameter at the time the proposer calls the add_proposal() method, namely actions).
NEAR contracts allow multiple consecutive function_call to be bound within a single Promise. Therefore, the actions set by the initial proposer can include the following types of ActionCall objects internally:
rust pub struct ActionCall { pub method_name: String, pub args: Vec, pub deposit: Balance, pub gas: Gas, }
Each ActionCall can specify the corresponding contract method name and method parameters, etc.
In summary, Sputnik-DAO completed the execution of the contract function execution type proposal in the form of Promise Batch Actions.
( 3.2 Contract Fund Transfer Proposal Execution ) ProposalKind::Transfer (
After the deployed NEAR smart contracts project has been running for a considerable amount of time, the contract account itself may have accumulated a significant amount of Fungible Token ), including the native NEAR token or other tokens that comply with the NEP-141 standard (.
At this time, members of the Sputnik-DAO community can consolidate these tokens into the specified receiver_id account by submitting a contract fund transfer proposal.
The same internal_execute_proposal)( also implements the corresponding processing entry for proposals with ProposalKind as Transfer:
rust ProposalKind::Transfer { token_id, receiver_id, amount } => { self.internal_payout)token_id, receiver_id, amount### .into() }
The underlying processing branch will call the internal_payout() function to implement transfer operations for different types of Fungible Tokens and different types of receiver_id( EOA or contract accounts).
4. Summary and Preview
This article has introduced the core concepts of the Sputnik DAO smart contracts - Proposal (, and also briefly explained how to create new proposals and vote for execution in Sputnik DAO, as well as the rules for changes in the related proposal basic status ).
The subsequent Rust smart contracts development diary will provide a more detailed description of the implementation and configuration of the governance model in Sputnik-DAO based on the proposal (Policy), so stay tuned!