当前位置:   article > 正文

全国职业技能大赛-区块链技术与应用赛项国赛三卷参考_运行脚本创建三个新的账户(格式为 pem),使用账户 1(account1)指定 群组 1 登录控

运行脚本创建三个新的账户(格式为 pem),使用账户 1(account1)指定 群组 1 登录控

十套答案详细讨论请留言或私信

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

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

  1. 根据题干描述使用Visio或是思维导图工具展现本系统的系统架构图,分为业务平台和支撑平台两个部分。

参考答案:

  1. 根据题干中描述内容,设计总体功能结构图

参考答案:

1.用户模块包括用户注册与登录功能,注册功能用于实现用户数据插入。用于实现合约的准入机制,提高合约的安全性。

2.资产模块包括新增、修改、交易、删除与查询模块。其中增删改查功能用于支撑区块链应用的实现,交易功能实现资产所有权的换绑。

3.能源模块包括新增、修改、交易、删除与查询模块。其中增删改查功能用于支撑区块链应用的实现,交易功能实现用于绑定能源信息的变化与订单记录。

  1. 根据题干中描述内容,完善“系统概要设计说明书.doc”具体工作内容如下:
    1. 将设计内容根据说明书模块需求进行补充,并完善概要设计说明书中的“需求概要”
    2. 完善说明书中接口说明部分内容

参考答案:

    参照“系统概要设计说明书的答案.doc”文档中内容

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

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

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

子任务1-2-1: 搭建区块链系统并验证

参照ipconf文件搭建区块链系统,要求在系统中包括3个独立组织以及6个节点,网络拓扑为星型网络,并且在联盟链中需实现2个数据隔离场景(group1、group2),节点可根据具体业务加入不同的业务场景。具体工作内容如下:

  1. 使用给定工具(地址“/root/tools”),配置区块链系统。
  2. 启动区块链系统全部节点并验证启动情况。
  3. 检查节点的连接状态以及所属场景的共识状态。

参考答案:

命令:bash build_chain.sh -f ipconf -e ./fisco-bcos -p 30300,20200,8545 -v 2.8.0

2. 启动区块链系统全部节点并验证启动情况。

参考答案:

(1)命令: bash nodes/127.0.0.1/start_all.sh

(2)检查全部节点进程全部启动情况

命令: ps -ef | grep -v grep | grep fisco-bcos

3. 检查节点的连接状态以及所属场景的共识状态。

参考答案:

命令: tail -f nodes/127.0.0.1/node1/log/log*  | grep connected

