GZ036 区块链技术应用赛项赛题第6套

2023年全国职业院校技能大赛

高职组

“区块链技术应用”

赛项赛卷(6卷)

参赛队编号:             

背景描述

近年来,食品安全问题层出不穷,涉及到各种食品类别,如肉类、水果、蔬菜等。食品安全事故不仅影响消费者的身体健康,还会导致社会恐慌,进而影响国家经济的稳定发展。随着全球化进程的加速,食品生产、加工、运输等环节变得更加复杂,食品安全溯源变得愈发困难。在这种背景下,采用先进的技术手段来保障食品安全,提高食品质量,已成为迫切的需求。

区块链技术为食品安全溯源提供了一种创新的解决方案。区块链技术能够实现数据的不可篡改、可追溯、透明共享等特性。这些特性使得区块链技术在食品安全溯源方面具有很大的潜力。

通过建立基于区块链技术的食品安全溯源平台,我们可以将食品安全溯源相关信息(如生产日期、产地、生产商和流通企业等)以去中心化的方式存储在区块链上,确保数据的真实性和不可篡改性。另外,利用区块链的智能合约技术,可以在保证数据安全的同时实现透明公开的食品安全溯源业务流程设计。在此基础上,引入监管机制有助于确保业务的健康发展。

模块一:区块链产品方案设计及系统运维(35分)

选手完成本模块的任务后,将任务中设计结果、运行代码、运行结果等截图粘贴至客户端桌面【区块链技术应用赛\重命名为工位号\模块一提交结果.docx】中对应的任务序号下。

任务1-1:区块链产品需求分析与方案设计(10分)

子任务1-1-1 食品安全溯源区块链产品需求分析(6分)

1. 根据项目背景描述,请设计一款基于区块链技术的食品溯源系统。请至少包括以下内容:(4分)

  1. 用户群体及需求分析
  2. 区块链技术分析
  3. 需求总结和优先级排序

2. 根据设计的食品溯源区块链系统,进行功能性与非功能性需求分析(2分)

子任务1-1-2 食品安全溯源区块链产品设计方案(4分)

设计一个基于区块链技术的食品安全溯源系统,满足以下需求:

  1. 食品溯源:通过系统可以追溯到每一个食品的生产、加工、运输、销售等环节,并能够记录和管理每一环节的数据和信息。
  2. 数据共享:系统应支持数据共享,各参与方可以通过系统实现数据的实时共享,提高数据的透明度和可信度,加强食品安全监管。
  3. 用户权限管理:系统应支持用户权限管理,各参与方可以根据自身权限进行数据的访问和管理,保障数据的安全和隐私。
  4. 防篡改性:系统应具备数据防篡改性,防止数据被篡改和伪造,确保数据的真实性和可信度。

请你根据以上需求设计一个食品安全溯源区块链系统,并给出系统的架构、数据结构、功能模块和技术方案。

任务1-2:区块链系统部署与运维(15分)

围绕食品安全溯源区块链平台部署与运维需求,进行项目相关系统、节点以及管理工具的部署工作。通过监控工具完成对网络、节点服务的监控。最终利用业务需求规范,完成系统日志、网络参数、节点服务等系统结构的维护,具体要求如下:

  1. 根据参数与端口设置要求,部署区块链系统并验证。
  2. 根据参数与端口设置要求,部署区块链网络管理平台并验证。
  3. 基于区块链系统相关管理平台,按照任务指南实施系统运维工作并验证。
  4. 基于区块链系统相关监管工具,按照任务指南对区块链系统进行监管。

子任务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秒检查一次区块链节点进程数量,若为4则打印正常信息,否则打印错误信息。

2. 编写脚本2,每隔3秒检查一次区块链节点进程占用的端口数量,若为12则打印正常信息,否则打印错误信息。

任务1-3:区块链系统测试(10分)

