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;
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

centos7部署nfs+keepalived+drbd

一、项目需求描述 现在使用的架构是nfskeepalivedrsyncsersync&#xff0c;目前这套架构存在主从nfs节点数据同步不一致问题&#xff0c;大概会有 120s左右的数据延长同步时间&#xff0c;需要提供优化的自动化方案。 二、现有方案缺点 1、切换不能保证主从节点数据一致。 2、…

C++之std::thread线程

std::thread是C11线程库提供的线程创建。参数绑定的是线程需要调用的函数与参数。 1、如何创建 std::thread th;//空的&#xff0c; std::thread th1([]() { //匿名函数&#xff0c; //执行线程代码 }); void thFun(int k)&#xff1b; std::thread th(thFun,10);// thFun为…

四、分类算法 - 随机森林

目录 1、集成学习方法 2、随机森林 3、随机森林原理 4、API 5、总结 sklearn转换器和估算器KNN算法模型选择和调优朴素贝叶斯算法决策树随机森林 1、集成学习方法 2、随机森林 3、随机森林原理 4、API 5、总结

【论文阅读】【yolo系列】YOLO-Pose的论文阅读

Abstract 我们介绍YOLO-pose&#xff0c;一种无热图联合检测的新方法&#xff0c;基于流行的YOLO目标检测框架的图像二维多人姿态估计。 【现有方法的问题】现有的基于热图的两阶段方法是次优的&#xff0c;因为它们不是端到端可训练的&#xff0c;训练依赖于surrogate L1 loss…

Linux pageset

1. 引言 在用户进程发生缺页异常时&#xff0c;Linux内核需要分配所需物理页面以及建立也表映射&#xff0c;来维持进程的正常内存使用需求。而对于分配物理页面仅依赖于buddy系统&#xff0c;对于小order页面的分配效率较低。因此Linux通过在每个cpu维护一个page链表&#xff…

12 Autosar_SWS_MemoryMapping.pdf解读

AUTOSAR中MemMap_autosar memmap-CSDN博客 1、Memory Map的作用 1.1 避免RAM的浪费&#xff1a;不同类型的变量&#xff0c;为了对齐造成的空间两份&#xff1b; 1.2 特殊RAM的用途&#xff1a;比如一些变量通过位掩码来获取&#xff0c;如果map到特定RAM可以通过编译器的位掩码…

爬取链家二手房房价数据存入mongodb并进行分析

实验目的 1.使用python将爬虫数据存入mongodb&#xff1b; 2.使用python读取mongodb数据并进行可视化分析。 实验原理 MongoDB是文档数据库&#xff0c;采用BSON的结构来存储数据。在文档中可嵌套其他文档类型&#xff0c;使得MongoDB具有很强的数据描述能力。本节案例使用的…

IP地址定位可以精确到哪里

IP地址定位能够精确到的位置级别取决于多种因素&#xff0c;包括IP地址的分配方式、数据库的质量和更新频率、用户的移动性等。一般而言&#xff0c;IP地址定位可以精确到市级&#xff0c;甚至可以达到街道级别 https://www.ip66.net/?utm-sourceLJ&utm-keyword?1146 但需…

LeetCode494. Target Sum——01背包

文章目录 一、题目二、题解 一、题目 You are given an integer array nums and an integer target. You want to build an expression out of nums by adding one of the symbols ‘’ and ‘-’ before each integer in nums and then concatenate all the integers. For …

大数据在电商领域的典型应用

大数据作为一种新兴的信息技术&#xff0c;是无法在一定时间范围内用常规软件工具进行捕捉、管理和处理的数据集合&#xff0c;是需要新处理模式才能具有更强的决策力、洞察发现力和流程优化能力的海量、高增长率和多样化的信息资产。 大数据技术是指在数据获取、存储、管理、…

程序媛的mac修炼手册-- 如何彻底卸载Python

