GZ036 2023年全国职业院校技能大赛高职组 区块链技术应用赛项赛题(第6套)

资源下载
  1. 二一教育资源

GZ036 2023年全国职业院校技能大赛高职组 区块链技术应用赛项赛题(第6套)

资源简介

2023年全国职业院校技能大赛
高职组
“区块链技术应用”
赛项赛卷(6卷)



参赛队编号:
背景描述
近年来,食品安全问题层出不穷,涉及到各种食品类别,如肉类、水果、蔬菜等。食品安全事故不仅影响消费者的身体健康,还会导致社会恐慌,进而影响国家经济的稳定发展。随着全球化进程的加速,食品生产、加工、运输等环节变得更加复杂,食品安全溯源变得愈发困难。在这种背景下,采用先进的技术手段来保障食品安全,提高食品质量,已成为迫切的需求。
区块链技术正是在这样的大背景下应运而生,为食品安全溯源提供了一种创新的解决方案。区块链技术的核心是分布式账本和加密技术,能够实现数据的不可篡改、可追溯、透明共享等特性。这些特性使得区块链技术在食品安全溯源方面具有很大的潜力。
通过建立基于区块链技术的食品安全溯源平台,我们可以将食品安全溯源相关信息(如生产日期、产地、生产商和流通企业等)以去中心化的方式存储在区块链上,确保数据的真实性和不可篡改性。另外,利用区块链的智能合约技术,可以在保证数据安全的同时实现透明公开的食品安全溯源业务流程设计。在此基础上,引入监管机制有助于确保业务的健康发展。
模块一:区块链产品方案设计及系统运维(35分)
选手完成本模块的任务后,将任务中设计结果、运行代码、运行结果等截图粘贴至客户端桌面【区块链技术应用赛\重命名为工位号\模块一提交结果.docx】中对应的任务序号下。
任务1-1:区块链产品需求分析与方案设计(10分)
子任务1-1-1 食品安全溯源区块链产品需求分析(6分)
1. 根据项目背景描述,请设计一款基于区块链技术的食品溯源系统。请至少包括以下内容:(4分)
用户群体及需求分析
区块链技术分析
需求总结和优先级排序
2. 根据设计的食品溯源区块链系统,进行功能性与非功能性需求分析(2分)
子任务1-1-2 食品安全溯源区块链产品设计方案(4分)
设计一个基于区块链技术的食品安全溯源系统,满足以下需求:
食品溯源:通过系统可以追溯到每一个食品的生产、加工、运输、销售等环节,并能够记录和管理每一环节的数据和信息。
数据共享:系统应支持数据共享,各参与方可以通过系统实现数据的实时共享,提高数据的透明度和可信度,加强食品安全监管。
用户权限管理:系统应支持用户权限管理,各参与方可以根据自身权限进行数据的访问和管理,保障数据的安全和隐私。
防篡改性:系统应具备数据防篡改性,防止数据被篡改和伪造,确保数据的真实性和可信度。
请你根据以上需求设计一个食品安全溯源区块链系统,并给出系统的架构、数据结构、功能模块和技术方案。
任务1-2:区块链系统部署与运维(15分)
围绕食品安全溯源区块链平台部署与运维需求,进行项目相关系统、节点以及管理工具的部署工作。通过通过监控工具完成对网络、节点服务的监控。最终利用业务需求规范,完成系统日志、网络参数、节点服务等系统结构的维护,具体要求如下:
根据参数与端口设置要求,部署区块链系统并验证。
根据参数与端口设置要求,部署区块链网络管理平台并验证。
基于区块链系统相关管理平台,按照任务指南实施系统运维工作并验证。
基于区块链系统相关监管工具,按照任务指南对区块链系统进行监管。
子任务1-2-1: 搭建区块链系统并验证(4分)
基于给定服务器环境以及软件(地址“/root/tools”),使用Docker配置单机4节点的区块链系统,具体要求如下:
P2P起始端口 30500
channel起始端口 20500
JSONRPC 8945
完成任务如下:
1. 完成系统搭建配置。
2. 完成单机4节点区块链平台搭建,成功运行区块链系统。
3. 使用基于Docker命令查看区块链系统状态。
4. 检查区块链系统节点node0连接状态输出。
子任务1-2-2:搭建区块链系统管理平台并运维(4分)
基于给定服务器环境以及软件(地址“/root/tools”),搭建区块链控制台并开展相关运维工作,具体工作内容如下:
1. 配置控制台,管理相关证书并启动。
2. 使用控制台查询区块链中区块高度。
3. 使用控制台查询区块链中创世区块信息。
4. 使用控制台查询区块链中共识状态。
子任务1-2-3:区块链系统权限管理(4分)
基于给定服务器环境以及软件(地址“/root/tools”),对区块链进行权限管理,具体工作如下:
1. 使用控制台,分别创建Account1、Account2、Account3用户并形成委员会。
2. 使用控制台,修改Account1的投票权重为2。
3. 使用控制台,将Account2从委员会中剔除赋予普通用户权限。
子任务1-2-4:区块链系统监控(3分)
基于搭建完成的区块链系统系统,编写监控脚本,检测区块链程序的运行情况,最后将执行结果截图保存。具体要求:
1. 编写脚本1,每隔1秒检查一次fisco进程数量,若为4则打印正常信息,否则打印错误信息。
2. 编写脚本2,每隔3秒检查一次fisco进程占用的端口数量,若为12则打印正常信息,否则打印错误信息。
任务1-3:区块链系统测试(10分)
设计对区块链系统的测试流程;结合实际业务需求,调用部署的智能合约中进行系统测试、性能测试等;根据业务需求,分析并且修复给定智能合约中的安全漏洞。利用模拟业务和测试工具来完成对区块链系统服务数据的测试。
1. 使用命令启动区块链系统可视化一体平台并验证启动情况(1分)
2. 通过可视化平台生成包括生产商(producer)、经销商(distributor)、零售商(retailer)账户,并将账户以p12加密形式导出后倒入指定前置可视化平台,验证地址一致性。(1分)
3. 使用Postman对上述功能接口进行验证,并将验证结果截图提交工程文档。
使用Postman对食品溯源系统服务端“获取食品”(/food)功能接口进行验证,并将验证结果截图。(1分)
请求路由: /food
请求方法: GET
输入项说明: 输入项类型说明traceNumberString食品编号
输出项说明: 输出项类型说明currentString食品当前所处用户地址nameString食品名称produceString食品生产者地址timestampTimestamp食品生产时间戳qualityInteger食品质量
4.参照工程项目(地址:“/root/projects”)使用Caliper测试工具对食品安全溯源系统智能合约获取食品信息(getFood)功能进行压力测试。具体要求如下:
提供核心测试代码。(2分)
设置txNumber=10,tps=1,所有测试通过率为100%。(1分)
5.智能合约安全漏洞测试。(4分)
有如下问题智能合约:
pragma solidity ^0.7.6;
contract TimeLock {
mapping(address => uint) public balances;
mapping(address => uint) public lockTime;
function deposit() external payable {
balances[msg.sender] += msg.value;
lockTime[msg.sender] = block.timestamp + 1 weeks;
}
function increaseLockTime(uint _secondsToIncrease) public {
lockTime[msg.sender] += _secondsToIncrease;
}
function withdraw() public {
require(balances[msg.sender] > 0, "Insufficient funds");
require(block.timestamp > lockTime[msg.sender], "Lock time not expired");
uint amount = balances[msg.sender];
balances[msg.sender] = 0;
(bool sent, ) = msg.sender.call{value: amount}("");
require(sent, "Failed to send Ether");
}
}
contract Attack {
TimeLock timeLock;
constructor(TimeLock _timeLock) {
timeLock = TimeLock(_timeLock);
}
fallback() external payable {}
function attack() public payable {
timeLock.deposit{value: msg.value}();
timeLock.increaseLockTime(
type(uint).max + 1 - timeLock.lockTime(address(this))
);
timeLock.withdraw();
}
}
分析智能合约中存在问题,并说明危害。(1分)
根据truffle工具中的代码文件,编写测试用例,复现智能合约中存在的漏洞。(1分)
创建新的智能合约,修复其中问题,说明修复内容并测试。(2分)
模块二:智能合约开发与测试(30分)
任务2-1:智能合约设计5分)
根据区块链食品溯源应用需求分析和方案设计文档的描述,完成以下工作要求:
1. 根据区块链食品溯源应用需求分析和方案设计文档的描述,设计智能合约功能。(2分)
2. 设计智能合约中各角色应具备的功能。(1分)
3. 设计智能合约中食品安全溯源功能。(2分)
任务2-2:智能合约开发(20分)
食品信息(FoodInfoItem)的接口编码(6分)
(1)编写食品信息实体的接口,完成可溯源食品信息初始化,实现可追溯的原始生产商食品信息上链功能。(2分)
表2.2.1 FoodInfoItem实体说明
名称 类型 说明
_currentTraceName string 当前用户名
_name string 食品名称
_owner address 合约的创建者
_quality uint8 质量
_status uint8 状态
_traceName string[] 用户名
_timestamp uint[] 流转时间戳
_traceAddress address[] 用户地址
_traceQuality uint8[] 食品质量
contract FoodInfoItem{
//①保存食品流转过程中各个阶段的时间戳
//②保存食品流转过程各个阶段的用户名
//③保存食品流转过程各个阶段的用户地址信息(和用户一一对应)
//④保存食品流转过程中各个阶段的质量
//⑤食品名称
//⑥当前用户名称
//⑦质量(0=优质 1=合格 2=不合格)
//⑧状态(0:生产 1:分销 2:出售)
//⑨初始化owner
(2)编写分销商食品上链信息接口,根据食品溯源智能合约地址获取分销商上链食品的信息。(2分)
function addTraceInfoByDistributor(①, uint8 quality) public returns(bool) {
require(_status == 0 , "status must be producing");
//②
_timestamp.push(now);
_traceName.push(traceName);
_currentTraceName = traceName;
//③
//④
_traceQuality.push(_quality);
_status = 1;
return true;
}
(3)编写超市进行食品上链信息的接口,根据食品溯源智能合约地址获取超市上链食品信息。(2分)
function addTraceInfoByRetailer(①, uint8 quality) public returns(bool) {
require(_status == 1 , "status must be distributing");
//②
_timestamp.push(now);
_traceName.push(traceName);
_currentTraceName = traceName;
//③
//④
_traceQuality.push(_quality);
_status = 2;
return true;
}
2.食品溯源(Trace)的接口编码(6分)
(1)编写食品溯源智能合约生产商Producer添加食品接口,必须生产商才能添加可溯源的食品,实现溯源功能。(2分)
function newFood(①, string traceName, uint8 quality)
public ② returns(③)
{
//④
//⑤
//⑥
//⑦
//⑧
}
(2)编写食品溯源智能合约分销商Distributor添加食品接口,必须分销商才能添加可溯源的食品,实现溯源功能。(2分)
function addTraceInfoByDistributor(①, uint8 quality)
public ② returns(bool) {
//③
return FoodInfoItem(foods[traceNumber]).④, quality);
}
(3)编写食品溯源智能合约超市Retailer添加食品接口,必须超市才能添加可溯源的食品,实现溯源功能。(2分)
function addTraceInfoByRetailer(①, uint8 quality)
public ② returns(bool) {
require(③, "traceNumber does not exist");
return FoodInfoItem(foods[traceNumber]).④, quality);
}
3.角色(Role)管理的接口编码(4分)
(1)编写食品溯源增加角色接口,必须是未增加的角色才能被添加,实现添加角色的功能。(2分)
function add(①, address account) ② {
require(!③, "Roles: account already has role");
role.④ = true;
}
(2)编写食品溯源移除角色接口,必须是已增加的角色才能被移除,实现移除角色的功能;(1分)
function remove(①, address account) ② {
require(③, "Roles: account does not have role");
role.④ = false;
}
(3)编写食品溯源角色授权接口,必须是授权的角色地址,实现角色权限管理功能;(1分)
function has(①, address account) ② returns (bool) {
require(③, "Roles: account is the zero address");
return role.④;
}
4.合约编译、部署和调用(4分)
(1)解决代码错误和警告,正确编译并部署合约,成功获取部署的合约地址和abi。(1分)
(2)调用食品溯源智能合约的接口,完整验证业务流程。(3分)
任务2-3:智能合约测试(5分)
配置区块链网络(1分)
启动Ganache软件,创建新的Wordspace,配置对外访问的RPC接口为7545,配置项目的truffle-config.js实现与新建Workspace的连接。
设置producerId和sellederId两个变量(1分)
基于VSCODE加载的Truffle项目,补全位于test文件夹中foodTraceNew.js文件预操作的方法。在测试文件中添加预定义的方法(在其他方法启动前使用),在方法中分别设置producerId和sellederId两个变量,具体要求如下:
(1)producerId设置为1
(2)sellderId设置为4
补全createMember和getMember方法(1分)
基于VSCODE加载的Truffle项目,补全位于test文件夹中foodTraceNew.js文件,添加测试用例,测试智能合约的createMember和getMember方法。
测试createOrder和getOrder方法(1分)
基于VSCODE加载的Truffle项目,补全位于test文件夹中foodTraceNew.js文件,添加测试用例,测试智能合约的createOrder和getOrder方法。
测试createFood和getFood方法(1分)
基于VSCODE加载的Truffle项目,补全位于test文件夹中foodTraceNew.js文件,添加测试用例,测试智能合约的createFood和getFood方法。