设计对区块链系统的测试流程;结合实际业务需求,调用部署的智能合约中进行系统测试、性能测试等;根据业务需求,分析并且修复给定智能合约中的安全漏洞。利用模拟业务和测试工具完成区块链系统服务数据的测试。

1. 使用命令启动区块链系统可视化一体平台并验证启动情况(1分)

2. 通过可视化平台生成包括生产商(producer)、经销商(distributor)、零售商(retailer)账户,并将账户以p12加密形式导出后,导入指定的前置可视化平台,并验证地址一致性(1分)

3. 使用Postman对上述功能接口进行验证,并将验证结果截图提交工程文档。

  1. 使用Postman对食品溯源系统服务端“获取食品”(/food)功能接口进行验证,并将验证结果截图。(1分)

请求路由:

/food

请求方法:

GET

输入项说明:

输入项

类型

说明

traceNumber

String

食品编号

输出项说明:

输出项

类型

说明

current

String

食品当前所处用户地址

name

String

食品名称

produce

String

食品生产者地址

timestamp

Timestamp

食品生产时间戳

quality

Integer

食品质量

4.参照工程项目(地址:“/root/projects”)使用Caliper测试工具对食品安全溯源系统智能合约获取食品信息(getFood)功能进行压力测试。具体要求如下:

  1. 提供核心测试代码。(2分)
  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. 分析智能合约中存在问题,并说明危害。(1分)
  2. 根据测试工具中的代码文件,编写测试用例,复现智能合约中存在的漏洞。(1分)
  3. 创建新的智能合约,修复其中问题,说明修复内容并测试。(2分)

模块二:智能合约开发与测试(30分)

任务2-1:智能合约设计5分)

根据区块链食品溯源应用需求分析和方案设计文档的描述,完成以下工作要求:

1. 根据区块链食品溯源应用需求分析和方案设计文档的描述,设计智能合约功能。(2分)

2. 设计智能合约中各角色应具备的功能。(1分)

3. 设计智能合约中食品安全溯源功能。(2分)

任务2-2:智能合约开发(20分)

  1. 食品信息(Food)、成员信息(Member)、生产订单信息(Productions)的结构体功能编码(6分)

(1)编写食品信息实体功能。(2分)

表2.2.1 Food实体说明

名称

类型

说明

id

uint

食品编号

name

string

食品名称

foodType

string

食品类型

quality

string

质量

spec

string

规格

other

string

其他信息

updateTime

uint

更新时间

struct Food{

    //①食品编号id

    //②食品名称name

    //③食品类型foodType

    //④质量quality

    //⑤规格spec

    //⑥其他信息other

    //⑦更新时间updateTime

(2)完善智能合约中用户结构体内容(2分)

名称

类型

说明

company

string

公司名称

location

string

地址

tel

string

电话

incharge

string

负责人

mainBusiness

string

主营业务

credit

uint

信誉分

businessType

uint

成员类型(1:生产商 2:收购商 3:运输商 4:销售商)

userAddress

address

创建用户地址

updateTime

uint

更新时间

struct Member {

        //①公司名称

        string location;//地址

        //②电话

        string incharge;//负责人

        string mainBusiness;//主营业务

        uint credit;//信誉值

        //③成员类型(1:生产商 2:收购商 3:运输商 4:销售商)

       //④创建用户地址;

        uint updateTime;

    }

(3)编写生产订单(Productions)结构体信息。(2分)

表2.2.2 生产订单Productios结构体信息

名称

类型

说明

orderNo

uint

溯源订单号

produceNo

uint

生产订单号

orderType

uint

订单类型(1: 直接付款  2:凭证付款)

foodId

uint

食品编号

price

uint

单价

num

uint

生产数量

updateTime

uint

更新时间

createUser

address

订单创建人

struct Productions {

        //①总订单号

        //②食品订单号

        uint orderType;//订单类型(1: 直接付款  2:凭证)

        uint foodId;//产品编号

        uint price;//单价

        uint num;//生产数量

       //③更新时间;