啊&#xff0c;前段时间因为想尝试chatgpt的API&#xff0c;需要先创建一个python虚拟环境来安装OpenAI Python library. 结果&#xff0c;不出意外的出意外了&#xff0c;安装好OpenAI Python library后&#xff0c;因为身份认证问题&#xff0c;根本就没有获取API key的权限…

Shader基础的简单实现(基于URP渲染)

一个模型是很多个顶点组成&#xff0c;顶点数据中包含坐标、法线、切线、UV坐标、顶点颜色等等组成。 URP(Universal Render Pipeline)通用渲染管线&#xff0c;是Unity在2019.3版本之后推出的一种新的渲染管线。传统的渲染管线在渲染多光源的情况&#xff0c;是把每一个主要光…

C语言第二十八弹---整数在内存中的存储

✨个人主页&#xff1a; 熬夜学编程的小林 &#x1f497;系列专栏&#xff1a; 【C语言详解】 【数据结构详解】 目录 1、整数在内存中的存储 2、大小端字节序和字节序 2.1、什么是大小端&#xff1f; 2.2、为什么有大小端? 2.3、练习 2.3.1、练习1 2.3.2、练习2 2.…

Java 注解机制解密并发编程的时间之谜:揭开Happens-Before的神秘面纱

优质博文&#xff1a;IT-BLOG-CN 一、简介 为什么需要happens-before原则&#xff1a; 主要是因为Java内存模型 &#xff0c; 为了提高CPU效率&#xff0c;通过工作内存Cache代替了主内存。修改这个临界资源会更新work memory但并不一定立刻刷到主存中。通常JMM会将编写的代码…

Pytorch 复习总结 2

Pytorch 复习总结&#xff0c;仅供笔者使用&#xff0c;参考教材&#xff1a; 《动手学深度学习》Stanford University: Practical Machine Learning 本文主要内容为&#xff1a;Pytorch 线性神经网络。 本文以机器学习中的两大基本问题 —— 回归和分类为例&#xff0c;介绍…

【数据结构初阶 6】二叉树:堆的基本操作 + 堆排序的实现

文章目录 &#x1f308; Ⅰ 二叉树的顺序结构&#x1f308; Ⅱ 堆的概念与性质&#x1f308; Ⅲ 堆的基本操作01. 堆的定义02. 初始化堆03. 堆的销毁04. 堆的插入05. 向上调整堆06. 堆的创建07. 获取堆顶数据08. 堆的删除09. 向下调整堆10. 判断堆空 &#x1f308; Ⅳ 堆的基本…

【selenium】八大元素定位方式|xpath css id name...

目录 一、基础元素定位 二、cssSelector元素定位——通过元素属性定位 三、xpath元素定位——通过路径 1 、xpath绝对定位 &#xff08;用的不多&#xff09; 缺点&#xff1a;一旦页面结构发生变化&#xff08;比如重新设计时&#xff0c;路径少两节&#xff09;&#x…

从计网的角度讲明白什么是网关

网关(Gateway)又称网间连接器、协议转换器。网关在传输层上以实现网络互连&#xff0c;是最复杂的网络互连设备&#xff0c;仅用于两个高层协议不同的网络互连。网关的结构也和路由器类似&#xff0c;不同的是互连层。网关既可以用于广域网互连&#xff0c;也可以用于局域网互连…

JDBC实现连接池

简单上手 使用 JDBC 来执行 SQL 查询和更新操作 import java.sql.*;public class Main {public static void main(String[] args) {String url "jdbc:mysql://localhost:3306/your_database_name";String username "your_username";String password &…

vs2015零基础编译zlib从失败到成功

本博文源于笔者不断尝试从0编译zlib到能够将文件打包成zip的一个简单过程&#xff0c;其中包含了如何下载zlib&#xff0c;如何编译zlib&#xff0c;如何使用zlib等。内容堪比教科书级别&#xff0c;可以收藏&#xff0c;可以自用&#xff0c;希望博文能帮助到读者。 1、下载z…