当前位置: 首页 > news >正文

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

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

高职组

“区块链技术应用”

赛项赛卷(9卷)

参赛队编号:             

背景描述

随着异地务工人员的增多,房屋租赁成为一个广阔是市场;目前,现有技术中的房屋租赁是由房主发布租赁信息,租赁信息发布在房屋中介和/或租赁软件,租客获取租赁信息后,现场看房,并签订纸质的房屋租赁合同;房屋租赁费用通过中介或直接给房主;另外,后期的房租还需房主收取。

区块链房屋租赁平台业务流程图

现在利用区块链技术实现房屋租赁系统,将房东、房屋、租客加入到区块链网络中,将发布、租赁、合同、房租等信息存储在区块链的分布式网络中,永久有效,无法篡改。在房屋租赁场景中, 房东将房屋租出后,无法有效控制房屋的使用权,比如租客未履行租赁合约相应内容时,房东无法及时有效限制租客对房屋的使用,造成租金或房屋使用权的回收困难。现有一个基于区块链的房屋租赁平台S,房东L在平台中发布房源,S可以调用该房屋的电子锁E的密码。L在S中发放租房合同给租客T。在租房合同中规定,每个月的16号缴纳房租,房租是3000元,交付形式是押一付一。在T签署合同后的24小时之内,T需要在S中预存3000元押金、3000元房租,如果T未预存,交易失败。如果T预存了押金和房租,L需要在24小时内在S中预存3000元保证金,如果L未在规定时间内预存保证金,S将T的保证金与房租退回,如果L在规定时间内预存了保证金,双方达成交易。S自动将T的一个月房租转账给L,并将房屋E的密码发送给T。在每月16日,E会自动更换密码,如果T按时缴纳房租,S将房屋密码重新更新给T;当T到期未缴纳,S将T的保证金转账给L代替一个月的租金,S仍会将密码更新给T;如果保证金已被扣除后,T仍然到期未缴纳,平台进入等待补缴状态,T将收不到变更后的密码。如果未到租期L提前终止合同,S将L的保证金转给T,如果T还有保证金将保证金一并退还给T。如果未到租期T提前终止合同,如果还有保证金S将T的保证金转给L,T还需赔偿L一个月租金,如果T保证金已被扣除,T需赔偿L两个月租金,S将L的保证金退还L。当合同正常到期,S将L的保证金退还,T如果还有也退还。

区块链房屋租赁平台系统架构图

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

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

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

房屋租赁平台中涉及到租客、房东、区块链租房平台、房屋等参与方,他们需要在区块链租房平台中完成账户注册、身份上链、出租房屋、生成合同等多种业务活动。通过对业务活动的功能分析,可以更好的服务系统的开发流程。基于房屋租赁平台系统架构,以区块链房屋租赁平台为背景,结合账户注册、登录服务、入驻上链、房屋出租、房租缴费等核心功能描述,撰写流程图/功能图、用例图等概要设计。本环节需要依据项目背景完成需求分析与方案设计,具体要求如下:

1. 依据给定区块链房屋租赁平台的业务流程图以及用例表,使用UML工具编制系统业务用例图,用例图中包含系统参与角色以及用例。

表1-1-1 用例表

用例编号

用例标题

优先级

测试步骤

预期

结果

测试结果

HK-TEST-01

房东在区块链房屋租赁平台出租房屋

在房屋租赁页面,点击出租功能按钮,跳转到维护房屋信息的页面

成功跳转

成功跳转

HK-TEST-02

房东在区块链房屋租赁平台发放合同

在租房管理页面获取租客的租房列表信息,在租房列表中点击发放按钮,可以对该租客发放默认的房屋合同

发放成功

发放成功

HK-TEST-03

租客在区块链房屋租赁平台签署合同

在租房管理页面获取租房信息列表,在列表中点击签署按钮,弹窗显示租房合同,将个人信息填充到合同中

收到合同

签署成功

收到合同签署成功

HK-TEST-04

租客在区块链房屋租赁平台缴纳费用

在房租缴费页面,获取租房合同信息列表,在列表中点击缴费按钮,弹窗显示租金和保证金并显示缴费倒计时,在倒计时内缴费成功

合同记录

缴费成功

合同记录

缴费成功

HK-TEST-05

房东在区块链房屋租赁平台缴纳费用

在租房缴费页面,获取租房合同信息列表,在列表中点击缴费按钮,弹窗显示保证金和缴费倒计时,在倒计时内缴费成功

合同记录

缴费成功

合同记录

缴费成功

HK-TEST-06

区块链房屋租赁平台将房租转账给房东

租客、房东缴费成功后,平台自动将房租转账给房东。在房东账户管理界面,显示出收款记录。同时在租客的租赁记录里自动回显房屋的最新电子锁密码

收款成功

电子锁密码回显成功

收款成功

HK-TEST-07

租客或者房东提前终止合同

租客或者房东在合同信息列表页,点击终止按钮,弹窗进行二次确认是否提前终止,确认则进入违约页面

终止成功

终止成功

2. 依据给定的背景信息、区块链房屋租赁业务流程图以及区块链房租租赁平台架构图以及给出的房屋租赁业务的核心流程,使用思维导图工具编制业务系统功能图;