       //④订单创建人

}

2.食品溯源(Trace)的接口编码(6分)

(1)根据食品信息结构体,完成食品信息添加相应功能(2分)

function createFood(①, ②, ③, ④, ⑤, string memory other) public returns(⑥) {

        foodMap[⑦] = Food(foodId, name, foodType, quality, spec, other, ⑧);

        emit CreateFood(foodId, name);

        return foodId;

    }

(2)编写食品溯源收购商创建收购订单功能。

    function Buy(uint orderNo, ①, uint orderType,uint foodId, uint price, uint num) public returns(②) {

        require(userRoleMap[msg.sender] == ③ || msg.sender == owner);

        buyMap[buyNo] = Buys(orderNo,buyNo, orderType, foodId, price, num, now, ④);

        return buyNo;

    }

(3)编写食品溯源创建运输订单功能。

    function Transport(uint orderNo, ①, uint orderType, uint num, string memory from_place, string memory to_place) public returns(②) {

        require(userRoleMap[msg.sender] == ③ || msg.sender == owner);

        transportMap[transportNo] = Transports(orderNo, transportNo, orderType, num, from_place, to_place, now,④ );

        return transportNo;

    }

3.角色(Role)管理的接口编码(4分)

(1)编写食品溯源增加角色接口,实现添加角色的功能。(1分)

function addRole(address userAddress, uint role) public ①{

        userRoleMap[②] = role;

    }

(2)编写食品溯源获取角色功能。(1分)

function getUserRole(address userAddress) public view returns(①) {

        uint role = userRoleMap[②];

        return role;

    }

(3)编写食品溯源修改角色功能。(2分)

function changeRole(address userAddress, uint newrole) public ①{

        userRoleMap[userAddress] = newrole;

        Member storage ②= memberMap[userAddress];

        member.businessType = ③;

        memberMap[userAddress] = ④;

    }

4.合约编译、部署和调用(4分)

(1)解决代码错误和警告,正确编译并部署合约,成功获取部署的合约地址和abi。(1分)

(2)调用食品溯源智能合约的接口,完整验证业务流程。(3分)

任务2-3:智能合约测试(5分)

  1. 配置区块链网络(1分)

启动区块链网络,创建新的Workspace,配置对外访问的RPC接口为7545,配置项目的配置文件config.js实现与新建Workspace的连接。

  1. 设置producerId和sellederId两个变量(1分)

基于VSCODE加载的测试项目,补全位于test文件夹中foodTraceNew.js文件预操作的方法。在测试文件中添加预定义的方法(在其他方法启动前使用),在方法中分别设置producerId和sellederId两个变量,具体要求如下:

(1)producerId设置为1

(2)sellderId设置为4

  1. 补全createMember和getMember方法(1分)

基于VSCODE加载的测试项目,补全位于test文件夹中foodTraceNew.js文件,添加测试用例,测试智能合约的createMember和getMember方法。

  1. 测试createOrder和getOrder方法(1分)

基于VSCODE加载的测试项目,补全位于test文件夹中foodTraceNew.js文件,添加测试用例,测试智能合约的createOrder和getOrder方法。

  1. 测试createFood和getFood方法(1分)

基于VSCODE加载的测试项目,补全位于test文件夹中foodTraceNew.js文件,添加测试用例,测试智能合约的createFood和getFood方法。

模块三:区块链应用系统开发(30分)

任务3-1:前端功能开发(10分)

1.请基于前端系统的开发模板,在组件main.js中添加对应的逻辑代码,实现角色生产商的部分功能,并测试功能完整性。(3分)

示例页面:

本任务具体要求如下:

  1. 生产商首页展示已有的食品列表,若没有食品则显示暂无数据,展示列有溯源码、食品名称、生产商、生产时间;
  2. 生产商首页有“退出”按钮,可以退出登录返回首页;
  3. 生产商页面可以新建食品,弹出框中需要用户输入溯源码、视频名称、生产商、质检情况等,单击取消关闭弹出框,单击确定则根据操作反馈进行提示;
  4. 生产商首页展示的食品列表可根据生产时间排序。

Main.js

代码片段1:

<!-- 创建蔬菜按钮 -->