模块三:区块链应用系统开发(30分)
任务3-1:前端功能开发(10分)
1.请基于前端系统的开发模板,在组件main.js中添加对应的逻辑代码,实现角色生产商的部分功能,并测试功能完整性。(3分)
示例页面:
本任务具体要求如下:
生产商首页展示已有的食品列表,若没有食品则显示暂无数据,展示列有溯源码、食品名称、生产商、生产时间
生产商首页有“退出”按钮,可以退出登录返回首页
生产商页面可以新建食品,弹出框中需要用户输入溯源码、视频名称、生产商、质检情况,点击取消弹窗消失,点击确定根据反馈进行提示
生产商首页展示的食品列表可根据生产时间排序
Main.js
代码片段1:

选手填写部分

选手填写部分
代码片段2:

:data="renderList"
style="width: 100%"
:default-sort =选手填写部分
>
prop="traceNumber"
label=选手填写部分
>

prop="foodName"
label=选手填写部分
>

prop="traceName"
label=选手填写部分
>

prop="date"
label=选手填写部分
选手填写部分
>


代码片段3:
.then(ret => {
if (ret.data.ret !== 1) {
// 已有溯源码校验
if (ret.data.ret === 0 && ret.data.msg === 'traceNumber already exist') {
this.$message({
message: '该溯源码已存在,请重新创建',
type: 选手填写部分,
center: true
});
} else {
this.$message({
message: 选手填写部分,
type: 选手填写部分,
center: true
});
}
return
}
this.$message({
message: 选手填写部分,
type: 选手填写部分,
center: true
});
2.请基于前端系统的开发模板,在组件components.js中添加对应的逻辑代码,实现角色中间商的部分功能,并测试功能完整性。(3分)
示例页面:
本任务具体要求如下:
中间商首页展示已有的食品列表,若没有食品则显示暂无数据,展示列有溯源码、食品名称、上架时间、质检情况、发货单位、收货单位
中间商首页有“退出”按钮,可以退出登录返回首页
中间商页面可以输入溯源码添加食品信息,输入正确的溯源码后在弹出框中展示相关溯源信息,并在弹出框中可以填写质检情况和收货单位,点击取消弹窗消失,点击确定根据反馈进行提示
中间商首页展示的食品列表可根据上架时间排序
点击溯源码可显示食品详细信息
components.js
代码片段1:


placeholder="选手填写部分"
v-model.number="traceNumber"
clearable>

添加食品信息
选手填写部分
代码片段2:

:data="renderList"
style="width: 100%"
:default-sort = "{prop: 'date', order: 'descending'}"
>
prop="traceNumber"
label=选手填写部分
>

代码片段3:
prop="name"
选手填写部分
>

prop="date"
选手填写部分 选手填写部分
>

prop="quality"
选手填写部分
>

prop="from"
选手填写部分
>

prop="to"
选手填写部分
>

代码片段4:
template:`



label=选手填写部分
prop="quality"
:rules="[
{ required: true, message: 选手填写部分, trigger: 'change' }
]">

优质
合格
不合格


label=选手填写部分
prop="traceName"
:rules="[
{ required: true, message: '请输入收货单位' }
]">




取 消
确 定




3.请基于前端系统的开发模板,在组件components.js中添加对应的逻辑代码,实现角色消费者的部分功能,并测试功能完整性。(4分)
示例页面:
本任务具体要求如下:
消费者页面左侧可进行溯源码搜索
消费者页面右侧可进行食品基本信息和食品流通信息展示
main.js
代码片段1:
template:`





选手填写部分



label=选手填写部分
prop="traceNumber"
>


查询






请在左侧查询栏中输入溯源码进行查询

该溯源码无对应信息,请确认后重新查询










退出


代码片段2:
// 处理按溯源码查询
onSubmit() {
if (!this.form.traceNumber) {
this.$message.error(选手填写部分);
return;
}
this.onSearch = true;
axios({
method: 'get',
url: `/trace traceNumber=${this.form.traceNumber}`
})
.then(ret => {
选手填写部分
})
.catch(err => {
console.log(err);
})
}
任务3-2:区块链应用后端功能开发(20分)
1.请基于后端开发模板,开发完善IndexController类,编写超市添加食品流转信息的方法,实现超市添加食品流转信息的功能,并测试功能完整性。(6分)
本任务具体要求如下:
开发文件IndexController.java中的add_trace_by_retailer方法,请求接口为/addretail
开发文件IndexController.java中的add_trace_by_retailer方法,要求对前端传入的参数进行二次验证
开发文件IndexController.java中的add_trace_by_retailer方法,要求封装返回值为String,但不返回视图页面
IndexController.java
代码片段1:
选手填写部分 @PostMapping(选手填写部分, produces=MediaType.APPLICATION_JSON_VALUE)
public String add_trace_by_retailer(@RequestBody JSONObject jsonParam) {
//声明返回对象
JSONObject _outPutObj = new JSONObject();
选手填写部分String trace_number = 选手填写部分
String trace_name = 选手填写部分
int quality = 选手填写部分
JSONArray params = JSONArray.parseArray("["+trace_number+",\""+trace_name+"\","+quality+"]");
JSONObject _jsonObj = new JSONObject();
_jsonObj.put("contractName",CONTRACT_NAME);
_jsonObj.put("contractAddress",CONTRACT_ADDRESS);
_jsonObj.put("contractAbi",JSONArray.parseArray(CONTRACT_ABI));
_jsonObj.put("user",RETAILER_ADDRESS);
_jsonObj.put("funcName",选手填写部分);
_jsonObj.put("funcParam",选手填写部分);
String responseStr = httpPost(URL,选手填写部分);
JSONObject responseJsonObj = JSON.parseObject(responseStr);
String msg = responseJsonObj.getString("message");
if (msg.equals("Success")){
_outPutObj.put("ret",选手填写部分);
_outPutObj.put("msg",msg);
}else{
_outPutObj.put("ret",选手填写部分);
_outPutObj.put("msg",msg);
}
return 选手填写部分
}
2.请基于已有的项目,开发完善IndexController类,编写获取所有食物信息的方法,实现获取所有食物信息的功能,并测试功能完整性。(6分)
本任务具体要求如下:
开发文件IndexController.java中的getlist方法,请求接口为/foodlist,该接口调用私有方法get_food_list,不直接与合约交互,提高系统的安全性。
开发文件IndexController.java中的get_food_list方法,要求通过合约进行食品列表的查询,且外部无法直接调用。
开发文件IndexController.java中的getlist方法,要求封装返回值为String,但不返回视图页面。
IndexController.java
代码片段1:
选手填写部分 @GetMapping(选手填写部分, produces=MediaType.APPLICATION_JSON_VALUE)
public String getlist(){
JSONArray num_list = get_food_list();
JSONArray num_list2 = num_list.getJSONArray(0);
JSONArray resList = new JSONArray();
for (int i=0;iString food = get_food(选手填写部分);
resList.add(food);
}
return 选手填写部分
}
代码片段2:
选手填写部分 JSONArray get_food_list(){
JSONObject _jsonObj = new JSONObject();
_jsonObj.put("contractName",CONTRACT_NAME);
_jsonObj.put("contractAddress",CONTRACT_ADDRESS);
_jsonObj.put("contractAbi",JSONArray.parseArray(CONTRACT_ABI));
_jsonObj.put("user","");
_jsonObj.put("funcName",选手填写部分);
String responseStr = httpPost(URL,选手填写部分);
JSONArray responseJsonObj = JSON.parseArray(responseStr);
return responseJsonObj;
}
3.请基于已有的项目,开发完善IndexController类,编写获取食品详细信息的相关方法,并测试功能完整性。(8分)
本题目的具体要求如下:
开发文件IndexController.java中的food方法,请求接口为/food,该接口调用私有方法get_food,不直接与合约交互,提高系统的安全性。
开发文件IndexController.java中的food方法,对传入数据进行二次验证。
开发文件IndexController.java中的get_food方法,要求通过合约进行溯源信息的查询,且外部无法直接调用。
开发文件IndexController.java中的food方法,要求封装返回值为String,但不返回视图页面。
IndexController.java
代码片段1:
/**
* 获取某个食品的当前信息
* @param traceNumber 食品溯源id,食品溯源过程中的标识符
* @return 对应食品的当前信息
*/
@ResponseBody
@GetMapping(path="/food", produces=MediaType.APPLICATION_JSON_VALUE)
public String food(String traceNumber){
JSONObject _outPut = new JSONObject();
if (Integer.parseInt(选色填写部分) <= 0){
_outPut.put(选色填写部分,"invalid parameter");
return _outPut.toJSONString();
}
String res = get_food(选色填写部分);
return res;
}
代码片段2:
/**
* 从链上获取某个食品的基本信息
* @param traceNumber: 食品溯源id,食品溯源过程中的标识符
* @return 对应食品的信息
*/
private String get_food(String traceNumber){
JSONArray params = JSONArray.parseArray("["+traceNumber+"]"); ;
JSONObject _jsonObj = new JSONObject();
_jsonObj.put("contractName",选色填写部分);
_jsonObj.put("contractAddress",选色填写部分);
_jsonObj.put("contractAbi",JSONArray.parseArray(CONTRACT_ABI));
_jsonObj.put("user","");
_jsonObj.put("funcName",选色填写部分;
_jsonObj.put("funcParam",选色填写部分);
String responseStr = httpPost(URL,选色填写部分);
JSONArray food = JSON.parseArray(responseStr);
JSONObject _outPut = new JSONObject();
_outPut.put(选色填写部分);
_outPut.put(选色填写部分);
_outPut.put(选色填写部分);
_outPut.put(选色填写部分);
_outPut.put(选色填写部分);
_outPut.put(选色填写部分);
return 选色填写部分;
}

展开更多......

收起↑

资源预览