表1-1-2 房屋租赁平台的核心流程

发布租房合同流程

房东起草租房合同协议,填写房屋信息、租期、房租等。使用房东的私钥对租房合同进行签名并广播到区块链中进行存证

签署合同流程

租客解密租房协议,验证租房协议的来源。通过租客节点在租房协议中填写个人信息和签名信息,生成租房合约

租房合约属性文本广播流程

租客对租房合约提炼合约属性文本,使用私钥对合约属性本文以及租房合约进行签名后,广播到区块链中

房东解密合约属性文本流程

房东使用自身私钥对加密后的租房合约进行解密,对解密后的租房合约提炼对照合约属性文本,并使用私钥对对照合约属性文本进行签名后广播到区块链中

缴纳房租流程

区块链房屋租赁平台节点实时房屋到期时间,如果房屋到期时,判断房租缴纳和电子锁密码的更新

3.按照基础层、合约层、接口层以及应用层来设计区块链系统的架构,画出系统架构图,其中在基础层需指明需要的节点、名称、协议、存储等信息;

4.结合案例背景将区块链房屋租赁平台核心功能进行划分,完成下方表格中各个主要模块要实现的功能;

房屋出租模块

请输入要实现的功能

合同发放模块

请输入要实现的功能

合同生效模块

请输入要实现的功能

费用缴纳模块

请输入要实现的功能

租房合约执行模块

请输入要实现的功能

违约判断功能模块

请输入要实现的功能

5.根据用例设计以及下方提供好的承诺集,使用Visio工具完成区块链应用系统业务流程图;

表1-1-3 承诺集

房屋出租承诺

判断房东是否在房屋租赁平台发布房屋

缴纳费用承诺

判断租客是否在房屋租赁平台缴纳房租和预存保证金;判断房东是否在房屋租赁平台预存保证金

房租到期缴纳承诺

判断租客是否按时将房租转账给房东,是则发送电子密码锁,否则解锁保证金

合同到期承诺

判断合同是否到期,是则进入判断保证金是否被转账流程,是则结束,否则退还

6.整合所有内容,模块调用接口编写并形成对应的需求用例文档至【区块链技术应用赛\重命名为工位号】下。

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

通过给定区块链项目需求,进行区块链系统的的部署,包括系统部署、节点部署等。通过监控工具完成对网络、节点服务的监控。最终利用业务需求规范,完成系统日志、网络参数、节点服务等系统结构的维护。

子任务1-2-1:区块链网络环境搭建

在本机部署区块链网络底层环境,我们需要准备编译运行的环境,并通过区块链底层源码脚本文件编译区块链网络。

(1)打开区块链源码文件,检查区块链网络基础运行环境,通过输入命令,检查Docker环境,并确定Docker版本;

(2)打开区块链源码文件,通过输入命令,make编译区块链网络,生成区块链网络编译执行文件,请把编译执行文件截图;

(3)成功编译区块链网络后,通过输入命令,启动区块链服务;

(4)启动区块链网络后,通过输入命令,检查区块链网络状态。

子任务1-2-2:区块链网络服务运行

区块链网络环境成功搭建后,启动区块链网络服务,区块链网络提供了很多的命令行基础功能,满足区块链网络服务的运行。

(1)进入区块链网络执行文件夹(output),通过命令行方式,创建区块链普通钱包账户(userTest),生产区块链钱包地址,私钥,公钥;

(2)进入区块链网络执行文件夹(output),通过命令行方式,获取区块链钱包余额(data/keys);

(3)进入区块链网络执行文件夹(output),通过命令行方式,由data/keys向(userTest)转账10,并查看交易ID;

(4)进入区块链网络执行文件夹(output),通过命令行方式,使用上一步的交易ID,查询交易状态,交易源和目标账号、交易的金额等信息

子任务1-2-3:部署区块链多节点服务

搭建一个3个节点的区块链网络,需要通过命令行创建多节点网络部署环境,并监听各个节点的RPC监听端口,并查看p2p监听渡口配置,现有任务如下:

(1)进入区块链网络主目录下,通过命令行,创建多节点网络部署环境;

(2)进入多节点网络环境目录下,创建多节点网络部署环境后,通过命令行方式,查看P2P网络配置;

(3)节点加入网络需要通过配置种子节点的网络连接地址netURL,请通过命令行方式,获取node3对应的节点netURL。

子任务1-2-4:搭建区块链网络监控系统

镜像提供了Prometheus开源框架,用户可以通过Prometheus+Grafana构建自己应用的监控系统。请按如下步骤,完成对系统的搭建:

(1)进入区块链网络监控系统主目录,通过命令行方式,在节点 env.yaml 配置中打开 metricSwitch;

(2)配置prometheus 设置endpoint服务修改 prometheus.yml 文件,添加如下配置,每个 target 对应区块链节点的 server.yaml 中的 metricPort 端口;

(3)进入到对应目录下,通过命令行启动启动prometheus,打开区块链监控系统项目网址。

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

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

1.启动区块链浏览器系统,找到区块链最新区块列表接口,使用Postman工具对该接口进行HTTP请求测试,并将测试保存;

2.使用测试工具进行测试区块链网络,针对区块链网络吞吐量与时延进行性能指标分析;