      <el-button type="primary" @click="popup = true;">选手填写部分</el-button>

      <!-- 退出按钮 -->

      <el-button type="danger" @click="$emit(选手填写部分, false)" class="button-logout">选手填写部分</el-button>

代码片段2:

<!-- 食品信息列表 -->

      <el-table

        :data="renderList"

        style="width: 100%"

        :default-sort =选手填写部分

      >

        <el-table-column

          prop="traceNumber"

          label=选手填写部分

        >

        </el-table-column>

        <el-table-column

          prop="foodName"

          label=选手填写部分

        >

        </el-table-column>

        <el-table-column

          prop="traceName"

          label=选手填写部分

        >

        </el-table-column>

        <el-table-column

          prop="date"

          label=选手填写部分

          选手填写部分

        >

        </el-table-column>

      </el-table>

代码片段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分)

示例页面:、

本任务具体要求如下:

  1. 中间商首页展示已有的食品列表,若没有食品则显示暂无数据,展示列有溯源码、食品名称、上架时间、质检情况、发货单位、收货单位;
  2. 中间商首页有“退出”按钮,可以退出登录返回首页;
  3. 中间商页面可以输入溯源码添加食品信息,输入正确的溯源码后在弹出框中展示相关溯源信息,并在弹出框中可以填写质检情况和收货单位,点击取消弹窗消失,点击确定根据反馈进行提示;
  4. 中间商首页展示的食品列表可根据上架时间排序;
  5. 点击溯源码可显示食品详细信息。

components.js

代码片段1:

<div>

      <el-input

        placeholder="选手填写部分"

        v-model.number="traceNumber"

        clearable>

      </el-input>

      <el-button type="primary" @click=选手填写部分>添加食品信息</el-button>

      <el-button type="danger" @click="$emit(选手填写部分, false)" class="button-logout">选手填写部分</el-button>

代码片段2:

<!-- 食品流转信息列表 -->

      <el-table

        :data="renderList"

        style="width: 100%"

        :default-sort = "{prop: 'date', order: 'descending'}"

        >

        <el-table-column

          prop="traceNumber"

          label=选手填写部分

          >

          <template slot-scope="scope">

        <!-- 鼠标点击食品细节弹窗信息 -->

        <el-popover trigger="click" placement="top" @show="handlePopover(scope.row)" :width="400">

          <FoodDetail :food=选手填写部分 />

          <div slot="reference">

            <span style="color: blue; cursor: pointer;">{{scope.row.traceNumber}}</span>

          </div>

        </el-popover>

      </template>

代码片段3:

<el-table-column

          prop="name"

         选手填写部分

          >

        </el-table-column>

        <el-table-column

        prop="date"

        选手填写部分      选手填写部分

        >

        </el-table-column>

        <el-table-column

          prop="quality"

          选手填写部分

        >

        </el-table-column>

        <el-table-column

          prop="from"

          选手填写部分

        >

        </el-table-column>

        <el-table-column

          prop="to"

          选手填写部分

        >

        </el-table-column>

代码片段4:

