智能合约——提案demo

目录

这是一个超超超级简单的智能合约提案项目,你确定不点进来看一下吗?

引言:

1、搭建开发环境:

2、编写智能合约:

3、部署智能合约:

​编辑​编辑4、编写前端交互代码(使用web3.js):

5、设计关于提案平台的html:


这是一个超超超级简单的智能合约提案项目,你确定不点进来看一下吗?

引言:


作为一个“新手”写智能合约,我选择做提案项目的目的是学习和成长。在这个项目中,我计划使用Solidity编程语言来编写智能合约,并进行部署和测试。我将设计一个简单而有趣的提案系统,允许用户提交提案并进行投票。我将利用前端技术,如HTML、CSS和JavaScript,来开发一个直观且易于使用的界面。通过这个项目,我希望能够提高我的编程能力和设计技巧。

1、搭建开发环境:

1.安装并配置必要的开发工具,如Node.js、Truffle Suite或Hardhat等。

2.部署一个本地的以太坊测试网络(如Ganache,Geth)或连接到以太坊的公共测试网络(如Ropsten)。

3.使用Remix,Remix是一个在线的Solidity IDE,其提供了Solidity编译器、调试器和运行环境。

4.MetaMask 是一种加密货币钱包,使用户能够访问分散式应用程序(dapps)的 Web 3 生态系统。

简单来说:

  • MetaMask 是一种加密货币钱包,使用户能够存储以太币和其他 ERC-20 代币。

  • 钱包还可用于与去中心化应用程序或 dapp 进行交互


2、编写智能合约:

编写提案智能合约及实现一个基于 ERC20 标准的代币合约。

定义合约的数据结构、状态变量、函数以及相关的事件。

// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.0;import"@openzeppelin/contracts/token/ERC20/ERC20.sol";
contract MyToken1 is ERC20 {constructor(string memory name, string memory symbol) ERC20(name, symbol) {_mint(msg.sender, 111 * 10**uint(decimals()));}function getDEcimals() public view returns (uint){return  decimals();}}
//SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.0;import"@openzeppelin/contracts/token/ERC20/ERC20.sol";contract EthVoting {//附议人信息struct Voter {uint voteTimeStamp; //投票时的区块时间uint voterMoney;bool initialized;   //判断是否投过票的标志}//提案内容struct  Proposal {string pName;        //提案标题string pCtx;         //提案内容address chairperson; //提案主持人uint voteCount;      //附议人数bool initialized;    //判断提案是否存在的标志uint limitTime;      //附议限制时间uint money;  //该提案的已经募集到的金额uint r_money;//该提案目标募集的金额mapping(address => Voter) voters; //附议列表} //提案内容-加入的数组中struct  Proposal_group {string pName;        //提案标题string pCtx;         //提案内容address chairperson; //提案主持人uint voteCount;      //附议人数bool initialized;    //判断提案是否存在的标志uint limitTime;      //附议限制时间uint money;  //该提案的已经募集到的金额uint r_money;//该提案目标募集的金额}//声明一个全局变量成为部署当前合约的调用者   
address public  master;//声明一个全局变量成为master指定一个账户成为提案合法提取者
address   receiver;//ERC20的合约地址赋值给这个变量address public ercaddress;constructor (address ercaddress_ ) {//实例化合约token合约对象master=msg.sender;//实例化一个tokenercaddress =ercaddress_;}//转ERC20代币function transfer2other(address to_ ,uint ercnum_) public {IERC20(ercaddress).transfer(to_,ercnum_*(10**18));}//获取某个ERC20代币余额function getBalance() public  view  returns (uint256) {return IERC20(ercaddress).balanceOf(address(this));}//提案编号
uint pId;//函数修饰符,表示只有master账户才能执行的函数
modifier  onlyMaster(){require(msg.sender==master,"it must be  master");_;}   //函数修饰符,表示只有指定账户才能提取提案里的钱
modifier  onlyReceiver(){require(msg.sender==receivers[msg.sender]&&msg.sender==receivers[msg.sender]&&msg.sender==receivers[msg.sender],"it must be  receiver");_;}//函数修饰符,表示只有指定账户才能进行提案的附议
modifier  onlySomeDoVoting(){
require(msg.sender!=receiver,"it can not be  receiver");
require(msg.sender!=master,"it can not be  master");_;
}//所有提案列表mapping(uint => Proposal) public proposals;//提案余额提取者mapping(address=>address) public receivers;//所有提案列表-加入到数组中mapping(uint => Proposal_group) public proposales;
//所有提案列表-加入到数组中mapping(uint=>Proposal_group[]) public Proposal_groups;//附议事件event VoteEvt(string indexed eventType, address _voter, uint timestamp);//提案事件event ProposeEvt(string indexed eventType, uint _proposalId, uint _limitTime);//创建新提案function createProposal(string  memory _pName, string memory  _pCtx, uint _limitTime ,uint r_money) public payable returns (uint){//赋值语句pId=pId+1;Proposal storage _proposal = proposals[pId];_proposal.pName = _pName;_proposal.pCtx = _pCtx;_proposal.chairperson = msg.sender;_proposal.initialized = true;_proposal.limitTime=block.timestamp+ _limitTime;_proposal.r_money= r_money;_proposal.voteCount = 0;//赋值并加入到数组中,以获取所有的提案Proposal_group storage _proposales = proposales[pId];_proposales.pName = _pName;_proposales.pCtx = _pCtx;_proposales.chairperson = msg.sender;_proposales.initialized = true;_proposales.limitTime=block.timestamp+ _limitTime;_proposales.r_money= r_money;_proposales.voteCount = 0;Proposal_groups[1].push(_proposales);emit ProposeEvt("propose", pId, _limitTime);return pId;}//提案提取人数量uint receiverCount;//master添加提案提取人function addReceiver(address voterAddr) public  payable onlyMaster{require(receiverCount<=3,"receiver can not exceed 3!");receiverCount+=1;receivers[voterAddr]=voterAddr;}//master删除提案提取人function deleteReceiver(address voterAddr) public  payable onlyMaster{delete receivers[voterAddr];receiverCount-=1;}//进行附议function doVoting(uint pId1) public payable  {if (proposals[pId1].chairperson == msg.sender)revert("proposal person is not youself");if (msg.value <2)revert("money is lower than 2");//提案是否存在if (proposals[pId1].initialized == false)revert("proposal not exist");uint currentTime = block.timestamp;//是否已超过提案时限if (proposals[pId1].limitTime < currentTime)revert("exceed voting time");//是否已经投过票if (proposals[pId1].voters[msg.sender].initialized == true)revert("already vote");if (proposals[pId1].money>=proposals[pId1].r_money)revert("money is enough!");//新投票信息Voter memory voter = Voter({voteTimeStamp: block.timestamp,initialized: true,voterMoney:msg.value});//记录投票信息proposals[pId1].voters[msg.sender] = voter;proposals[pId1].voteCount+=1;proposals[pId1].money+=msg.value;emit VoteEvt("vote", msg.sender, block.timestamp);}	//提案里的钱由合法提取者提取出来function collectMoney(uint pId1) public payable onlyReceiver{
payable(receiver).transfer(proposals[pId1].money);proposals[pId1].money=0;delete proposals[pId1];}//查询是否附议function queryVoting(uint pId1, address voterAddr) public view returns (uint,uint){//提案是否存在if (proposals[pId1].initialized == false)revert("proposal not exist");//返回投票时间和和金额return (proposals[pId1].voters[voterAddr].voteTimeStamp,proposals[pId1].voters[voterAddr].voterMoney);}	//获取区块链时间function getBlockTime() public view returns (uint t) { t = block.timestamp;}//  //查询所有提案function getProposals() public view returns (Proposal_group[] memory) { return Proposal_groups[1];} 	// 查询附议提案function queryP_dovot(uint pid) public view returns (uint,uint ) { return (proposals[pid].voteCount,proposals[pid].money);} //查询提案标题function getProposalName(uint pId1) public view returns (string memory s) { s = proposals[pId1].pName;} 	//查询提案内容function getProposalCtx(uint pId1) public view returns (string memory s) { s = proposals[pId1].pCtx;}//查询提案内容function getProposalVCnt(uint pId1) public view returns (uint v) { v = proposals[pId1].voteCount;}//查询提案期限function getProposalLimit(uint pId1) public view returns (uint t) { t = proposals[pId1].limitTime;}}