3.通过SQL手工注入方法分析区块链系统漏洞,寻找环境注入点,判断注入类型并获取数据库中的信息。

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

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

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

根据房屋租赁系统需求用例文档,设计合约接口,画出各需求用例的时序图。

任务2-2:智能合约开发

使用Solidity语言进行智能合约开发,根据需求用例文档在待补充源码中完成程序接口功能的编码,解决代码错误和警告,正确编译合约,功能调试正确,运行合约进行业务功能的验证,成功获取合约的ABI,将合约部署至区块链,获取部署的合约信息,将任务中编写代码、运行截图。

子任务2-2-1:合同管理合约编码

根据需求用例文档在待补充源码中完成合同管理合约的编码,解决代码错误和警告,正确编译合约,功能调试正确,运行合约中的房东签署合同、租金支付接口功能。

(1)编写房东签署合同接口,完成本合同位置只允许房东签署,通过合同中的信息生成租赁合同的链上哈希,触发协议签署合同的功能,其中合同中的信息包括房东链上账户、租客链上账户、租赁开始时间、租赁结束时间、月租金额、押金金额、交租时间;

(2)编写租金支付接口,完成只允许租客支付租金的规则,检查支付的租金金额是否正确,触发记录租金支付情况的功能。

待补充源码:

contract RentalAgreement {

    address public landlord; // 房东的账户

    address public tenant; // 租客的账户

    uint public rentAmount = 3000; // 每月租金金额(以wei为单位)

    uint public depositAmount = 3000; // 押金金额(以wei为单位)

    uint public rentDueDate = 16; // 租金到期日

    uint public leaseStartDate; // 租赁开始日期

    uint public leaseEndDate; // 租赁结束日期

    uint public leaseDuration; // 租赁期限(以秒为单位)

    bytes32 public contractHash; // 租赁协议的哈希值

    bytes32 public propertyHash; // 租赁物业信息的哈希值

    event AgreementSigned(address indexed _signer, bytes32 _contractHash); // 租赁协议签署事件

    event RentPaid(address indexed _payer, uint _amount); // 租金支付事件

    event DepositPaid(address indexed _payer, uint _amount); // 押金支付事件

    event LeaseTerminated(address indexed _terminator); // 租赁终止事件

    constructor(address _landlord, address _tenant, uint _leaseDuration, bytes32 _propertyHash) {

        landlord = _landlord;

        tenant = _tenant;

        leaseDuration = _leaseDuration; // 初始化租赁期限

        propertyHash = _propertyHash;

    }

   

    /*********** 房东签署合同接口开发 **********/

    /********** 房东签署合同接口开发 ***********/  

   

    /*********** 租金支付接口开发 **********/

    /********** 租金支付接口开发 ***********/  

    function payDeposit() public payable {

        require(msg.sender == tenant, "Only the tenant can pay the deposit."); // 仅允许租客支付押金

        require(msg.value == depositAmount, "Incorrect deposit amount."); // 检查支付的押金金额是否正确

        emit DepositPaid(msg.sender, msg.value); // 触发押金支付事件

    }

    function terminateLease() public {

        require(msg.sender == landlord, "Only the landlord can terminate the lease."); // 仅允许房东终止租赁

        require(block.timestamp < leaseEndDate, "Lease has already ended."); // 检查租赁是否已经结束

        leaseEndDate = block.timestamp; // 更新租赁结束日期为当前时间

        emit LeaseTerminated(msg.sender); // 触发租赁终止事件

    }

}

子任务2-2-2:违约管理合约编码

根据需求用例文档在待补充源码中完成违约管理合约的编码,解决代码错误和警告,正确编译合约,功能调试正确,运行合约中的房东终止合同、租客终止合同接口功能。

(1)编写房东终止合同接口,实现房东终止合同判断,如果租客已经终止合同则合同无效,如果合同有效,对合同终止状态进行标记,将剩余押金退还给租客的功能;

(2)编写租客终止合同接口,实现租客终止合同判断,如果房东已经终止合同则合同无效,如果合同有效,对合同终止状态进行标记,将剩余押金退还给房东的功能。

待补充源码:

contract RentalContract {

    address payable public landlord; // 房东地址

    address payable public tenant; // 租客地址

    uint public rentAmount; // 租金

    uint public securityDeposit; // 押金

    uint public contractStartDate; // 合同开始日期

    uint public contractEndDate; // 合同结束日期

    uint public gracePeriod; // 宽限期

    uint public terminationFee; // 终止合同费用

    bool public contractActive; // 合同是否有效

    bool public landlordTerminated; // 房东是否终止合同

    bool public tenantTerminated; // 租客是否终止合同

    bool public tenantDefaulted; // 租客是否违约

    bool public securityDepositReturned; // 押金是否已退还

   

    constructor(address payable _landlord, address payable _tenant, uint _rentAmount, uint _securityDeposit, uint _contractStartDate, uint _contractEndDate, uint _gracePeriod, uint _terminationFee) {

        landlord = _landlord;

        tenant = _tenant;

        rentAmount = _rentAmount;

        securityDeposit = _securityDeposit;

        contractStartDate = _contractStartDate;

        contractEndDate = _contractEndDate;

        gracePeriod = _gracePeriod;

        terminationFee = _terminationFee;

        contractActive = true;

        landlordTerminated = false;

        tenantTerminated = false;

        tenantDefaulted = false;

        securityDepositReturned = false;

    }

   

    function payRent() public payable {

        require(msg.sender == tenant, "只有租客可以支付租金。"); // 判断是否为租客

        require(msg.value == rentAmount, "租金金额不正确。"); // 判断支付的租金是否正确

        require(contractActive, "合同无效。"); // 判断合同是否有效

        require(block.timestamp <= contractEndDate, "合同已过期。"); // 判断合同是否已过期

        if (block.timestamp > contractStartDate + gracePeriod) { // 如果已经超过宽限期

            tenantDefaulted = true; // 标记租客违约

            if (securityDeposit >= rentAmount) { // 如果押金足够支付租金

                securityDeposit -= rentAmount; // 押金减去租金

            } else {

                securityDeposit = 0; // 押金清零

            }

            if (block.timestamp > contractEndDate) { // 如果合同已经过期

                contractActive = false; // 合同无效

                if (securityDeposit > 0) { // 如果押金还有剩余

                    tenant.transfer(securityDeposit); // 将押金退还给租客

                }

                if (msg.value > rentAmount) { // 如果支付的租金超过了租金金额

                    payable(msg.sender).transfer(msg.value - rentAmount); // 将多余的租金退还给租客

                }

            } else {

                landlord.transfer(rentAmount); // 将租金转账给房东

            }

        } else {

            landlord.transfer(rentAmount); // 将租金转账给房东

        }

    }

   

    function terminateContract() public {

        require(contractActive, "合同无效。"); // 判断合同是否有效

        if (msg.sender == landlord) { // 如果是房东

            require(!landlordTerminated, "房东已终止合同。"); // 判断房东是否已经终止合同

        /*********** 编写房东终止合同接口开发 **********/

        /********** 编写房东终止合同接口开发 ***********/  

        /*********** 编写租客终止合同接口开发 **********/

        /********** 编写租客终止合同接口开发 ***********/  

    }

   

    function getSecurityDeposit() public {

        require(!contractActive, "合同仍然有效。"); // 判断合同是否已经失效

        require(!securityDepositReturned, "押金已经退还。"); // 判断押金是否已经退还

        require(!tenantDefaulted, "租客已违约。"); // 判断租客是否违约

        if (msg.sender == landlord) { // 如果是房东

            securityDepositReturned = true; // 标记押金已经退还

            landlord.transfer(securityDeposit); // 将押金退还给房东

        } else if (msg.sender == tenant) { // 如果是租客

            require(!landlordTerminated, "房东已终止合同。"); // 判断房东是否已经终止合同

            require(!tenantTerminated, "租客已终止合同。"); // 判断租客是否已经终止合同

            require(block.timestamp > contractEndDate, "合同尚未到期。"); // 判断合同是否已经到期

            securityDepositReturned = true; // 标记押金已经退还

            tenant.transfer(securityDeposit); // 将押金退还给租客

        }

    }

}

子任务2-2-3:押金管理合约编码

根据需求用例文档在待补充源码中完成押金管理合约的编码,解决代码错误和警告,正确编译合约,功能调试正确,运行合约中的租客缴纳押金情况查询、房东收取押金情况查询接口功能。

(1)编写租客缴纳押金情况查询接口,实现查询租客是狗已缴纳押金功能;

(2)编写房东收取押金情况查询接口,实现房东是否已收到押金的功能。

待补充源码:

contract Rent {

    uint256 constant deposit = 3000; // 押金金额

    uint256 constant rent = 3000; // 租金金额

    uint256 constant timeLimit = 1 days; // 时间限制

    struct Tenant {

        bool deposited; // 是否已缴纳押金

        bool rentPaid; // 是否已缴纳租金

        uint256 depositTime; // 缴纳押金的时间

    }

    struct Landlord {

        bool deposited; // 是否已收到押金

        uint256 depositTime; // 收到押金的时间

    }

    mapping(address => Tenant) public tenants; // 租户信息

    mapping(address => Landlord) public landlords; // 房东信息

    function tenantDeposit() public payable {

        require(!tenants[msg.sender].deposited && !tenants[msg.sender].rentPaid, "Tenant has already deposited or paid rent"); // 确保租户未缴纳押金或租金

        require(msg.value == deposit + rent, "Tenant must deposit both deposit and rent"); // 确保租户缴纳的金额正确

        tenants[msg.sender].deposited = true; // 标记租户已缴纳押金

        tenants[msg.sender].depositTime = block.timestamp; // 记录缴纳押金的时间

    }

    function landlordDeposit() public payable {

        require(tenants[msg.sender].deposited && tenants[msg.sender].rentPaid, "Tenant has not deposited or paid rent"); // 确保租户已缴纳押金和租金

        require(!landlords[msg.sender].deposited, "Landlord has already deposited"); // 确保房东未收到押金

        landlords[msg.sender].deposited = true; // 标记房东已收到押金

        landlords[msg.sender].depositTime = block.timestamp; // 记录收到押金的时间

    }

    function checkTenantDeposit(address tenant) public view returns (bool) {

        return tenants[tenant].deposited; // 返回租户是否已缴纳押金

    }

    /*********** 租客缴纳押金情况查询接口 **********/

    /********** 租客缴纳押金情况查询接口 ***********/

   

    /*********** 收取押金情况查询接口 **********/

    /********** 收取押金情况查询接口 ***********/

    function checkTenantDepositTime(address tenant) public view returns (uint256) {

        return tenants[tenant].depositTime; // 返回租户缴纳押金的时间

    }

    function checkLandlordDepositTime(address landlord) public view returns (uint256) {

        return landlords[landlord].depositTime; // 返回房东收到押金的时间

    }

    function checkTimeLimit() public view returns (bool) {

        return block.timestamp <= tenants[msg.sender].depositTime + timeLimit; // 返回是否在时间限制内

    }

    function refund() public {

        require(!landlords[msg.sender].deposited && block.timestamp > tenants[msg.sender].depositTime + timeLimit, "Landlord has already deposited or time limit has not been reached"); // 确保房东未收到押金且时间限制已到期

        payable(msg.sender).transfer(deposit + rent); // 将押金和租金退还给租户

    }

}

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

(1)解决代码错误和警告,正确编译合约,成功获取三个合约的ABI;

(2)将三个合约形成一个文件部署至区块链,获取部署合约的地址信息。

任务2-3:智能合约测试

根据需求用例文档完成违约管理的功能测试以及性能测试,解决违约管理合约代码正确性的验证以及验证系统响应时间是否满足预期响应效果,编写功能测试用例,实现违约管理的业务测试,使用测试工具,对合同管理接口进行性能测试。

1.根据需求用例文档在以下测试用例表格中编写违约管理合约中的测用例,依据违约管理中租客违约、房东违约、合同违约的三种状态,分析在前置条件为签署合同、缴纳保证金、押金的情况下,租客提前解除合同、房东提前解除合同、合同失效等情况下,产生的保证金和押金的归属结果;

 

用例编号

用例标题

优先级

前置条件

测试步骤

测试数据

预期结果

FW-RC0001

违约管理(租客违约)

请填写

请填写

请填写

请填写

请填写

请填写

请填写

请填写

请填写

请填写

请填写

请填写

请填写

请填写

请填写

请填写

请填写

请填写

2.利用测试工具,模拟测合同管理接口发送150次请求,将所需HTTP请求、协议、服务器名称或IP以及路径填到工具Web服务器中,连同通请求一起发送的参数,运行成功后将汇总报告提交到指定位置。

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

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

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

完成区块链应用系统的构建、服务器端(后端)与Web端(前端)的接口的联调。要求如下:

1.使用VsCode工具,按照押金详情原型图的长度、宽度、行高、间距、文字样式、颜色等,完成押金详情页面的样式开发;

2.使用VsCode工具,完成Vue调用押金查询接口API,获取接口返回的租房人、房屋位置、楼号、押金金额、收款人、收款日期信息,填充至Vue页面中。

押金详情页面的样式开发补充源码:

.content{

   width: 100%;

   height: 100%;

   background: #EEEEEE;

   .contentModel{

position: absolute;

       top: 50%;

       left: 50%;

       box-sizing: border-box;

       width: 560px;

       padding: 41px 40px 40px;

       background: #fff;

       border-radius: 8px;

       box-shadow: 0 3px 12px 0 #c0c4cc;

       transform: translate(-50%, -50%);

       -ms-transform: translate(-50%, -50%);

       -moz-transform: translate(-50%, -50%);

       -webkit-transform: translate(-50%, -50%);

       -o-transform:translate(-50%, -50%);

   }

// 此处代码补全:按原型图样式,进行长度、宽度、行高、间距、文字样式、颜色等样式设置;

}

押金详情页面的Html开发补充源码:

<template>

   <div class="content">

<div class='contentModel'>

   <!-- 此处代码补全:按照原型图格式,画出租房人、房屋位置、楼号、押金金额、收款人、收款日期信息 -->

</div>

   </div>

</template>

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

子任务3-2-1:区块链网络环境启动

区块链应用系统开发需要区块链底层网络进行支撑,完成和链上数据进行交互,与节点建立链接,完成链上信息查询。要求如下:

(1)打开区块链网络文件目录,通过区块链启动脚本,输入bash control.sh start命令,启动区块链网络;

(2)使用IntelliJ IDEA工具,打开

(src/controller/BlockController.java)文件,在查询区块链信息接口中,使用Java-SDK获取区块链的最新高度和最新交易Hash,并将结果按十进制的整数和字符串类型返回。

启动区块链源码截图:

区块链的最新高度和最新交易Hash接口补充源码:

/**获取最新区块高度和最新交易Hash*/

@RequestMapping(value = "/getBlockInformation")

@ResponseBody

public Map<String,Object> getBlockInformation(FlightInformation flightInformation){

   Map<String,Object> resMap = new HashMap<>();

   try{

     

      // 获取最新区块高度

      long blockHeight = block.getLong("height");

      System.out.println("最新区块高度:" + blockHeight);

      // 获取最新区块交易Hash

      String txHashes = block.getJSONArray("txHashes");

      System.out.println("最新区块交易Hash:" + txHash);

     

      resMap.put("code",200);

      resMap.put("message","请求成功");

      resMap.put("data",null);

   } catch (ClientProtocolException e) {

      log.error("操作失败—log:",e);

      resMap.put("code",500);

      resMap.put("message","请求失败");

   } catch (IOException e) {

      log.error("操作失败—log:",e);

      resMap.put("code",500);

      resMap.put("message","请求失败");

   }catch (Exception e){

      log.error("操作失败—log:",e);

      resMap.put("code",500);

      resMap.put("message","请求失败");

   }

   return resMap;

}

子任务3-2-2:实体类声明和数据库设计

(1)根据“签署房屋租赁合同合约”中变量的字段,在Java项目中声明实体类(HouseLeasingContract),将声明代码结果截图保存;

包含字段:房东的账户公钥(landlord)、租客的账户公钥(tenant)、每月租金金额(rentAmount)、押金金额(depositAmount)、租金到期日(rentDueDate)、租赁开始日期(leaseStartDate)、租赁结束日期(leaseEndDate)、租赁期限(leaseDuration)、租赁协议的哈希值(contractHash)、租赁物业信息的哈希值(propertyHash)。

(2)请打开Mysql命令行,连接数据库,根据第1步声明的实体类,创建数据库表(house_leasing_contract)与表结构字段。

签署房屋租赁合同合约实体字段补充源码:

/**

 * 签署房屋租赁合同实体

 */

public class HouseLeasingContract {

   private static final long serialVersionUID = 1L;

   //在此处进行代码补全,声明签署房屋租赁合同实体字段,并添加Get和Set方法

}

创建house_leasing_contract表补充源码:

CREATE TABLE `house_leasing_contract` (

`id` INT NOT NULL AUTO_INCREMENT COMMENT '主键id',

//在此处进行建表sql语句补全或使用工具创建表字段

`create_time` DATETIME NOT NULL COMMENT '创建时间',

`update_time` DATETIME NOT NULL COMMENT '修改时间',

PRIMARY KEY (`id`) USING BTREE

)

COLLATE='utf8_general_ci'

ENGINE=InnoDB

ROW_FORMAT=COMPACT

;

子任务3-2-3:编写调用查询押金合约接口

已将押金管理合约部署至区块链,通过Java-SDK完成调用押金管理合约接口,获取租房押金信息。要求如下:

(1)接受从Web端接收对应各种参数(包括钱包地址);

(2)调用Java-SDK,运行调用智能合约API,接收租房押金信息传递给前端页面;

(3)租房押金信息查询成功后,将获取到的押金信息进行解析,并通过数据库依赖包(mysql-connector-java-bin.jar)存储到数据库中。

/**获取押金详情接口*/
@RequestMapping(value = "/getBlockCashPledgeInformation")
@ResponseBody
//此处代码补全:接收从Web端传输的参数(包含钱包地址)
public Map<String,Object> getBlockCashPledgeInformation(…){
   Map<String,Object> resMap = new HashMap<>();
   try{
      //此处代码补全:调用Java-SDK,运行调用智能合约API,接收租房押金信息传递给前端页面
//此处代码补全:租房押金信息查询成功后,将获取到的押金信息进行解析,并通过数据库依赖包(mysql-connector-java-bin.jar)存储到数据库中
      resMap.put("code",200);
      resMap.put("message","请求成功");
      resMap.put("data",depositInfo);
   } catch (Exception e){
      log.error("操作失败—log:",e);
      resMap.put("code",500);
      resMap.put("message","请求失败");
   }
   return resMap;
}

相关文章:

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

2023年全国职业院校技能大赛 高职组 “区块链技术应用” 赛项赛卷&#xff08;9卷&#xff09; 任 务 书 参赛队编号&#xff1a; 背景描述 随着异地务工人员的增多&#xff0c;房屋租赁成为一个广阔是市场&#xff1b;目前&#xff0c;现有技术中的房屋租赁是由…...

微服务—RabbitMQ高级(延迟消息)

本博客为个人学习笔记&#xff0c;学习网站&#xff1a;2023黑马程序员RabbitMQ入门到实战教程 高级篇章节 目录 延迟消息 死信交换机 延迟消息插件 下载安装 延迟交换机声明 ​编辑 发送延迟消息 订单状态同步问题 延迟消息 在电商的支付业务中&#xff0c;对于一些库…...

香港服务器如何取消windows的自动更新

大家用过电脑的人对windows系统的自动更新应该都不会陌生&#xff0c;其实香港服务器的使用也是一样的方法。为什么要对香港服 务器windows的自动更新进行关闭呢&#xff1f;其主要原因在于&#xff0c;有些更新是不能更新&#xff0c;一更新话&#xff0c;系统反而会变得不稳定…...

kali虚拟机桥接模式快速设置

第一步&#xff1a;选择 虚拟机 > 设置 > 虚拟机设置&#xff0c;设置桥接模式 不选择复制物理网络连接状态选项&#xff1a; 如果采用DHCP的方式来分配IP地址&#xff0c;当电脑网络从有线或无线网络之间进行移动时&#xff0c;DHCP会重新分配ip地址&#xff0c;即虚拟机…...

「连载」边缘计算(十五)02-18:边缘部分源码(源码分析篇)

&#xff08;接上篇&#xff09; ChannelContext struct定义如下所示。 KubeEdge/beehive/pkg/core/context/context.go // ChannelContext is object for Context channel type ChannelContext struct { //ConfigFactory goarchaius.ConfigurationFactory channels map[…...

MySQL性能调优篇(8)-NoSQL与MySQL的比较

MySQL数据库是一种关系型数据库&#xff0c;而NoSQL是一种非关系型数据库。它们在数据存储和处理方式、数据模型和可扩展性等方面存在一些明显的差异。本文将对MySQL数据库和NoSQL进行比较&#xff0c;并介绍它们的优势和劣势。 首先&#xff0c;MySQL使用表格的形式来存储数据…...

【Linux学习】线程池

目录 23.线程池 23.1 什么是线程池 23.2 为什么需要线程池 23.3 线程池的应用场景 23.4 实现一个简单的线程池 23.4.1 RAII风格信号锁 23.4.2 线程的封装 23.4.3 日志打印 22.4.4 定义队列中存放Task类任务 23.4.5 线程池的实现(懒汉模式) 为什么线程池中需要有互斥锁和条件变…...

利用Docker部署一个简单的springboot项目

文章目录 1、首先利用docker部署一个redis中间件1.1、下载redis镜像1.2、在主机创建redis挂载的目录和文件1.3、部署redis中间件 2、创建springboot项目2.1、修改application.yml2.2、编写controller2.3、启动应用并测试访问 3、将应用打包成镜像3.1、编写Dockerfile3.2、上传文…...

【Java】纯小白的三种工厂模式基础知识学习笔记

工厂模式概念 在Java中&#xff0c;工厂模式是一种设计模式&#xff0c;用于创建对象而无需指定明确的类。工厂模式通过定义一个共同的接口或抽象类来创建对象&#xff0c;然后由工厂类根据特定条件或参数来实例化具体的对象。 工厂模式通常包括三种类型&#xff1a;简单工厂…...

Spring Boot 笔记 006 创建接口_注册

1.1 由于返回数据都是以下这种格式&#xff0c;那么久再编写一个result实体类 报错了&#xff0c;原因是没有构造方法 可以使用lombok的注解自动生成&#xff0c;添加无参的构造器和全参的构造器 package com.geji.pojo;import lombok.AllArgsConstructor; import lombok.NoArg…...

沁恒CH32V30X学习笔记08---基本定时器超时功能

TIM 基本定时器 高级定时器模块包含一个功能强大的 16 位自动重装定时器(TIM1、TIM8、TIM9 和 TIM10) 通用定时器模块包含一个 16 位可自动重装的定时器(TIM2、TIM3、TIM4 和 TIM5) 基本定时器模块包含一个 16 位可自动重装的定时器(TIM6 和 TIM7) 定时器的结构大致可…...

GitHub | 在 GitHub 上在线展示 Vue 项目

简洁版&#xff1a;上传所有代码 << 构建项目并上传 dist 目录 << 设置仓库 << 访问 Step1&#xff1a;在 GitHub 上新建仓库&#xff0c;并将 Vue 项目的代码 push 到该仓库中。坑点在于&#xff0c;如果你是从 GitHub 上 clone 的别人的项目&#xff0c;那…...

Android的Compose

Jetpack Compose 是用于构建原生 Android 界面的新工具包&#xff0c;无需修改任何 XML 布局&#xff0c;也不需要使用布局编辑器。相反&#xff0c;只需调用可组合函数来定义所需的元素&#xff0c;Compose 编译器即会完成后面的所有工作。 简而言之&#xff0c;使用Compose&…...

C++ STL->list模拟实现

theme: smartblue list list文档 list是可以在常数范围内在任意位置进行插入和删除的序列式容器&#xff0c;并且该容器可以前后双向迭代。list的底层是双向链表结构&#xff0c;双向链表中每个元素存储在互不相关的独立节点中&#xff0c;在节点中通过指针指向 其前一个元素…...

基于python+django+vue.js开发的健身房管理系统

功能介绍 平台采用B/S结构&#xff0c;后端采用主流的Python语言进行开发&#xff0c;前端采用主流的Vue.js进行开发。 功能包括&#xff1a;教练管理、会员管理、场地管理、设备管理、用户管理、日志管理、系统信息模块。 源码地址 https://github.com/geeeeeeeek/python_…...

GPT-4对编程开发的支持

在编程开发领域&#xff0c;GPT-4凭借其强大的自然语言理解和代码生成能力&#xff0c;能够深刻理解开发者的意图&#xff0c;并基于这些需求提供精准的编程指导和解决方案。对于开发者来说&#xff0c;GPT-4能够在代码片段生成、算法思路设计、模块构建和原型实现等方面给予开…...

“成像光谱遥感技术中的AI革命:ChatGPT应用指南“

遥感技术主要通过卫星和飞机从远处观察和测量我们的环境&#xff0c;是理解和监测地球物理、化学和生物系统的基石。ChatGPT是由OpenAI开发的最先进的语言模型&#xff0c;在理解和生成人类语言方面表现出了非凡的能力。本课程重点介绍ChatGPT在遥感中的应用&#xff0c;人工智…...

12.25 校招 实习 内推 面经

绿*泡*泡VX&#xff1a; neituijunsir 交流*裙 &#xff0c;内推/实习/校招汇总表格 1、校招 | 百度2024校园招聘持续热招中 校招 | 百度2024校园招聘持续热招中 2、校招 | 毫末智行2024秋招补录进行时 校招 | 毫末智行2024秋招补录进行时 3、实习丨蔚来2024届冬季实习生计…...

深度学习基础之《TensorFlow框架(3)—TensorBoard》

一、TensorBoard可视化学习 1、TensorFlow有一个亮点就是&#xff0c;我们能看到自己写的程序的可视化效果&#xff0c;这个功能就是TensorBoard 2、TensorFlow可用于训练大规模深度神经网络所需的计算&#xff0c;使用该工具涉及的计算往往复杂而深奥。为了方便TensorFlow程…...

杨氏矩阵和杨辉三角

杨氏矩阵 有一个数字矩阵&#xff0c;矩阵的每行从左到右是递增的&#xff0c;矩阵从上到下是递增的&#xff0c;请编写程序在这样的矩阵中查找某个数字是否存在。 要求&#xff1a;时间复杂度小于O(N); 分析 若要满足要求时间复杂度小于O(N)&#xff0c;就不能每一行一个个…...

PostgreSQL教程(四):高级特性

一、简介 在之前的章节里我们已经涉及了使用SQL在PostgreSQL中存储和访问数据的基础知识。现在我们将要讨论SQL中一些更高级的特性&#xff0c;这些特性有助于简化管理和防止数据丢失或损坏。最后&#xff0c;我们还将介绍一些PostgreSQL扩展。 本章有时将引用教程&#xff0…...

168基于matlab的六自由度并联摇摆台的反解控制算法

基于matlab的六自由度并联摇摆台的反解控制算法&#xff0c;stewart平台&#xff0c;配有GUI界面&#xff0c;可以自定义角度&#xff0c;杆长等参数。设定动平台位姿即能得到电机参数。程序已调通&#xff0c;可直接运行。 168 六自由度并联摇摆台 反解控制算法 (xiaohongshu.…...

MDC 日志跟踪笔记

一、前言 本文主要解析应用中比较实在的一个log4j的链路应用&#xff0c;在经过一段时间的应用后发现还是很稳的&#xff0c;就记录一下这个MDC 代表Mapped Diagnostic Context&#xff08;映射式诊断上下文&#xff09;的情况。 Tisp: 它是一个线程安全的存放诊断日志的容器 T…...

MySQL错误-this is incompatible with sql_mode=only_full_group_by完美解决方案

项目场景 有时候&#xff0c;遇到数据库重复数据&#xff0c;需要将数据进行分组&#xff0c;并取出其中一条来展示&#xff0c;这时就需要用到group by语句。 但是&#xff0c;如果mysql是高版本&#xff0c;当执行group by时&#xff0c;select的字段不属于group by的字段的…...

人工智能|机器学习——基于机器学习的舌苔检测

代码下载&#xff1a; 基于深度学习的舌苔检测毕设留档.zip资源-CSDN文库 1 研究背景 1.1.研究背景与意义 目前随着人们生活水平的不断提高&#xff0c;对于中医主张的理念越来越认可&#xff0c;对中医的需求也越来越多。在诊断中&#xff0c;中医通过观察人的舌头的舌质、苔…...

SQL查询转化为 Elasticsearch 查询

使用SQL 转化为查询 Elasticsearch 支持 sql 语句转化为 elasticsearch 的 查询语句 第一步&#xff1a; 打开在线转换工具的网页&#xff0c;进入工具页面 第二步&#xff1a;在指定的输入框中输入需要转换的 sql 语句。 您学会了这么简单的办法...

目标检测教程视频指南大全

魔鬼面具-哔哩哔哩视频指南 必看干货系列(建议搞深度学习的小伙伴都看看,特别是图像相关) 深度学习常见实验问题与实验技巧(适用于所有模型&#xff0c;小白初学者必看!)还在迷茫深度学习中的改进实验应该从哪里开始改起的同学&#xff0c;一定要进来看看了&#xff01;用自身…...

【Linux取经路】文件系统之重定向的实现原理

文章目录 一、再来理解重定向1.1 输出重定向效果演示1.2 重定向的原理1.3 dup21.4 输入重定向效果演示1.5 输入重定向代码实现 二、再来理解标准输出和标准错误2.1 同时对标准输出和标准错误进行重定向2.2 将标准输出和标准错误重定向到同一个文件 三、再看一切皆文件四、结语 …...

JAVA设计模式结构型模式

一、前言 java设计模式主要分为创建型模式&#xff0c;结构型模式和行为型模式。上一篇主要总结了行为型设计模式&#xff0c;本章总结&#xff0c;结构型模式。像创建型模式就不写了&#xff0c;比较简单。大概知道是工厂模式和建造者模式&#xff0c;原型模式就行&#xff0…...

第4讲引入JWT前后端交互

引入JWT前后端交互 Json web token (JWT), 是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准&#xff08;(RFC 7519)&#xff1b; JWT就是一段字符串&#xff0c;用来进行用户身份认证的凭证&#xff0c;该字符串分成三段【头部、载荷、签证】 后端接口测试&…...