template:`

    <div>

      <el-dialog title="选手填写部分" :visible.sync="dialogFormVisible" :show-close="false" width="40%" :center="true">

        <el-form :model="form" ref="form" label-position="left" :label-width="formLabelWidth">

          <el-form-item

            label=选手填写部分

            prop="quality"

            :rules="[

              { required: true, message: 选手填写部分, trigger: 'change' }

            ]">

            <el-radio-group v-model="form.quality">

              <el-radio label="0">优质</el-radio>

              <el-radio label="1">合格</el-radio>

              <el-radio label="2">不合格</el-radio>

            </el-radio-group>

          </el-form-item>

          <el-form-item

            label=选手填写部分

            prop="traceName"

            :rules="[

              { required: true, message: '请输入收货单位' }

            ]">

            <el-input v-model="form.traceName" autocomplete="off"></el-input>

</el-form-item>

        </el-form>

        <div>

          <el-button @click="$emit(选手填写部分, false)">取 消</el-button>

          <el-button type="primary" 选手填写部分>确 定</el-button>

        </div>

        <el-divider></el-divider>

<!-- 食品详情信息 -->

        <TraceDetail :food-detail=选手填写部分:user=选手填写部分/>

3.请基于前端系统的开发模板,在组件components.js中添加对应的逻辑代码,实现角色消费者的部分功能,并测试功能完整性。(4分)

示例页面:

本任务具体要求如下:

  1. 消费者页面左侧可进行溯源码搜索;
  2. 消费者页面右侧可进行食品基本信息和食品流通信息展示。

main.js

代码片段1:

template:`

    <el-row style="height: 100%;" class="consumer">

      <!-- 左边为溯源查询 -->

      <el-col :span="7" style="height: 100%;">

        <div class="grid-content bg-purple">

          <el-form :model="form" ref="form">

            <h4>选手填写部分</h4>

            <el-divider></el-divider>

            <el-form-item

              label=选手填写部分

              prop="traceNumber"

            >

              <el-input v-model.number="form.traceNumber" type="textarea" :rows="3" autocomplete="off" @clear="onSearch = false;"></el-input>

            </el-form-item>

            <el-button type="primary" 选手填写部分  >查询</el-button>

          </el-form>

        </div>

      </el-col>

      <!-- 右边为溯源查询结果 -->

      <el-col :span="16">

        <div class="grid-content bg-purple-light">

          <div v-if ="!onSearch" class="consumer-tip">请在左侧查询栏中输入溯源码进行查询</div> 

          <div v-if ="onSearch && 选手填写部分" class="consumer-tip">该溯源码无对应信息,请确认后重新查询</div> 

          <!-- 溯源查询成功后才展示 -->

          <div v-if ="onSearch && foodDetail.length">

            <!-- 溯源详情组件, user: 3 为消费者 -->

            <TraceDetail :food-detail="选手填写部分" :user="选手填写部分" />

          </div> 

        </div>

      </el-col>

      <el-col :span="1">

        <!--退出按钮 -->

        <el-button type="danger" @click=选手填写部分class="button-logout">退出</el-button>

      </el-col>

    </el-row>

代码片段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分)

本任务具体要求如下:

  1. 开发文件IndexController.java中的add_trace_by_retailer方法,请求接口为/addretail;
  2. 开发文件IndexController.java中的add_trace_by_retailer方法,要求对前端传入的参数进行二次验证;
  3. 开发文件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分)

本任务具体要求如下:

  1. 开发文件IndexController.java中的getlist方法,请求接口为/foodlist,该接口调用私有方法get_food_list,不直接与合约交互,提高系统的安全性;
  2. 开发文件IndexController.java中的get_food_list方法,要求通过合约进行食品列表的查询,且外部无法直接调用;
  3. 开发文件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;i<num_list2.size();i++){

            String 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分)

本题目的具体要求如下:

  1. 开发文件IndexController.java中的food方法,请求接口为/food,该接口调用私有方法get_food,不直接与合约交互,提高系统的安全性;
  2. 开发文件IndexController.java中的food方法,对传入数据进行二次验证;
  3. 开发文件IndexController.java中的get_food方法,要求通过合约进行溯源信息的查询,且外部无法直接调用;
  4. 开发文件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 选色填写部分;

    }

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

SQL32 截取出年龄(substring_index函数的用法)

代码 select substring_index(substring_index(profile,,,3),,,-1) as age ,count(device_id) from user_submit group by age知识点 substring_index(FIELD, sep, n)可以将字段FIELD按照sep分隔&#xff1a; (1).当n大于0时取第n个分隔符(n从1开始)之前的全部内容&#xff1…

