Let`s move - sui move开发实战-dao(3)

引言

经过之前的学习,准备进行实战开发一个简单的dao项目,实现一个去中心化自治组织,用于管理共享资金、社区任务、提案和投票等功能,本篇文章分享了提案模块、错误定义。

提案设计

关于提案模式的具体设计:

  1. dao member又提案的权利
  2. 为了减少废案,规定提案需要支付一些dao代币(5)
  3. 提案被成功接受,根据提案等级,提案者会获得不同的dao代币奖励
  4. 其余dao member可以对提案进行投票,1 dao代币对应1 票,提案时需要将dao代币质押,获取对应凭证,在提案结束后可以销毁凭证取回dao代币
  5. core member可以管理提案,控制提案关闭时间,变更提案等级等。

const

    const MAX_VOTES_ONE_TIME: u64 = 10;const TOTAL_SUPPLY:u64 = 100_000_000_000_000_000;const PROPOSAL_FEE:u64 = 5;const LEVEL0_REWARD:u64 = 0;const LEVEL1_REWARD:u64 = 10;const LEVEL2_REWARD:u64 = 15;const LEVEL3_REWARD:u64 = 30;

首先定义了一些常量,代表提案花费,各个等级的提案奖励。

proposal

    struct Proposal has key,store{id: UID,title: String, //The title of the proposaldescribe: String, //Content of the Proposallevel: u64,proposer: address, //Initiator of the Proposallock_balance: u64, //DAO Tokens Locked by the Proposalsupport: u64, //Number of votes in favor of the proposalagainst: u64, //Number of votes against the proposalis_closed: bool, is_passed: bool,is_claimed_reward: bool,}

提案结构体,包括提案题目,描述,等级,提案者,投票总数,赞成反对票数,是否关闭,是否通过,是否已经领取奖励等字段。

投票凭证

    struct VoteCap has key{id: UID,proposal_id: ID,voter: address,is_support: bool,votes: u64,}

投票凭证,用户投票后会生成相应的投票凭证,在提案结束后销毁凭证取回质押的dao

发起提案

    public fun submit_proposal(member_cap:&MemberCap,title: String, describe:String, level:u64, coin:&mut Coin<DAO>,treasury:&mut Treasury<DAO>,ctx:&mut TxContext){//1.Verify Membership in the DAOcheck_membercap_role(member_cap, ctx);//2.Pay Proposal Feetransfer_coin_to_treasury(treasury,coin, PROPOSAL_FEE);//3.get duration time//4.Create Proposallet proposal = Proposal {id: object::new(ctx),title: title, //The title of the proposaldescribe: describe, //Content of the Proposallevel: level,proposer: member_cap.role_address, //Initiator of the Proposallock_balance: 0, //DAO Tokens Locked by the Proposalsupport: 0, //Number of votes in favor of the proposalagainst: 0, //Number of votes against the proposalis_closed: false,is_passed: false,is_claimed_reward: false,};transfer::share_object(proposal);}
  1. 首先验证提案者的身份
  2. 支付提案费
  3. 创建提案obj 设置为share对象

投票

    public fun vote(member_cap:&MemberCap, proposal:&mut Proposal, votes:u64, is_support:bool, coin:&mut Coin<DAO>, treasury:&mut Treasury<DAO>,ctx:&mut TxContext){//1. verifycheck_membercap_role(member_cap,ctx);assert!(!proposal.is_closed,EProposalClosed);assert!(member_cap.role_address != proposal.proposer, EVoteSelf);assert!(votes >= 1  && votes <= MAX_VOTES_ONE_TIME, EInvailVotes);check_membercap_role(member_cap, ctx);//2. transfer daotransfer_coin_to_treasury(treasury,coin,votes);//3. change proposalupdate_proposal_vote(proposal,votes,is_support);//4. distrubte voteCaplet vote_cap = VoteCap {id: object::new(ctx),proposal_id:object::uid_to_inner(&proposal.id),voter: member_cap.role_address,is_support: is_support,votes: votes,};transfer::transfer(vote_cap, member_cap.role_address);}
  1. 验证投票者身份
  2. 对提案的状态进行检查 查看是否关闭 提案者不能为自己投票 投票数不能超贵最大限制
  3. 质押相应的dao 代币
  4. 更改提案数据
  5. 颁发投票凭证

manage

    public fun change_proposal_level(core_cap:& CoreCap, proposal:&mut Proposal, new_level:u64 ,ctx:&mut TxContext){check_corecap_role(core_cap,ctx);assert!(!proposal.is_closed, EProposalClosed);proposal.level = new_level;}public fun close_proposal(core_cap:& CoreCap,proposal:&mut Proposal,ctx:&mut TxContext){check_corecap_role(core_cap,ctx);assert!(!proposal.is_closed, EProposalClosed);if(proposal.against == 0 || (proposal.support * 2) / 3 >= proposal.against){proposal.is_passed = true;};proposal.is_closed = true;}

core member可以对提案进行管理 更改等级或关闭提案

取回票据

    public fun claim_proposal_vote(member_cap:&MemberCap, proposal:&mut Proposal, vote_cap: VoteCap,treasury:&mut Treasury<DAO>, ctx:&mut TxContext){// 1.veriry the parameterscheck_membercap_role(member_cap,ctx);assert!(&vote_cap.proposal_id == object::borrow_id(proposal), EProposalCheck);assert!(proposal.is_closed, EProposalNotClosed);assert!(member_cap.role_address == vote_cap.voter, ERoleCheck);// 2.delete voteCaplet VoteCap {id, proposal_id, voter, is_support, votes} = vote_cap;object::delete(id);// 3.take coin from treasurylet reward_coin = take_coin_from_treasury(treasury,votes,ctx);// 4.transfer coin to votertransfer::public_transfer(reward_coin,voter);}

在投票结束后,投票者销毁Votecap取回dao代币

public fun claim_proposal_reward(member_cap:&MemberCap, proposal:&mut Proposal, treasury:&mut Treasury<DAO> ,ctx:&mut TxContext){// 1.veriry the parameterscheck_membercap_role(member_cap,ctx);assert!(proposal.is_passed, EProposalNotPassed);assert!(!proposal.is_claimed_reward, EAlreadyClaimed);assert!(proposal.proposer == tx_context::sender(ctx), ERoleCheck);proposal.is_claimed_reward = true;//2.reward calculationlet level = proposal.level;let reward_amount:u64;if(level == 1){reward_amount = LEVEL1_REWARD;}else if(level == 2){reward_amount = LEVEL2_REWARD;}else{reward_amount = LEVEL3_REWARD;};//3.send reward token;let reward_coin = take_coin_from_treasury(treasury,reward_amount,ctx);transfer::public_transfer(reward_coin,proposal.proposer);}

如果提案被接受,提案者可以获取奖励

内部函数

    fun check_init_corecap_role(init_core_cap:& InitCoreCap,ctx: &mut TxContext){assert!(init_core_cap.role_address== tx_context::sender(ctx), ERoleCheck);}fun check_corecap_role(core_cap:& CoreCap,ctx: &mut TxContext){assert!(core_cap.role_address== tx_context::sender(ctx), ERoleCheck);}fun check_membercap_role(member_cap:& MemberCap,ctx: &mut TxContext){assert!(member_cap.role_address == tx_context::sender(ctx), ERoleCheck);}fun transfer_coin_to_treasury(treasury:&mut Treasury<DAO>,coin:&mut Coin<DAO>,amount: u64){assert!(balance::value<DAO>(&treasury.supply) >= amount, EInsufficientTreasurySupply);balance::join<DAO>(&mut treasury.supply, balance::split<DAO>(coin::balance_mut(coin), amount));}fun take_coin_from_treasury(treasury:&mut Treasury<DAO>,amount: u64,ctx:&mut TxContext): Coin<DAO>{let supply = &mut treasury.supply;let reward_coin = coin::take<DAO>(supply, amount, ctx);reward_coin}fun update_proposal_vote(proposal:&mut Proposal,votes:u64,is_support:bool){let lock_balance = & proposal.lock_balance;proposal.lock_balance =*lock_balance + votes;if(is_support){let support = & proposal.support;proposal.support =*support + votes;}else{let against = & proposal.against;proposal.against =*against + votes;}}

重构了一些重复的功能,用于代码简化
check_init_corecap_role和check_corecap_role和check_membercap_role用于角色检查
transfer_coin_to_treasury和take_coin_from_treasury用于将代币转到金库或从金库转出
update_proposal_vote用来更新提案选票

视图函数

    public fun is_closed(proposal: &Proposal):bool{proposal.is_closed}public fun is_passed(proposal: &Proposal):bool{proposal.is_passed}public fun support(proposal: &Proposal):u64{proposal.support}public fun against(proposal: &Proposal):u64{proposal.against}public fun proposer(proposal: &Proposal):address{proposal.proposer}public fun total_members(dao: &Dao<DAO>):u64{dao.total_members}public fun treasury_supply(treasury: &Treasury<DAO>):u64{balance::value<DAO>(&treasury.supply)}

用于获取状态,分为提案状态和dao状态

错误定义

    const ETaskDistributeEnded:u64 = 0;const ENotTaskCapOwner:u64 = 1;const EProposalClosed:u64 = 2;const EVoteSelf:u64 = 3;const EInvailVotes:u64 = 4;const EProposalCheck:u64 = 5;const EProposalNotClosed:u64 = 6;const ERoleCheck:u64 = 7;const EProposalNotPassed:u64 = 8;const EAlreadyClaimed:u64 = 9;const EInsufficientTreasurySupply:u64 = 10;

定义一些错误,在assert时返回,方便交互失败时定位回滚位置
这些错误在之前代码的检查中有用到

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/780615.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Android开发 OCR:通过Tesseract实现图片文字识别

下面是整个详解步骤过程 效果图一、OCR的含义二、什么是Tesseract三、前提准备1、添加依赖2、数据文件下载路径 四、实际代码案例Demo如下&#xff1a;Main.xmlMain.java 效果图 流程&#xff1a;获取assets中的图片显示到页面&#xff0c;提取照片内的文字 一、OCR的含义 o…

综合实验1

一、配置IP地址 [AR1]int g0/0/0 [AR1-GigabitEthernet0/0/0]ip add 192.168.1.254 24 [AR1-GigabitEthernet0/0/0]int se4/0/0 [AR1-Serial4/0/0]ip add 15.1.1.1 24 [AR1-Serial4/0/0] [AR2]int g0/0/0 [AR2-GigabitEthernet0/0/0]ip add 192.168.2.254 24 [AR2-Giga…

Android 12.0 mtp模式下连接pc后显示的文件夹禁止删除copy重命名功能实现

1.前言 在12.0的系统rom定制化开发中,usb连接pc端的时候有好几种模式,在做otg连接pc端的时候,改成mtp模式的时候,在pc端可以看到产品设备 的显示的文件夹的内容,对于产品设备里面的文件在pc端禁止做删除重命名拷贝等操作功能的实现 2.mtp模式下连接pc后显示的文件夹禁止删…

Docker 容器编排利器 Docker Compose

文章目录 一、Docker Compose 简介二、Docker Compose 安装2.1 Mac、Windows 平台默认支持2.2 Linux 安装(通过包管理)2.2.1 安装2.2.2 测试2.2.3 卸载 2.3 使用PIP 安装与卸载2.3.1 PIP安装2.3.2 PIP 卸载 三、基本使用3.1 术语3.2 部署Flask 应用 四、Compose 常用命令4.1 命…

机器学习——LightGBM算法

机器学习——LightGBM算法 摘要&#xff1a; LightGBM是一种高效的梯度提升框架&#xff0c;它在处理大规模数据时表现出色&#xff0c;并且具有较快的训练速度和较低的内存消耗。本文将介绍LightGBM算法的原理、特点以及与传统GBDT算法的区别&#xff0c;并使用Python对其进行…

什么样的人适合学习网络安全?怎么学?_

有很多想要转行网络安全或者选择网络安全专业的人在进行决定之前一定会有的问题&#xff1a;什么样的人适合学习网络安全&#xff1f;我适不适合学习网络安全&#xff1f; 会产生这样的疑惑并不奇怪&#xff0c;毕竟网络安全这个专业在2017年才调整为国家一级学科&#xff0c;…

pandas在循环中多次写入数据到一个excel防止锁定的方法

啥都不说&#xff0c;都是泪&#xff0c;直接上代码: # 在循环中多次写入数据 for i in range(10):# 创建一个新的DataFramedf pd.DataFrame({A: [i],B: [i * 2]})# 每次写入后保存文件with pd.ExcelWriter(example.xlsx, engineopenpyxl, modea, if_sheet_existsoverlay) as…

用html写一个贪吃蛇游戏

<!DOCTYPE html> <html> <head><title>贪吃蛇</title><meta charset"UTF-8"><meta name"keywords" content"贪吃蛇"><meta name"Description" content"这是一个初学者用来学习的小…

亚远景科技-Hardware Engineering SPICE课程大纲

Hardware SPICE是intacs为电子硬件开发创建的PRM/PAM过程参考和评估模型&#xff0c;其符合ISO/IEC15504-2, Automotive SPICE 4.0, ISO 26262-1和5: 2018等标准。 无论您是想要深入了解硬件工程领域&#xff0c;还是希望成长为Provisional初级、Competent主任和Principal首席硬…

Linux(CentOS7)安装 MongoDB

目录 下载 上传 解压 创建mongodb.conf 创建数据文件夹和日志文件夹 启动服务 创建软链接 安装客户端 下载 上传 安装 下载 官方地址&#xff1a; Download MongoDB Community Server | MongoDBhttps://www.mongodb.com/try/download/community 上传 将下载好的 …

springboot/ssm宠物猫认养系统Java宠物用品商城领养系统web

springboot/ssm宠物猫认养系统Java宠物用品商城领养系统web 基于springboot(可改ssm)vue项目 开发语言&#xff1a;Java 框架&#xff1a;springboot/可改ssm vue JDK版本&#xff1a;JDK1.8&#xff08;或11&#xff09; 服务器&#xff1a;tomcat 数据库&#xff1a;my…

基于java+springboot+vue实现的电商个性化推荐系统(文末源码+Lw+ppt)23-389

摘 要 伴随着我国社会的发展&#xff0c;人民生活质量日益提高。于是对电商个性化推荐进行规范而严格是十分有必要的&#xff0c;所以许许多多的信息管理系统应运而生。此时单靠人力应对这些事务就显得有些力不从心了。所以本论文将设计一套电商个性化推荐系统&#xff0c;帮…

C++对C的扩充(三)

5 带缺省参数的函数 一般情况下,实参个数应与形参个数相同。C允许实参个数与形参个数不同。办法是在形参表列中对一个或几个形参指定缺省值(或称默认值)。例如某一函数的首部可用如下形式: void fun(int a, int b,int c100) 在调用此函数时如写成fun(2,4,6),则形参a,b,c的值…

信号量或互斥锁

在使用信号量或互斥锁时&#xff0c;调用mutex_lock或sem_wait的程序会被挂起&#xff0c;进入等待状态&#xff0c;直到另一个线程调用unlock或sem_post来唤醒它。这种等待不是死循环&#xff0c;也不会一直消耗 CPU。 具体来说&#xff0c;当一个线程调用mutex_lock或sem_wa…

kubernetes(K8S)学习(五):K8S进阶(Lifecycle......偏理论)

K8S进阶&#xff08;Lifecycle......偏理论&#xff09; 一、Pod进阶学习之路1.1 Lifecycle1.2 重启策略1.3 静态Pod1.4 健康检查1.5 ConfigMap1.6 Secret1.7 指定Pod所运行的Node 二、Controller进阶学习之路2.1 Job & CronJob2.2 StatefulSet2.3 DaemonSet2.4 Horizontal…

Adobe Illustrator 2023 for Mac/Win:创意无限,设计无界

在数字艺术与设计领域&#xff0c;Adobe Illustrator 2023无疑是一颗璀璨的明星。这款专为Mac和Windows用户打造的矢量图形设计软件&#xff0c;以其强大的功能和卓越的性能&#xff0c;赢得了全球设计师的广泛赞誉。 Adobe Illustrator 2023在继承前代版本优点的基础上&#…

python——遍历网卡并禁用/启用

一、遍历网卡 注意&#xff1a;只能遍历到启用状态的网卡&#xff0c;如果网卡是禁止状态&#xff0c;则遍历不到&#xff01;&#xff01;&#xff01; import os import time import psutil import loggingdef get_multi_physical_network_card():physical_nic_list []try:…

线性代数笔记25--复数矩阵、快速傅里叶变换

1. 复数矩阵 复向量 Z [ z 1 z 2 z 3 z 4 ⋯ ] Z\begin{bmatrix} z_1\\z_2\\z_3\\z_4\\ \cdots \end{bmatrix} Z ​z1​z2​z3​z4​⋯​ ​ 复向量的模长 ∣ z ∣ z ‾ ⊤ z [ z ‾ 1 z ‾ 2 z ‾ 3 ] [ z 1 z 2 z 3 ] \lvert z\rvert\overline z^{\top}z \begin{bmatrix…

鸿蒙 UIAbility和Compent 生命周期

一、UIAbility的生命周期 在UIAbility的使用过程中&#xff0c;会有多种生命周期状态&#xff0c;掌握UIAbility的生命周期&#xff0c;对于应用的开发非常重要。 1、UIAbility的生命周期 UIAbility的生命周期主要分为以下4个&#xff1a; Create---Foreground---Background---…

【Golang星辰图】数据处理的航海家:征服数据海洋的航行工具

数据处理的建筑师&#xff1a;用Go语言中构建稳固的数据分析建筑物 前言 数据处理和分析是现代计算机科学中的关键任务之一&#xff0c;而Go语言作为一门现代化的编程语言&#xff0c;也需要强大的数据处理和分析库来支持其在这一领域的应用。本文将介绍几款优秀的数据处理和…