该管理系统为Solidity语言和区块链智能合约技术的实践,适于初涉区块链人群了解Solidity语言语法和基本相关软件操作。开始编这个系统时,学了好多内容,但网上知识虽然多,但质量良莠不齐,要么收费,要么零零散散,本着知识共享的目的该内容。水平有限,语法没有多么高级,仍有改善的地方,功能上也可继续完善。之后,设想可以采用Truffle框架改进系统交互页面,使用Hyperledger Fabric创建联盟链,将系统真正运行起来。区块链技术因其安全性、公开性、不可篡改性等特点,一定会在管理系统、交易平台等应用中发挥巨大的作用! 实现一个高校志愿服务管理系统,包括三个功能模块,志愿服务申请、志愿服务管理、志愿服务查询,每个功能模块实现具体功能介绍如下。 志愿者参与志愿活动前,需进行注册。注册需提供姓名和学号,之后系统自动创建用户,同时将个人信息与用户地址绑定。参与志愿活动前,查询可参加的志愿活动ID,通过志愿活动ID查询志愿活动具体信息。在申请志愿活动时,输入志愿活动ID,参与相应的志愿活动。 该模块不需要任何权限,只需提供某用户地址,即可查询到用户的志愿活动信息,若有异议,可提出修改用户的志愿时长请求,需提供修改原因、修改地址和修改数目。请求将会提交给管理员,管理员通过投票判断是否修改。 该模块面向于系统管理员,用于管理志愿活动。合约部署者为最高管理员,只需提供地址和管理员职位,即可设置管理员权限于某地址。管理员可以发布志愿活动,需提供志愿活动名称、志愿活动时间、志愿活动需要时间、志愿活动每人花费时间和志愿活动报名截止时间。管理员可以停止志愿活动,对修改请求进行投票。投票要求至少五人投票,赞成票数大于反对票数才可通过,成功执行修改。 志愿者注册后会有一个可用志愿时长信息,每月每人有12小时的可用志愿时长,目的在于保证志愿者都有机会参与志愿活动。因此,增加一个恢复用户可用志愿时长功能,用来每个月恢复用户可用志愿时长。 使用Solidity语言和Remix平台进行代码编译,代码如下。 使用Ganache软件部署一个本地主机的私有链,部署成功后会提供一个MetaMask账户,账户拥有十个地址,通过MetaMask密语登录,使用Remix平台交互。 Ganache软件界面 MetaMask登录界面 MateMask账户界面 用户1、用户2、用户3进行注册 设置五个管理员 发布的一项志愿活动中,只需两人,因此用户一、用户二报名成功,用户三报名失败。 扣除用户2三小时志愿时长基于智能合约的高校志愿服务管理系统
PS:强烈推荐北京大学肖瑧老师的课程:《区块链技术与应用》
系统功能设计
志愿服务申请
志愿服务查询
志愿服务管理
其他设定
系统代码实现
pragma solidity >=0.4.24 <0.7.0; contract volunteermanagement{ //创建合约部署者 address public creatoraddr; constructor() public{ creatoraddr = msg.sender; } //创建志愿者结构体 struct Volunteer{ string stuname; string stunumber; uint havetime; uint score; address stuaddress; } //维护一个志愿者信息数组 Volunteer[] public allvolunteers; //维护一个志愿活动信息数组 Volunteering[] public allvolunteerings; //维护一个地址到是否注册的mapping mapping(address=>bool) public isenrolledmap; //维护一个地址到个人信息的mapping mapping(address=>Volunteer) inquiremap; //维护地址到注册ID的映射 uint enrollID; mapping(address=>uint) inquireIDmap; uint volunteeringID; //注册 function enroll(string memory _stuname,string memory _stunumber) public { require(isenrolledmap[msg.sender] == false);//判断是否注册,未注册继续,已注册则退出 Volunteer memory volunteer = Volunteer({ stuname:_stuname,stunumber:_stunumber,havetime:12,score:0,stuaddress:msg.sender }); allvolunteers.push(volunteer);//创建用户并添加信息 isenrolledmap[msg.sender] = true;//标记已注册 //创建地址和个人信息的映射 inquiremap[msg.sender] = volunteer; //创建地址到注册ID的映射 inquireIDmap[msg.sender] = enrollID; enrollID++; } //查询志愿者信息 function inquire(address inquireaddr) public view returns(string memory ,string memory,uint,uint,address){ require(isenrolledmap[inquireaddr]);//判断是否注册,注册继续,未注册则退出 uint m = inquireIDmap[inquireaddr]; Volunteer memory c = allvolunteers[m]; return(c.stuname,c.stunumber,c.havetime,c.score,c.stuaddress);//返回志愿者信息 } //创建志愿活动结构体 struct Volunteering{ string volname; string voltime; uint targettime; uint supporttime; uint supportedtime; string deadline; bool status; uint INvolunteeringID; mapping(address=>bool) isapplymap; } //创建志愿活动 function creatvolunteering(string memory _volname,string memory _voltime,uint _targettime,uint _supporttime,string memory _deadline) public onlymanager{ Volunteering memory volunteering = Volunteering({ volname:_volname,voltime:_voltime,targettime:_targettime,supporttime:_supporttime,supportedtime:0,deadline:_deadline,status:true,INvolunteeringID:volunteeringID++ }); allvolunteerings.push(volunteering); } //停止志愿活动 function stopvulunteering(uint _volunteeringID) public onlymanager { Volunteering storage volunteering = allvolunteerings[_volunteeringID]; volunteering.status = false; } uint[] public availablevolunteerings; //查看可参加志愿活动ID function inquirevolunteering() public returns(uint[] memory){ uint[] memory array;//创建一个空数组 availablevolunteerings = array;//用空数组初始化志愿活动ID数组 for(uint i;i<allvolunteerings.length;i++){ if(allvolunteerings[i].status == true){ availablevolunteerings.push(allvolunteerings[i].INvolunteeringID); } }//遍历已创建志愿活动数组,提取正在进行志愿活动的ID return(availablevolunteerings);//输出正在进行志愿活动ID数组 } //参加志愿活动 function applyvolunteering(uint _volunteeringID) public { require(isenrolledmap[msg.sender]);//判断是否注册,注册继续,未注册则退出 uint m = inquireIDmap[msg.sender]; Volunteering storage volunteering = allvolunteerings[_volunteeringID];//提取参加志愿活动信息 Volunteer storage volunteer = allvolunteers[m];//提取参加志愿者信息 require(volunteering.supportedtime<volunteering.targettime);//判断报名人数是否已满 require(volunteer.havetime>=volunteering.supporttime);//判断志愿者是否有用于志愿活动的时间 require(volunteering.isapplymap[msg.sender]==false);//判断志愿者是否已经报名志愿活动 require(volunteering.status == true);//判断志愿活动是否结束 volunteering.supportedtime = volunteering.supportedtime + volunteering.supporttime;//修改志愿活动信息 volunteer.havetime = volunteer.havetime - volunteering.supporttime; volunteer.score = volunteer.score + volunteering.supporttime;//修改志愿者信息 volunteering.isapplymap[msg.sender]=true;//标记该志愿者已参加过活动 } //创建管理员信息结构体 struct Manager{ string occupation; address manageraddr; } //维护一个管理员信息数组 Manager[] public allmanagers; //标记地址是否管理员 mapping(address=>bool) public ismanagermap; //设置管理员权限 function creatmanager(string memory _occupation,address _manageraddr) public { require(creatoraddr == msg.sender);//验证是否是合约部署者,不是合约部署者无法创建管理员 Manager memory manager = Manager({ occupation:_occupation,manageraddr:_manageraddr }); allmanagers.push(manager); ismanagermap[_manageraddr] = true; inquiremanagermap[_manageraddr] = manager; } //修改志愿信息 struct Request{ string reason;//修改原因 address changeaddr;//被修改者地址 uint changescore;//被修改数量 uint appprovecount;//赞成数 uint opposecount;//反对数 mapping(address=>bool) isvotemap;//记录是否投过票 } Request[] public allrequests;//所有修改志愿信息请求的集合 //创建修改志愿信息请求 function creatrequest(string memory _reason,address _changeaddr,uint _changescore) public { Request memory request = Request({ reason:_reason,changeaddr:_changeaddr,changescore:_changescore,appprovecount:0,opposecount:0 }); allrequests.push(request); } //投票是否修改志愿者时长 function vote(uint i,bool _isqpprove) public onlymanager{ Request storage request = allrequests[i];//提取请求信息 require(request.isvotemap[msg.sender] == false);//判断是否投过票 if(_isqpprove == true) { request.appprovecount++; }else{ request.opposecount++; }//若赞成,则赞成票数加一,若反对,反对票数加一 request.isvotemap[msg.sender]=true;//标记地址已投过票 } //执行修改志愿者时长 function changescore(uint i) public onlymanager{ Request memory request = allrequests[i];//提取请求信息 require(request.appprovecount+request.opposecount>=5);//判断投票人数是否大于5人 require(request.appprovecount>request.opposecount);//判断赞成票数是否大于反对票数 address changeaddruse = request.changeaddr; uint changescoreuse = request.changescore; uint m = inquireIDmap[changeaddruse]; Volunteer storage volunteer = allvolunteers[m];//获取志愿者信息 volunteer.score = volunteer.score - changescoreuse;//对志愿信息修改 } //判断是否管理员,管理员继续,不是管理员则退出 modifier onlymanager() { require(ismanagermap[msg.sender]); _; } //恢复可用志愿时长数 function restore() public{ require(creatoraddr == msg.sender);//验证是否是合约部署者,不是合约部署者无法恢复拥有可用志愿时长数 for(uint i=0;i<allvolunteers.length;i++){ Volunteer storage volunteer = allvolunteers[i]; volunteer.havetime = 12; } } }
系统测试
地址和用户身份对应表
测试一:志愿者注册和查询
测试二:管理员设置和查询
测试三:志愿活动发布和申请
测试四:修改志愿者信息
测试五:恢复可用志愿时长
所有功能在部署后都已测试,只对关键功能测试进行展示。
本网页所有视频内容由 imoviebox边看边下-网页视频下载, iurlBox网页地址收藏管理器 下载并得到。
ImovieBox网页视频下载器 下载地址: ImovieBox网页视频下载器-最新版本下载
本文章由: imapbox邮箱云存储,邮箱网盘,ImageBox 图片批量下载器,网页图片批量下载专家,网页图片批量下载器,获取到文章图片,imoviebox网页视频批量下载器,下载视频内容,为您提供.
阅读和此文章类似的: 全球云计算