【Vision Pro 应用分享】Make It Spatial——将普通照片转化为Spatial空间照片,以在Vision Pro视界眼镜上观看3D效果

该应用目前在Mac App Store上免费提供 下载地址:‎Make It Spatial on the Mac App Store Read reviews, compare customer ratings, see screenshots, and learn more about Make It Spatial. Download Make It Spatial for macOS 14.0 or later and enjoy it on your Mac.h…

BUGKU-WEB 变量1

题目描述 题目截图如下&#xff1a; 进入场景看看&#xff1a; flag In the variable !<?php error_reporting(0); include "flag1.php"; highlight_file(__file__); if(isset($_GET[args])){$args $_GET[args];if(!preg_match("/^\w$/",$args…

Airtest-Selenium实操小课:爬取新榜数据

1. 前言 最近看到群里很多小伙伴都在用Airtest-Selenium做一些web自动化的尝试&#xff0c;正好趁此机会&#xff0c;我们也出几个关于web自动化的实操小课&#xff0c;仅供大家参考~ 今天跟大家分享的是一个非常简单的爬取网页信息的小练习&#xff0c;在百度找到新榜网页&a…

前端工程化面试题 | 09.精选前端工程化高频面试题

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…

从零开始学习数据结构—【链表】—【探索环形链的设计之美】

环形链表 文章目录 环形链表1.结构图2.具体实现2.1.环形链表结构2.2.头部添加数据2.2.1.具体实现2.2.2.测试添加数据 2.3.尾部添加数据2.3.1.具体实现2.3.2.添加测试数据 2.4.删除头部数据2.4.1.具体实现2.4.2.测试删除数据 2.5.删除尾部数据2.5.1.具体实现2.5.2.测试删除数据 …

PFA洗气瓶配空气采样泵用PFA气体吸收瓶的特点

PFA洗气瓶是一种洗去气体中杂质的器皿&#xff0c;是将不纯气体通过选定的适宜液体介质鼓泡吸收&#xff08;溶解或由于发生化学反应&#xff09;&#xff0c;从而洗去杂质气体&#xff0c;以达净化气体的目的。在设计时&#xff0c;四氟球的周围都布满小孔。一般情况下&#x…

【教学类-19-10】20240214《ABAB式-规律黏贴18格-手工纸15*15CM-一页3种图案,AB一组样板,纵向、有边框》(中班)

背景需求 利用15*15CM手工纸制作AB色块手环&#xff08;手工纸自带色彩&#xff09;&#xff0c;一页3个图案&#xff0c;2条为一组&#xff0c;画图案&#xff0c;黏贴成一个手环。 素材准备 代码展示 # # 作者&#xff1a;阿夏 # 时间&#xff1a;2024年2月14日 # 名称&…

LeetCode刷题计划---day2

07 #include <iostream> #include <iomanip> // 头文件用于控制输出格式 using namespace std;int main() {const int n 5; // 等级个数double grade[n] {4.0, 3.0, 2.0, 1.0, 0.0}; // 每个等级对应的分数string input;while (getline(cin, input)) { // 读入一…

我国纯自研水陆两栖大飞机,鲲龙AG600M完成高寒试飞任务

据航空工业官微介绍&#xff0c;近期我国自主研制的大型水陆两栖飞机“鲲龙”AG600M在海拉尔完成最后一项高寒试飞任务。 其动力装置系统、燃油系统、液压系统、飞控系统、航电系统、起落架系统等关键系统通过了高寒地面试验和试飞验证&#xff0c;可满足我国全疆域范围内的森…

如何将阿里云服务器迁移

&#x1f4d1;前言 本文主要是如何将阿里云服务器迁移实现数据转移的文章&#xff0c;如果有什么需要改进的地方还请大佬指出⛺️** &#x1f3ac;作者简介&#xff1a;大家好&#xff0c;我是青衿&#x1f947; ☁️博客首页&#xff1a;CSDN主页放风讲故事 &#x1f304;每日…