命令: tail -f nodes/127.0.0.1/node1/log/* | grep "g:2.*+++"

子任务1-2-2:搭建区块链系统管理平台并验证

基于给定服务器环境、软件以及工具(地址“/root/tools”),构建区块链系统相关控制台,并通过控制台实现相关系统管理,具体工作内容如下:

  1. 使用给定工具,配置控制台证书。

参考答案:

命令: tar -zxf console.tar.gz

命令: cp -n console/conf/config-example.toml console/conf/config.toml

  1. 使用给定工具,以pem加密方式创建3个区块链账户(Account1、Account2、Account3)。

参考答案:

使用bash get_account.sh创建三个账户。

  1. 使用给定工具,通过Account1登录控制台,并查看区块高度。

参考答案:

使用命令:

./start.sh 1 -pem accounts/0x3f76b7db3a121e3b298228262c971483db3213df.pem

查看区块高度

  1. 使用给定工具,通过Account2登录控制台,并查看共识状态。

参考答案:

查看共识状态

子任务1-2-3:区块链节点运维

基于已完成的区块链系统与管理平台搭建工作,开展区块链节点的加入与退出运维工作,具体内容如下:

  1. 获取node3的节点ID

参考答案:

命令:cat nodes/127.0.0.1/node3/conf/node.nodeid

  1. 启动控制台,在group1中移除node3节点

参考答案:

(1) 启动控制台:命令:bash start.sh

(2) 查看共识节点:命令:getSealerList (此时有5个共识节点)

(3) 移除node3结点:

命令:removeNode 43bb7946657843b16fe2b92a1e3cbf3ec4e4f5dc5067a6803bd2b8e1a09b6d8898999357058b62cb3fb887ff3cf6f93bbec9ccee8199d3d770b55b4b69c71fe6

  1. 检查node3节点共识状态日志

参考答案:

命令:tail -f nodes/127.0.0.1/node4/log/log*  | grep +++ (此时无输出)

子任务1-2-4:区块链网络运维

基于已完成的区块链系统与管理平台搭建工作,开展相关节点运维工作,具体内容如下:

  1. 生成新节点(node4),启动并检查

参考答案:

使用gen_node_cert.sh生成新节点node4

命令: ./gen_node_cert.sh -c nodes/cert/agency -o node4

将新节点node4复制到节点群nodes目录下。

命令:cp -r ./node4/ nodes/127.0.0.1/

  1. 修改新节点配置,并查看节点的nodeid

参考答案:

(1)将新节点node4复制到节点群nodes目录下。

命令:cd nodes/127.0.0.1/ && cp node0/config.ini node0/start.sh node0/stop.sh node4/

(2)修改node4/config.ini。

对于[rpc]模块,修改channel_listen_port和jsonrpc_listen_port;

对于[p2p]模块,修改listen_port并在node.中增加自身节点信息;

命令:vi node4/config.ini

获取新节点ID

命令:cd node4  && cat conf/node.nodeid

  1. 将新节点作为观察节点加入group1当中,并检查是否加入成功

参考答案:

(1)复制群组配置信息

节点4拷贝节点1的node1/conf/group.3.genesis(内含群组节点初始列表)和node1/conf/group.3.ini到node4/conf目录下,不需改动

命令:cp node1/conf/group.1.genesis node4/conf/ && cp node1/conf/group.1.ini node4/conf/

(2)启动新节点node4

命令: cd node4 && bash stop.sh && bash start.sh

检查新节点连接情况

  1. 将区块打包最大交易数量设为2000笔。

参考答案:

(1)启动控制台:命令:bash start.sh

(2)设置区块打包最大交易数量为2000

命令: setSystemConfigByKey tx_count_limit 2000

任务1-3:区块链系统测试

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

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

参考答案:

命令: python3 deploy.py startAll

  1. 使用可视化一体平台,创建user3用户,部署新能源管理合约,调用合约注册功能(account_register),将user3进行注册为“用户”并获取正确返回。

参考答案:

使用平台调用合约,进行如下设置:

设置后进行调用获得如下正确反馈:

  1. 使用可视化一体平台,调用新能源管理合约judgeUserRole功能,验证注册情况。

参考答案:

使用平台调用合约,进行如下设置

  1. 参照工程项目(地址:“/root/projects”)使用Caliper测试工具对新能源管理系统智能合约太阳能板能源信息新增(Energy_insert)功能进行压力测试。具体要求如下:
    1. 提供核心测试代码。

参考答案:

config.yaml:

energyInsert.js

    1. 设置txNumber=10,tps=1,所有测试通过率为100%

参考答案:

执行命令:

npx caliper benchmark run --caliper-workspace caliper-benchmarks --caliper-benchconfig benchmarks/samples/fisco-bcos/newenergy/config.yaml  --caliper-networkconfig networks/fisco-bcos/test-nw/fisco-bcos.json

正确执行结果:

report.html

  1. 智能合约安全漏洞测试。

有如下问题智能合约:

pragma solidity ^0.8.3;

contract EtherGame {

    uint public targetAmount = 7 ether;

    address public winner;

    function deposit() public payable {

        require(msg.value == 1 ether, "You can only send 1 Ether");

        uint balance = address(this).balance;

        require(balance <= targetAmount, "Game is over");

        if (balance == targetAmount) {

            winner = msg.sender;

        }

    }

    function claimReward() public {

        require(msg.sender == winner, "Not winner");

        (bool sent, ) = msg.sender.call{value: address(this).balance}("");

        require(sent, "Failed to send Ether");

    }

}

contract Attack {

    EtherGame etherGame;

    constructor(EtherGame _etherGame) {

        etherGame = EtherGame(_etherGame);

    }

    function attack() public payable {

        address payable addr = payable(address(etherGame));

        selfdestruct(addr);

    }

}

    1. 分析智能合约中存在问题,并说明危害。

参考答案:

在智能合约中使用了selfdestruct方法,使用此方法攻击智能合约将使智能合约无效化,从而使得存钱的账户都无法获得奖励。

    1. 根据truffle工具中的代码文件,编写测试用例,复现智能合约中存在的漏洞。
    2. 创建新的智能合约,修复其中问题,说明修复内容并测试。

参考答案:

在合约中取消对address(this).balance的依赖可以有效帮助合约规避由于合约销毁带来的风险。如下为修复后EthGame智能合约的具体内容:

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.3;

contract EtherGame {

    uint public targetAmount = 3 ether;

    uint public balance;

    address public winner;

    function deposit() public payable {

        require(msg.value == 1 ether, "You can only send 1 Ether");

        balance += msg.value;

        require(balance <= targetAmount, "Game is over");

        if (balance == targetAmount) {

            winner = msg.sender;

        }

    }

    function claimReward() public {

        require(msg.sender == winner, "Not winner");

        (bool sent, ) = msg.sender.call{value: balance}("");

        require(sent, "Failed to send Ether");

    }

}

模块二:智能合约开发与测试

任务2-1:基于“新能源管理”业务逻辑,设计智能合约结构图,以文字的形式描述智能合约实现的总体功能以及配套模块的子功能

子任务2-1-1 编写新能源智能合约功能需求文档

    根据区块链新能源管理项目背景和需求分析,编写该区块链新能源管理的智能合约功能需求文档。

参考答案:

1. 具备合约用户管理功能,包括用户注册与登录功能,注册功能用于实现用户数据插入。用于实现合约的准入机制,提高合约的安全性。

2. 具备合约资产管理功能,包括资产数据的新增、修改、交易、删除与查询模块。其中增删改查功能用于支撑区块链应用的实现,交易功能实现资产所有权的换绑

3. 具备合约能源管理功能,包括能源数据的新增、修改、交易、删除与查询模块。其中增删改查功能用于支撑区块链应用的实现,交易功能实现用于绑定能源信息的变化与订单记录。

子任务2-1-2 完成区块链新能源管理智能合约的设计

1. 设计区块链新能源管理智能合约接口,画出区块链新能源管理智能合约的角色UML用例图。

参考答案:

2. 以图文结合的方式描述智能合约各参与实体间的关系

参考答案:

1、新能源管理智能合约中需包含用户模块、资产模块、能源模块。首先,需要通过用户模块新增用户信息,当资产模块与能源模块需要有数据插入时,新数据需要与用户模块绑定,不能独立存在。

2、当资产模块中的资产所有权发生变化时,需要修改对应资产信息进行换绑。

3、当能源模块中存在能源交易时,对应用户绑定能源信息要发生变化

任务2-2:使用Solidity语言进行智能合约开发;

子任务2-2-1:太阳能板管理接口编码

1. 根据文档要求,编写太阳能板新增接口功能,必须将新增太阳能板数据存入指定表中,在存储完成后需触发后事件并返回存储与否的标识。

参考答案:

完善SolarPanelsStorage.sol文件中的insert函数,具体内容如下:

2. 根据文档要求,编写太阳能板修改接口,必须通过指定表修改完成数据更新,在完成更新后需触发事件并返回更新与否的标识。

参考答案:

完善SolarPanelsStorage.sol文件中的update函数,具体内容如下:

子任务2-2-2:能源管理接口编码

1. 根据文档要求,编写能源新增接口功能,必须将新增能源数据存入指定表中,在存储完成后需触发后事件并返回存储与否的标识。

参考答案:

完善EnergyStorage.sol文件中的update函数,具体内容如下:

2. 根据文档要求,编写能源修改接口,必须通过指定表修改完成数据更新,在完成更新后需触发事件并返回更新与否的标识。

参考答案:

完善EnergyStorage.sol文件中的update函数,具体内容如下:

子任务2-2-3:合约部署和调用

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

参考答案:

2. 调用太阳能板查询合约接口,完整验证业务流程。

参考答案:

(1)注册,授权“用户”身份

(2)使用注册用户地址新增数据,使用SPU_insert函数

(3)查询新增太阳能板数据

通过get_numid_Spu查询太阳能板

3. 调用能源查询合约接口,完整验证业务流程。

参考答案:

1. 使用energy_insert接口,新增能源。

2. 使用太阳能板编号查询新增能源。(get_numid_Energy)

任务2-3:使用Solidity语言进行智能合约测试

1. 调用太阳能板查询合约接口,完整验证业务流程。

参考答案:

(1)使用注册用户地址新增数据,使用SPU_insert函数

(2)查询新增太阳能板数据

通过get_numid_Spu查询太阳能板

2. 调用能源查询合约接口,完整验证业务流程。

参考答案:

(1) 使用energy_insert接口,新增能源。

(2) 使用太阳能板编号查询新增能源。(get_numid_Energy)

模块三:区块链应用系统开发

任务3-1:区块链应用前端功能开发

(1)请基于前端系统的开发模板,在注册组件Register.vue、中添加对应的逻辑代码,实现对前端的角色选择功能,并测试功能完整性,示例页面如下:

本题目的具体要求如下:

  1. 需要填写的项有地址、角色、密码
  2. 地址项输入框默认内容为“请输入0x开头的用户地址”,若不满足则报错
  3. 角色使用单选按钮组件,可选项为“用户”和“电力公司”
  4. 密码项需验证长度大于6位,输入框默认内容为“请输入6位以上的密码”
  5. 页面需要有“返回”按钮,可以返回登录页面
  6. 注册成功后返回登录页面

Register.vue

代码片段1:

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

    <el-col :span="8" :offset="8" class="register-box">

      <el-row>

        <el-col :span="16" :offset="4">

          <el-form :model="queryForm" ref="queryForm" label-width="100px">

            <h2>注册页面</h2>

            <el-form-item label="地址:" prop="address">

              <input type="primary" placeholder="请输入0x开头的用户地址" v-model="registerdata.address"/>

            </el-form-item>

            <el-form-item label="角色:" prop="role">

              <el-radio-group v-model="registerdata.role">

                <el-radio label="1">用户</el-radio>

                <el-radio label="2">电力公司</el-radio>

              </el-radio-group>

            </el-form-item>

            <el-form-item label="密码:" prop="password">

              <input type="primary" placeholder="请输入6位以上的密码" v-model="registerdata.password"

              show-password/>

            </el-form-item>

          </el-form>

        </el-col>

      </el-row>

      <el-row style="margin-bottom: 20px">

      <el-col :span="16" :offset="4">

        <el-button type="primary" @click="register" round>注册</el-button>

        <el-button type="primary" @click="goback" round>返回</el-button>

      </el-col>

      </el-row>

</el-col>

代码片段2:

      goback: function () {

      this.$router.push('/login')

      },

代码片段3:

      register: function() {

        // 表单信息检查

        if(!this.registerdata.address.startsWith("0x"))

        {

          alert("地址填入内容不符合要求!")

          return

        }

        if(this.registerdata.role == "")

        {

          alert("请选择角色!")

          return

        }

        if(this.registerdata.password.length < 6)

        {

          alert("密码太短!")

          return

        }

          this.axios.post('/account/register', this.registerdata).then((response) => {

              if (response.data.code == 200) {

                  alert('注册成功')

                  this.$router.push('/login')

              }else {

                  alert(`注册失败, ${response.data.data}`)

              }

          })

        },

(2)请基于前端系统的开发模板,在登录组件Login.vue文件中添加对应的登录逻辑代码,实现对后端系统的登录功能,并测试功能完整性(1.5分)

本题目的具体要求如下:

  1. 需要填写的项有地址、密码,且密码以密文形式展现
  2. 地址填写栏默认内容为“请输入0x开头的用户地址”
  3. 页面需要有“注册”按钮,可以跳转注册页面
  4. 点击“登录”按钮时需要验证,地址栏内容需以”0x”开头,密码需大于6位
  5. 对登录密码进行简单加密,传输内容为原内容后增加字符串“pd”
  6. 登录成功后进入首页

参考界面如下:

Login.vue

代码片段1:

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

    <el-col :span="8" :offset="8" class="login-box">

      <el-row >

        <el-col :span="16" :offset="4">

          <el-form label-width="100px">

            <h2>电力能源交易系统登录</h2>

            <el-form-item label="地址:">

              <input type="primary" placeholder="请输入0x开头的用户地址" v-model="logindata.address"/>

            </el-form-item>

            <el-form-item label="密码:">

              <input type="password" v-model="logindata.password"/>

            </el-form-item>

          </el-form>

        </el-col>

      </el-row>

      <el-row style="height: 50px">

        <el-col :span="16" :offset="4">

        <el-button type="primary" @click="loginfun" round>登录</el-button>

        <el-button type="primary" @click="register" round>注册</el-button>

        </el-col>

      </el-row>

代码片段2:

      loginfun() {

        // 表单信息检查

        if(!this.logindata.address.startsWith("0x"))

        {

          alert("地址填入内容不符合要求!")

          return

        }

        if(this.logindata.password == "")

        {

          alert("密码不能为空!")

          return

        }

        else{

          this.logindata.password = this.logindata.password + "pd"

        }

        console.log(this.logindata.password )

        this.axios.post('/account/login', this.logindata).then((response) => {

          if (response.data.code == 200) {

              this.$cookies.set("useraddress", response.data.data)

              console.log(this.$cookies.get('useraddress'))

              // this.uaddress = response.data.data

              this.$router.push('/')

          }

        })

      },

代码片段3:

      register: function () {

          this.$router.push('/register')

      },

(3)请基于前端系统的开发模板,编写个人产权组件MyAsset.vue文件,实现对个人能源的管理功能,并测试功能完整性

本题目的具体要求如下:

  1. 界面有明确的资产相关提示语
  2. 界面需要展现当前用户设备列表,无设备时要给出提示
  3. 对于每个列出的设备在操作栏增加“出售”按钮,可添加出售订单,点击后应有弹出框提示用户填写相关信息(设备编号、所属权、价格)用于出售,该弹出框有“确认”按钮,点击该按钮有结果提示

MyAsset.vue

代码片段1:

        <el-row gutter="20" type="flex" justify="space-between">

          <el-col style="margin-bottom:0px">

            <el-page-header content="资产列表" @back="goBack"/>

          </el-col>

          <el-divider direction="horizontal " />

          <el-col :span="2" style="margin-bottom:10px">

              <el-button primary @click="add">新增设备</el-button>

          </el-col>

        </el-row>

        <el-row gutter="20" type="flex" justify="space-between">

        <el-col>

        <el-table :data="tableData" stripe border  style="width: 100%">

            <el-table-column type="selection" width="55"></el-table-column>

            <el-table-column fixed prop="numid" label="设备编号" width="150" show-overflow-tooltip />

            <el-table-column prop="name" label="设备名称" width="150" />

            <el-table-column prop="actual_Power" label="功率" width="150" />

            <el-table-column prop="rated_Power" label="额定功率" width="150" />

            <el-table-column prop="input_Time" label="生效时间" width="100" />

            <el-table-column prop="position" label="投放地点" width="150" />

            <el-table-column prop="price" label="单价" width="120" />           

            <el-table-column prop="Ownership" label="所属权" show-overflow-tooltip width="170" />

            <el-table-column fixed="right" label="操作" width="150">

            <template #default>

                <el-button link type="primary" size="small" @click="handleClick">出售</el-button>

            </template>

            </el-table-column>

        </el-table>

代码片段2:

        <el-dialog v-model="dialogFormVisible2" title="创建订单">

          <el-form>

            <el-form-item label="设备编号">

              <input v-model="createOrderPrice._numid"/>

            </el-form-item>

            <el-form-item label="所属权">

              <input v-model="createOrderPrice.address"/>

            </el-form-item>

            <el-form-item label="价格">

              <el-input v-model="createOrderPrice._price"/>

            </el-form-item>         

          </el-form>

          <template #footer>

            <span class="dialog-footer">

              <el-button @click="dialogFormVisible2 = false">离开</el-button>

              <el-button type="primary" @click="saller">确认</el-button>

            </span>

          </template>          

        </el-dialog>

代码片段3:

    saller() {

      this.axios.post(`/SPU_saller`, this.createOrderPrice).then((res) => {

        if (res.data.code == 200){

          alert('添加成功')

          this.dialogFormVisible2 = false

          this.listinfo()

        }else('添加失败')

      })

    }

  },

代码片段4:

    goBack() {

        this.$router.push('/')

    },

    // 新增

    add() {

      this.dialogFormVisible = true

    },

    handleClick() {

      this.dialogFormVisible2 = true

    },

    getAssert(){

      let _Address = this.$cookies.get('useraddress')

      this.axios.get(`/get_Address_Assert?_Address=${_Address}`).then((res) => {

        if (res.data.code == 200){

          this.tableData = res.data.data

        }else{

          alert(`失败,$(res.data.data)`)

        }

      })     

},

(4)请基于前端系统的开发模板,编写产权市场组件Market.vue文件,实现产权的查询和交易功能,并测试功能完整性

本题目的具体要求如下:

  1. 界面有明确的产权市场相关提示语
  2. 界面有输入框,提示用户输入产权型号,有搜索按钮可供搜索
  3. 搜索结果展示页面展示该产权的具体信息,包括型号、卖方、额定功率、实际功率、投入时间、所在位置,有“购买”按钮可进行购买操作
  1. 点击“购买按钮”,提示用户输入设备编号、所属权、当前账号,该弹出框有“确认”按钮,点击该按钮有结果提示

参考界面如下:

Market.vue

代码片段1:

    <el-container style="height: 100% ">

      <el-aside width="auto"><Aside></Aside></el-aside>

      <el-container>

        <el-header><Header></Header></el-header>

        <el-main>

        <el-row><el-col>

            <el-page-header content="产权市场" @back="goBack"/>

        </el-col></el-row>

        <el-divider direction="horizontal " />

代码片段2:

        <el-row>

          <el-input placeholder="请输入想要查找的型号" v-model="searchs" style="margin-bottom:20px">

            <template #append>

              <el-button @click="getData">

                <el-icon><Search /></el-icon>

              </el-button>

            </template>

          </el-input>

代码片段3:

            <el-card :body-style="{ padding: '0px' }" style="margin-bottom: 20px">

              <img

              v-for="item2 in imgs"

              :key="item2"

                :src="item2.img"

                class="image"/>

                  <span>

                    总价:

                  </span>

                  <span>

                    {{item.price}}

                  </span>

              <div style="padding: 14px">

                <span>{{item.name}}</span>

                <div class="bottom">

                  <time class="time">{{ currentDate }}</time>

                  <el-button text @click="drawer = true">详细信息</el-button>  

                  <el-button text @click="transferorder = true">购买</el-button>             

                </div>

                <el-form size="mini">

                  <el-form-item label="型号:">

                    {{item.numid}}

                  </el-form-item>

                  <el-form-item label="卖方:">

                    {{item.Ownership}}

                  </el-form-item>

                  <el-form-item label="额定功率:">

                    {{item.rated_Power}}

                  </el-form-item>

                  <el-form-item label="实际功率:">

                    {{item.actual_Power}}

                  </el-form-item>

                  <el-form-item label="投入时间:">

                    {{item.input_Time}}

                  </el-form-item>

                  <el-form-item label="所在位置:">

                    {{item.position}}

                  </el-form-item>

                </el-form>

代码片段4:

            <el-dialog v-model="transferorder" title="购买确认">

              <el-form>

                <el-form-item label="设备编号">

                  <input v-model="owner._numid"/>

                </el-form-item>

                <el-form-item label="所属权">

                  <input v-model="owner.ownership"/>

                </el-form-item>

                <el-form-item label="当前账号">

                  <el-input v-model="owner.address"/>

                </el-form-item>         

              </el-form>

              <template #footer>

                <span class="dialog-footer">

                  <el-button @click="transferorder = false">离开</el-button>

                  <el-button type="primary" @click="transfer">确认</el-button>

                </span>

              </template>       

            </el-dialog>

              </div>

            </el-card>

代码片段5:

    transfer() {

      this.axios.post(`/SSPU_transfer`, this.owner).then((res) => {

        if (res.data.code == 200){

          alert('购买成功')

          this.transferorder = false

        }else{

          alert('购买失败')

        }

      })

},

代码片段6:

    getData() {

      let _numid = this.searchs

      this.axios.get(`/get_numid_Spu?_numid=${_numid}`).then((res) => {

        console.log(res.data.data)

        if(res.data.code == 200 ){

          this.list_data = res.data.data

          console.log(res.data.data)

        }else{

          alert(`失败,$(res.data.data)`)

        }

      })

    }

  },

(5)请基于前端系统的开发模板,编写管理员的区块链浏览器组件Browser.vue文件,实现底层合约的管理,并测试功能完整性

本题目的具体要求如下:

  1. 界面有明确的区块链浏览器相关提示语
  2. 展示页面展示合约名称、合约地址、部署时间、创建时间、修改时间
  3. 后端代码完成后截图

参考界面如下:

Browser.vue

代码片段1:

            <el-page-header content="区块链浏览器" @back="goBack" />

          </el-col>

          <el-divider direction="horizontal " />

          <el-col>

            <el-table

                :data="contracts"

                style="width: 100%">

              <el-table-column

                  prop="合约名称"

                  label="合约名称"

                  width="180">

              </el-table-column>

              <el-table-column

                  prop="合约地址"

                  label="合约地址"

                  width="180">

              </el-table-column>

              <el-table-column

                  prop="部署时间"

                  label="部署时间">

              </el-table-column>

              <el-table-column

                  prop="创建时间"

                  label="创建时间">

              </el-table-column>

              <el-table-column

                  prop="修改时间"

                  label="修改时间">

              </el-table-column>

代码片段2:

  created() {

    this.axios.get(`/list`).then((response) => {

      if(response.data.result){

        this.contracts = response.data.result

      }

    })

  },

任务3-2:区块链应用后端功能开发

(1)请基于已有的项目,基于WeBASEUtils.java工具类,编写注册相关文件,实现注册接口,并测试功能完整性。

本题目的具体要求如下:

  1. 开发注册文件RegisterBO.java实现注册功能实体的定义包含登录页面所传递的三个变量:地址、角色、密码,并补充get、set方法
  2. 开发账户管理文件AccountService.java中注册部分,再次验证前端传值,合约的交互逻辑,返回值封装成为Result结果类

开发账户管理入口文件AccountController.java中注册部分,要求接口地址为/account/register

RegisterBO.java

代码片段1:

public class RegisterBO {

    String address;

    String role;

    String password;

    public String getAddress() {

        return address;

    }

    public void setAddress(String address) {

        this.address = address;

    }

    public String getRole() {

        return role;

    }

    public void setRole(String role) {

        this.role = role;

    }

    public String getPassword() {

        return password;

    }

    public void setPassword(String password) {

        this.password = password;

    }

}

AccountService.java

代码片段1:

    public  Result<String> RegisterService(RegisterBO registerBO) {

        List funcParam = new ArrayList();

        funcParam.add(registerBO.getAddress());

        funcParam.add(registerBO.getRole());

        funcParam.add(registerBO.getPassword());

        Dict result = weBASEUtils.commonReq(userAddress,

                "account_register", funcParam, ABI, "NewEnergy", contractAddress);

        JSONObject respBody = JSONUtil.parseObj(result.get("result"));

        String data = (String)respBody.get("message");

        if (data.equals("Success")) {

            return Result.success("ok");

        }else {

            return Result.error(ResultVO.PARAM_EMPTY);

        }

}

AccountController.java

代码片段1:

    @Autowired

    AccountService accountService;

    @RequestMapping(value = "/register", method = RequestMethod.POST)

    public Result<String> register(@RequestBody RegisterBO registerBO) {

        return accountService.RegisterService(registerBO);

    }

(2)请基于已有的项目,基于WeBASEUtils.java工具类,编写登录相关文件,实现登录接口,并测试功能完整性。

本题目的具体要求如下:

  1. 开发注册文件LoginBO.java实现功能实体的定义,包含登录页面所传递的两个变量:地址、密码并补充get、set方法
  2. 开发账户管理文件AccountService.java中登录部分,实现与合约的交互逻辑,返回值封装成为Result结果类

开发账户管理入口文件AccountController.java中登录部分,要求接口地址为/account/login

LoginBO.java

代码片段1:

public class LoginBO {

    String address;

    String password;

    public String getAddress() {

        return address;

    }

    public void setAddress(String address) {

        this.address = address;

    }

    public String getPassword() {

        return password;

    }

    public void setPassword(String password) {

        this.password = password;

    }

}

AccountService.java

代码片段1:

    public  Result LoginService(LoginBO loginBO) {

        List funcParam = new ArrayList();

        funcParam.add(loginBO.getAddress());

        funcParam.add(loginBO.getPassword());

        Dict result = weBASEUtils.commonReq(userAddress,

                "account_login", funcParam, ABI, "NewEnergy", contractAddress);

        JSONArray respBody = JSONUtil.parseArray(result.get("result"));

        String data = (String)respBody.get(0);

        if (data.equals("true")){

            return Result.success(loginBO.getAddress());

        }else {

            return Result.error(ResultVO.PARAM_EMPTY);

        }

    }

AccountController.java

    @RequestMapping(value = "/login", method = RequestMethod.POST)

    public Result<String> login(@RequestBody LoginBO loginBO) {

        return accountService.LoginService(loginBO);

    }

(3)请基于已有的项目,基于WeBASEUtils.java工具类,编写产权管理相关文件,实现产权管理的相关接口,并测试功能完整性。(4分)

本题目的具体要求如下:

1.开发文件SPU_sallerBO.java实现功能实体的定义,包含变量用户地址、价格和产权编号,并补充get、set方法

2.开发管理文件NewEnergyService.java中产权出售部分,对前端的数据进行二次验证,要求用户地址为0x开头的数据串,实现与合约的交互逻辑,返回值封装成为Result结果类

3.开发管理入口文件NewEnergyController.java中产权出售部分,要求接口地址为/SPU_saller,接口可接受请求方法为POST

SPU_sallerBO.java:

public class SPU_sallerBO {

    String _numid;

    String _price;

    String address;

    public String get_numid() {

        return _numid;

    }

    public void set_numid(String _numid) {

        this._numid = _numid;

    }

    public String get_price() {

        return _price;

    }

    public void set_price(String _price) {

        this._price = _price;

    }

    public String getAddress() {

        return address;

    }

    public void setAddress(String address) {

        this.address = address;

    }

}

NewEnergyService.java:

 public  Result<String> SPU_sallerService(SPU_sallerBO spu_sallerBO) {

    List funcParam = new ArrayList();

    if(!spu_sallerBO.getAddress().startsWith("0x")){

      return Result.error(ResultVO.ADDRESS_INVALID);

    }

    funcParam.add(spu_sallerBO.get_numid());

    funcParam.add(spu_sallerBO.get_price());

    funcParam.add(spu_sallerBO.getAddress());

    Dict result = weBASEUtils.commonReq(userAddress,

            "SPU_saller", funcParam, ABI,

            "NewEnergy", contractAddress);

    JSONObject  resBody = JSONUtil.parseObj(result.get("result"));

    String data = (String) resBody.get("message");

    if (data.equals("Success")) {

      return Result.success("ok");

    }else {

      return Result.success("failed");

    }

  }

NewEnergyController.java:

 @RequestMapping(value = "/SPU_saller", method = RequestMethod.POST)

    public Result<String> SPU_saller(@RequestBody SPU_sallerBO spu_sallerBO) {

        return newEnergyService.SPU_sallerService(spu_sallerBO);

}

(4)请基于已有的项目,基于WeBASEUtils.java工具类,编写产权交易相关文件,实现产权交易的相关接口,并测试功能完整性。

本题目的具体要求如下:

1.开发文件SpuVO.java实现功能实体的定义,包含变量:设备编号、设备名称、实际功率、额定功率、结束时间、工作地点、单价、所属权,并补充get、set方法

2.开发文件SPU_sallerBO.java实现功能实体的定义,包含变量:产权编号、价格、用户地址,并补充get、set方法

3.开发管理文件NewEnergyService.java中产权交易、查询部分,实现与合约的交互逻辑,返回值封装成为Result结果类

4.开发管理文件NewEnergyController.java中产权交易,要求接口地址为/SSPU_transfer,请求方法为POST;产权查询部分,要求接口为/get_numid_Spu_,请求方法为GET

SpuVO.java:

public class SpuVO {

    String _numid;

    String name;

    String actual_Power;

    String rated_Power;

    String input_Time;

    String position;

    String price;

    String address;

    public String get_numid() {

        return _numid;

    }

    public void set_numid(String _numid) {

        this._numid = _numid;

    }

    public String getName() {

        return name;

    }

    public void setName(String name) {

        this.name = name;

    }

    public String getActual_Power() {

        return actual_Power;

    }

    public void setActual_Power(String actual_Power) {

        this.actual_Power = actual_Power;

    }

    public String getRated_Power() {

        return rated_Power;

    }

    public void setRated_Power(String rated_Power) {

        this.rated_Power = rated_Power;

    }

    public String getInput_Time() {

        return input_Time;

    }

    public void setInput_Time(String input_Time) {

        this.input_Time = input_Time;

    }

    public String getPosition() {

        return position;

    }

    public void setPosition(String position) {

        this.position = position;

    }

    public String getPrice() {

        return price;

    }

    public void setPrice(String price) {

        this.price = price;

    }

    public String getAddress() {

        return address;

    }

    public void setAddress(String address) {

        this.address = address;

    }

}

NewEnergyService.java:

public  Result<String> SPU_transferService(SPU_transferBO spu_transferBO) {

    List funcParam = new ArrayList();

    funcParam.add(spu_transferBO.get_numid());

    funcParam.add(spu_transferBO.getAddress());

    funcParam.add(spu_transferBO.getOwnership());

    Dict result = weBASEUtils.commonReq(userAddress,

            "SPU_transfer", funcParam,

            ABI, "NewEnergy", contractAddress);

    JSONObject  resBody = JSONUtil.parseObj(result.get("result"));

    String data = (String) resBody.get("message");

    if (data.equals("Success")) {

      return Result.success("ok");

    }else {

      return Result.success("failed");

    }

  }

 public Result get_numid_SpuService(String _numid) {

    List funcParam = new ArrayList();

    funcParam.add(_numid);

    Dict result = weBASEUtils.commonReq(userAddress,

            "get_numid_Spu", funcParam, ABI,

            "NewEnergy", contractAddress);

    JSONArray resBody = JSONUtil.parseArray(result.get("result"));

    JSONArray res =  JSONUtil.parseArray(resBody.get(0));

    JSONArray array = new JSONArray();

    for (int i = 0; i < res.toArray().length; i++){

      JSONObject jsonObject = JSONUtil.parseObj(res.get(i));

      array.add(jsonObject);

    }

    return Result.success(array);

  }

NewEnergyController.java:

@RequestMapping(value = "/SSPU_transfer", method = RequestMethod.POST)

    public Result<String> SSPU_transfer(@RequestBody SPU_transferBO spu_transferBO) {

        return newEnergyService.SPU_transferService(spu_transferBO);

    }

    @RequestMapping(value = "/get_numid_Spu", method = RequestMethod.GET)

    public Result get_numid_Spu(@RequestParam("_numid") String _numid) {

        return newEnergyService.get_numid_SpuService(_numid);

    }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/盐析白兔/article/detail/600049
推荐阅读
相关标签
  

闽ICP备14008679号