3、部署智能合约:

编译智能合约代码,生成合约的字节码和ABI(Application Binary Interface)。

将合约部署到所选择的以太坊网络中。


4、编写前端交互代码(使用web3.js):

创建一个前端应用程序,可以是基于HTML/CSS/JavaScript的简单界面。

使用web3.js库与部署的智能合约进行交互,包括调用合约方法、处理交易等。

配置MetaMask或其他以太坊钱包插件,使用户可以通过浏览器与智能合约交互并进行以太币交易。

具体功能见代码注释

const web3 = new Web3(Web3.givenProvider);
const abi = [];
let changeAccount = [];
var myContract = new web3.eth.Contract(abi,"0xa9dC761F2B9986Ce04694c3f279f0d62bb82A9CA"
);
let Accounts = [];
console.log(web3);
web3.eth.getAccounts().then(function (accounts) {Accounts = accounts;
});
ethereum.on("accountsChanged", function (account) {changeAccount = account;
});
function handle() {var Title = document.getElementById("Title").value;var content = document.getElementById("content").value;var time = document.getElementById("time").value;var eth = document.getElementById("eth").value;var start = new Date("1970-01-01");var end = new Date(time);var t_start = start.getTime();var t_end = end.getTime();var days = (t_end - t_start) / 1000 / 60 / 60 / 24; //10var s = days * 24 * 60 * 60;//添加提案myContract.methods._createProposal(Title, content, s, eth).send({ from: changeAccount[0], gas: 3000000 }).then(function (receipt) {alert("提案添加成功");});
}
//查询提案列表
function queryall() {myContract.methods._getProposals().call({ from: changeAccount[0] }).then(function (receipt) {console.log(receipt);});
}var personAdd = [];
//添加提案余额提取人
function handle1() {var Person = document.getElementById("Person").value;var Person1 = document.getElementById("Person1").value;console.log(Person == "");console.log(Person1 == "");if (Person != "") {personAdd[0] = Person;myContract.methods._addReceiver(personAdd[0]).send({ from: changeAccount[0], gas: 3000000 }).then(function (receipt) {alert("添加提案余额提取人成功");});}if (Person1 != "") {personAdd[0] = Person1;myContract.methods._deleteReceiver(personAdd[0]).send({ from: changeAccount[0], gas: 3000000 }).then(function (receipt) {alert("删除提案余额提取人成功");});}
}
//附议提案
function handle2() {var id = document.getElementById("id").value;var eth = document.getElementById("eth").value;web3.eth.getAccounts().then(function (accounts) {Accounts = accounts;});myContract.methods._doVoting(id).send({ from: changeAccount[0], gas: 3000000, value: eth }).then(function (receipt) {alert("提案附议成功");var amount = 10;myContract.methods._transfer2other(Accounts[0], amount).send({ from: changeAccount[0], gas: 3000000 }).then(function (receipt) {alert("附议成功,该账户获得10个ERC20代币");});});
}//receiver接收提案中的金额
function handle3() {web3.eth.getAccounts().then(function (accounts) {Accounts = accounts;});var id = document.getElementById("id").value;myContract.methods._collectMoney(id).send({ from: changeAccount[0], gas: 3000000 }).then(function (receipt) {alert("receiver提取成功");});
}
//查询提案附议结果
function handle4() {web3.eth.getAccounts().then(function (accounts) {Accounts = accounts;});var id = document.getElementById("id").value;var id1 = document.getElementById("id1").value;var Address = document.getElementById("Address").value;if (id != "") {myContract.methods._queryP_dovot(id).call({ from: changeAccount[0] }).then(function (receipt) {alert("查询成功");console.log(receipt);});}if (id1 != "") {//查询某人附议结果(pid,address)personAdd[0] = Address;myContract.methods._queryVoting(id1, personAdd[0]).call({ from: changeAccount[0] }).then(function (receipt) {alert("查询成功");console.log(receipt);});}
}

5、设计关于提案平台的html:

1、是的,HTML代码我没给全,比如设置提案接收人,提案附议页面,查询提案页面我都没给,看到这个文章的有缘人,你们要靠你们自己了!

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>首页</title><!--bootstrap css 挺方便简洁的一款第三方前端开发框架-->
<link rel="stylesheet" href="css/bootstrap.css" /><link rel="stylesheet" href="css/style.css" /></head>
<body><div class="span12 content" style="width: 1180px;"><div class="box" style="    margin-top: 166px;margin-left: 245px;"><div class="box-head"><h3>公告提案平台</h3><a href="/setReveiver.html"><button>设置提案接收人</button></a><a href="/dovot.html"><button>附议页面</button></a><a href="/searchPid.html"><button>查询提案</button></a><a href="/reveiver.html"><button>余额提取页面</button></a><button onclick="queryall()">查询提案列表(控制台查看)</button></div><div class="box-content"><div class="form-horizontal"><div class="control-group"><label class="control-label">标题</label><div class="controls"><div class="input-append"><input id="csyTitle" type="text" class="tip" /><!-- <span class="tip add-on"  id="jieshouren"> --><!-- <i class="icon-user" style="cursor:pointer" ></i> --><!-- <div style="display:none" id="selectlxr"></div> --></span></div></div></div><div class="control-group"><label class="control-label">内容</label><div class="controls"><textarea id="csycontent" class="span6 input-square"></textarea></div></div><div class="control-group"><label class="control-label">截止时间</label><div class="controls"><input id="csytime" type="datetime-local" /></div></div><div class="control-group"><label class="control-label">所需费用</label><div class="controls"><input type="text" id="csyeth" class="tip" /></div></div><div class="control-group"><label class="control-label">&nbsp;</label><div class="controls"><input type="button" class="btn btn-fo" onclick="handle()" value="新建提案" /></div></div></div></div></div>
</div>
<script src="web3.min.js"></script>
<script src="app1.js"></script>
<script src="js/jQuery.js"></script>
<script src="js/jquery.artDialog.js?skin=idialog"></script>
<!--js结束-->
<script>
//循环输出创建十个复选框
var chtml = "";
for (var i = 0; i < 10; i++) {chtml += "<div style='word-wrap:break-word; width:450px; '>";chtml += '<label style="float:left;padding:15px"><input type="checkbox" name="aaa" value="1" class="{required:true}" /><span style="margin-left:10px">小'+i+'</span></label>';chtml += "</div>";
}
//把得到字符串利用jquery添加到元素里面生成checkbox
$("#selectlxr").html(chtml);
//创建一个 dialog弹出框(第三方插件有兴趣可以看下 超赞的一款插件 http://www.planeart.cn/demo/artDialog/) 把创建好的弹出框隐藏起来
var dia = $.dialog({title: "选择联系人", width: "500px",content: $("#selectlxr").html(),close: function () {this.hide();return false;},follow: document.getElementById("jieshouren")}).hide();//点击 显示
$("#jieshouren").click(function () {dia.show();
})
//事件 获取checkbox点击时候的父元素的值 添加到text 如果点击收的选中状态为checked 则添加 否则 删除
$("input[type=checkbox]").click(function () {try {if ($(this).attr("checked")) {$("#jsrtxt").val($("#jsrtxt").val() + $(this).parent().text() + ";");} else {$("#jsrtxt").val($("#jsrtxt").val().replace($(this).parent().text() + ';', ""));}} catch (e) {$("#jsrtxt").val("");}
})
//初步测试 暂无小bug 可以为text增加一个只读  
</script></body>
</html>

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

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

相关文章

使用riscv-tests进行指令测试(二)

使用riscv-tests进行指令测试&#xff08;二&#xff09; 1 测试用例命名规则2 测试用例dump文件介绍 本文属于《 TinyEMU模拟器基础系列教程》之一&#xff0c;欢迎查看其它文章。 1 测试用例命名规则 用例名称 TVM Name “-” Target Environment Name “-” “指令”…

区块链基础——区块链应用架构概览

目录 区块链应用架构概览&#xff1a; 1、区块链技术回顾 1.1、以太坊结点结构 1.2、多种应用场景 2、区块链应用架构概览 2.1、传统的Web2 应用程序架构 2.2、Web3 应用程序架构——最简架构 2.3、Web3 应用程序架构——前端web3.js ether.js 2.4、Web3 应用程序架构—…

Python 基于 OpenCV 视觉图像处理实战 之 OpenCV 简单人脸检测/识别实战案例 之六 简单进行人脸训练与识别

Python 基于 OpenCV 视觉图像处理实战 之 OpenCV 简单人脸检测/识别实战案例 之六 简单进行人脸训练与识别 目录 Python 基于 OpenCV 视觉图像处理实战 之 OpenCV 简单人脸检测/识别实战案例 之六 简单进行人脸训练与识别 一、简单介绍 二、简单进行人脸训练与识别 1、LBPH…

【MATLAB源码-第198期】基于simulink的三相光伏并网仿真模拟。

操作环境&#xff1a; MATLAB 2022a 1、算法描述 三相光伏并网系统是一种将太阳能转换为电能并将其馈入电网的系统。这个系统通常包括光伏阵列、逆变器&#xff08;包括其控制算法&#xff09;、滤波器、电网连接和监控系统。从上载的框图中可以看出&#xff0c;该系统的设计…

找不到mfc140.dll如何解决?mfc140.dll丢失的几种解决方法分享

在我们启动并开始利用电脑进行日常工作的过程中&#xff0c;如果遭遇了操作系统提示“mfc140.dll文件丢失”的错误信息&#xff0c;导致某些应用程序无法正常运行&#xff0c;这究竟是何种情况呢&#xff1f;小编将介绍计算机缺失mfc140.dll文件的5种解决方法&#xff0c;帮助大…

java项目:微信小程序基于SSM框架实现的购物系统小程序【源码+数据库+毕业论文+PPT】

一、项目简介 本项目是一套基于SSM框架实现的购物系统小程序 包含&#xff1a;项目源码、数据库脚本等&#xff0c;该项目附带全部源码可作为毕设使用。 项目都经过严格调试&#xff0c;eclipse或者idea 确保可以运行&#xff01; 该系统功能完善、界面美观、操作简单、功能齐…

unity学习(91)——云服务器调试——补充catch和if判断

本机局域网没问题&#xff0c;服务器放入云服务器后&#xff0c;会出现异常。 想要找到上面的问题&#xff0c;最简单的方法就是在云服务器上下载一个vs2022&#xff01; 应该不是大小端的问题&#xff01; 修改一下readMessage的内容&#xff0c;可以直接粘贴到云服务器的。 …

使用FunASR处理语音识别

FunASR是阿里的一个语音识别工具&#xff0c;比SpeechRecognition功能多安装也很简单&#xff1b; 官方介绍&#xff1a;FunASR是一个基础语音识别工具包&#xff0c;提供多种功能&#xff0c;包括语音识别&#xff08;ASR&#xff09;、语音端点检测&#xff08;VAD&#xff…

【Java数据结构】初步认识ArrayList与顺序表

前言~&#x1f973;&#x1f389;&#x1f389;&#x1f389; hellohello~&#xff0c;大家好&#x1f495;&#x1f495;&#xff0c;这里是E绵绵呀✋✋ &#xff0c;如果觉得这篇文章还不错的话还请点赞❤️❤️收藏&#x1f49e; &#x1f49e; 关注&#x1f4a5;&#x…

分布式文件系统--MinIO

1 MinIO安装(Docker) ●在root目录下新建docker_minio文件夹 ●在docker_minio文件夹下新建config文件夹,data文件夹 ●在root目录下新建docker_compose文件夹,在docker_compose文件夹中添加docker-compose.yaml services:minio:image: quay.io/minio/miniocontainer_name: mi…

Vuforia AR篇(三)— AR模型出场效果

目录 前言一、AR模型出场二、AR出场特效三、添加过渡效果四、效果 前言 例如&#xff1a;随着人工智能的不断发展&#xff0c;机器学习这门技术也越来越重要&#xff0c;很多人都开启了学习机器学习&#xff0c;本文就介绍了机器学习的基础内容。 一、AR模型出场 创建ARCamer…

Three.js——基础材质、深度材质、法向材质、面材质、朗伯材质、Phong材质、着色器材质、直线和虚线、联合材质

个人简介 &#x1f440;个人主页&#xff1a; 前端杂货铺 &#x1f64b;‍♂️学习方向&#xff1a; 主攻前端方向&#xff0c;正逐渐往全干发展 &#x1f4c3;个人状态&#xff1a; 研发工程师&#xff0c;现效力于中国工业软件事业 &#x1f680;人生格言&#xff1a; 积跬步…

【树莓派】强力烧写工具 Balena Etcher,烧写树莓派系统,树莓派系统克隆,备份

文章目录 使用Win32DiskImager备份和写入树莓派系统步骤一&#xff1a;下载和安装Win32DiskImager步骤二&#xff1a;准备工作步骤三&#xff1a;备份树莓派系统步骤四&#xff1a;写入树莓派系统 使用Balena Etcher给树莓派烧写系统Balena Etcher简介步骤一&#xff1a;下载Ba…

Mac安装telnet

一、安装Homebrew 1、打开官网&#xff1a;Homebrew — The Missing Package Manager for macOS (or Linux) 2、打开终端输入&#xff1a; /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" 二、安装Telnet bre…

【LAMMPS学习】八、基础知识(4.5)TIP5P水模型

8. 基础知识 此部分描述了如何使用 LAMMPS 为用户和开发人员执行各种任务。术语表页面还列出了 MD 术语&#xff0c;以及相应 LAMMPS 手册页的链接。 LAMMPS 源代码分发的 examples 目录中包含的示例输入脚本以及示例脚本页面上突出显示的示例输入脚本还展示了如何设置和运行各…

园区智慧化转型新篇章:解码智慧技术如何助力园区实现精细化管理,提升运营效率

目录 一、智慧技术概述及其在园区管理中的应用 &#xff08;一&#xff09;物联网技术的应用 &#xff08;二&#xff09;大数据技术的应用 &#xff08;三&#xff09;云计算技术的应用 二、智慧技术助力园区实现精细化管理 &#xff08;一&#xff09;实现资源优化配置…

轻松上手,无缝对接:详述如何接入企讯通空号检测接口API

企讯通空号检测接口API作为一款高效、精准的手机号码状态检测工具&#xff0c;能够帮助企业及开发者快速识别手机号码的有效性&#xff0c;优化通讯资源&#xff0c;提升营销效果。本篇文章将带领您一步步了解如何轻松、无缝地对接企讯通空号检测接口API&#xff0c;让您的业务…

【RAG 论文】Adaptive-RAG:自适应地根据 query 难度来选择合适的 RAG 模型

论文&#xff1a;Adaptive-RAG: Learning to Adapt Retrieval-Augmented Large Language Models through Question Complexity ⭐⭐⭐⭐ Code&#xff1a;github.com/starsuzi/Adaptive-RAG NAACL 2024&#xff0c;arXiv:2403.14403 文章目录 一、论文速读二、实现细节2.1 三种…

使用FPGA实现逐级进位加法器

介绍 逐级进位加法器就是将上一位的输出作为下一位的进位输入&#xff0c;依次这样相加。下面以一个8位逐级进位加法器给大家展示。 我增加了电路结构&#xff0c;应该很容易理解吧。 下面我也列举了一位加法器&#xff0c;可以看下。 电路结构 设计文件 1位加法器 librar…

Docker 的数据管理 端口映射 容器互联 镜像的创建

目录 概念 概念 管理 Docker 容器中数据主要有两种方式&#xff1a;数据卷&#xff08;Data Volumes&#xff09;和数据卷容器&#xff08;DataVolumes Containers&#xff09;。总结&#xff1a;因为容器数据是临时保存的为了安全&#xff0c;就要让数据保持持久化。 1&#…