【hcie-cloud】【30】华为云Stack应用安全于防护

文章目录 前言Web技术基础和常见Web漏洞Web技术Web系统组成URL结构Web后端技术HTTP/HTTPS协议Cookie/Session简介OWASP TOP 10OWASP TOP 10 2021年版访问控制失效 - 越权访问控制失效 - 跨站请求伪造&#xff08;CSRF&#xff09;URL不安全跳转应用安全法律法规及行业规范 Web应…

React 更改程序入口点(index.js文件位置变更)

食用前提示&#xff1a;本文基于已经快速配置好的React环境而作&#xff0c;配置React环境详见拙作&#xff1a;React环境配置-CSDN博客~ 一、了解默认入口点 使用create-react-app快速搭建react环境后&#xff0c;npm start启动程序的默认入口点为/src/index(即src目录下的ind…

【JavaEE】_HTTP请求首行

目录 1. URL 2. 方法 2.1 GET方法 2.2 POST方法 2.3 GET与POST的区别 2.4 低频使用方法 1. URL 在mysql JDBC中已经提到过URL的相关概念&#xff1a; 如需查看有关JDBC更多内容&#xff0c;原文链接如下&#xff1a; 【MySQL】_JDBC编程-CSDN博客 URL用于描述某个资源…

揭秘京东商品背后的秘密:一键获取详细数据,打造全新购物体验

京东商品详情原数据API接口技术详解 一、概述 京东商品详情原数据API接口是京东开放平台提供的一套用于获取商品详细信息的接口。通过调用该接口&#xff0c;第三方开发者可以获取包括商品描述、价格、图片、评价等详细信息&#xff0c;进而在自己的应用或网站中展示给用户&a…

听说解锁字节扣子,能轻松搭建你的私人AI助手!

一、引子 几年前低代码平台推出了&#xff0c;这种概念应该是未来的一种趋势&#xff0c;不过一直没有被大面积推广起来&#xff0c;或许技术方面还不算成熟。不过随着科技的发展&#xff0c;区块链技术、元宇宙技术、AI技术这些对我们来说触不可及的技术也已经走进大家的视线…

自定义类型详解 ----结构体,位段,枚举,联合

目录 结构体 1.不完全声明 2.结构体的自引用 3.定义与初始化 4.结构体内存对齐与结构体类型的大小 结构体嵌套问题 位段 1.什么是位段&#xff1f; 2.位段的内存分配 枚举 1.枚举类型的定义 2.枚举的优点 联合&#xff08;共同体&#xff09; 1.联合体类型的声明以…

PyCharm 自动添加文件头注释

PyCharm 自动添加文件头注释 1. File and Code Templates2. Python FileReferences 1. File and Code Templates File -> Settings -> Editor -> File and Code Templates -> Python Script Reformat according to style & Enable Live Templates Created by…

UE4 C++联网RPC教程笔记(一)(第1~4集)

UE4 C联网RPC教程笔记&#xff08;一&#xff09;&#xff08;第1~4集&#xff09; 前言1. 教程介绍与资源2. 自定义 Debug 功能3. Actor 的复制4. 联网状态判断 前言 本系列笔记将会对梁迪老师的《UE4C联网RPC框架开发吃鸡》教程进行个人的知识点梳理与总结&#xff0c;此课程…

第三十五回 梁山泊吴用举戴宗 揭阳岭宋江逢李俊-python中用Shell通配符匹配字符串

宋江被抓住&#xff0c;判脊杖二十&#xff0c;刺配江州牢城。临走时宋太公专门叮嘱他不要入伙梁山。 宋江和差人专门挑小路走&#xff0c;想避开梁山&#xff0c;结果还是被赤发鬼刘唐守到了。大家把宋江请上山&#xff0c;都参拜了宋江。看宋江执意要走&#xff0c;吴用说自…