项目开发
学习目标
1. 了解项目背景和用户诉求
2. 了解项目需求和区块链系统组成
3. 利用第三方云平台完成区块链系统服务创建
4. 独立完成个人信息认证
5. 独立完成房屋信息认证
6. 独立完成个人征信认证
7. 独立完成电子合同和租金记录管理
租房网区块链系统
场景分析
近年来,租房这个相对偏传统的行业,在快速发展中已经成为不少大城的“痛”,虚假房源泛滥、黑中介横行、租客
和房东之间缺乏信任、行业交易效率低下等问题一直存在。
用户诉求
构建一个更加可靠的互联网租房系统,从根本上解决价值交换与转移中存在的欺诈和寻租等现象。租房者和出租人
信息不对称等问题。
项目背景
中国银行与蚂蚁金服合作,通过区块链技术助力“雄安”租房赁领域
4月20日 ,蚂蚁雄安数字技术有限公司(下称“蚂蚁雄安”)与中国银行雄安分行在雄安新区签署战略合作协议据了
解,未来双方将基于在区块链技术打造的雄安住房租赁相关领域开展深度合作,为各方提供相关金融服务支持,以
此助力新区在住房租赁领域快速发展。
项目分析
系统会部分代替中介工作,通过房管局节点校验房屋信息,通过公安局节点验证个人信息,通过征信中心验证个人
信用。
当租房时,租户能够了解到房屋的一些信息,比如:是否是可租赁房屋,是否是房东直租,房屋是否存在抵押情况
等。
房东可以通过平台了解到租户的个人信息,是否有违法记录,个人征信信息是否良好等。
当出现合租时,房东和现有租户,都可以了解到新租户的个人信息,同时新租户也可以了解到对等的信息。
个人认证信息、房产信息、征信信息都会分布在不同的节点上,现阶段由各个部门单独管理,我们在需要认证时发
送认证请求即可。
租赁合同、租金、违约金等不可篡改数据会上链。各个节点均可记录这些信息。
系统组成(联盟链)
Orderer Service:2个节点, 共识策略使用kafka
Organizations :3个组织(公安局、房管局、征信中心),每个组织两个节点
channel:
1. 三个组织独立的channel
2. 三个组织的联合channel
利用华为云平台完成上述系统的创建。
个人认证
学习目标:
1. 独立完成个人信息认证(chaincode)编写
2. 独立完成后端个人信息认证功能
3. 独立完成前端个人信息认证功能
4. 独立完成个人信息上传(chaincode)编写
5. 独立完成chaincode更新
6. 独立完成后端信息上传功能
7. 独立完成前端信息上传功能
认证chaincode编写
个人认证信息会发送到相关的政府部门节点,通过查询区块链上的数据得到用户的认证信息结果。回复内容包括两
项认证结果:姓名与证件是否匹配的结果和是否有不良记录的结果(考虑到个人隐私,不会返回不良记录内容)。
为了能够测试通过,我们当前仅仅返回测试结果。
package main
import (
"github.com/hyperledger/fabric/core/chaincode/shim"
"github.com/hyperledger/fabric/protos/peer"
"fmt"
"strings"
)
// 个人认证
// 发送姓名和身份证信息,回复:是否通过认证,是否有不良个人记录
type Auth struct {
}
func (this *Auth) Init(stub shim.ChaincodeStubInterface) peer.Response {
return shim.Success(nil)
}
func (this *Auth) Invoke(stub shim.ChaincodeStubInterface) peer.Response {
function, args := stub.GetFunctionAndParameters()
if function == "check" {
return this.check(stub, args)
}
return shim.Error("Invalid Smart Contract function name.")
}
func (this *Auth) check(stub shim.ChaincodeStubInterface, args []string) peer.Response {
name := args[0]
id := args[1]
data, err := stub.GetState(id) // 通过身份证号查询出姓名和是否有不良记录信息。数据结构
name:true(false)
if err != nil {
return shim.Error(fmt.Sprintf("Error getting data %s", err.Error()))
}
var result string = ""
if data != nil {
var str string = string(data[:]) // []byte结果转换成字符串
split := strings.Split(str, ":") // 依据":"对结果进行划分
if split[0] == id {
result = "true"
} else {
result = "false"
}
result = result + ":" + split[1]
return shim.Success([]byte(result))
}
// TODO 由于没有记录数据,此处我们使用模拟数据
后端个人信息认证
测试
1、证书下载及解压
2、配置文件下载及解压
3、Host文件修改
4、app.conf配置文件修改(参照test项目,完成key和value的同时修改)
5、通过浏览器模拟get请求
return shim.Success([]byte("true:true"))
//return shim.Success([]byte("false:false"))
}
func (this *AuthController) Check() {
name := this.GetString("name")
id := this.GetString("id")
if name == "" || id == "" {
handleResponse(this.Ctx.ResponseWriter, 400, "Request parameter name(or id) can't be
empty")
return
}
beego.Info(name + "::" + id)
args := [][]byte{[]byte(name), []byte(id)}
var (
channelId = beego.AppConfig.String("channel_id_gaj")
chainCodeName = beego.AppConfig.String("chaincode_id_auth")
)
ccs, err := models.Initialize(channelId, chainCodeName, userId)
if err != nil {
handleResponse1(this.Ctx.ResponseWriter, 500, err.Error())
return
}
defer ccs.Close()
response, err := ccs.ChaincodeQuery("check", args)
if err != nil {
handleResponse(this.Ctx.ResponseWriter, 500, err.Error())
return
}
handleResponse(this.Ctx.ResponseWriter, 200, response)
}
前端个人信息认证
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>用户认证</title>
<script src="vue.js"></script>
<script src="vue-resource.js"></script>
</head>
<body>
<div id="app">
<table>
<tr>
<td>姓名:</td>
<td><input type="text" v-model="name"></td>
</tr>
<tr>
<td>身份证号:</td>
<td><input type="text" v-model="id"><br></td>
</tr>
</table>
<button v-on:click="check">认证</button>
</div>
</body>
<script>
var vm = new Vue({
el: '#app',
data:{
name:"",
id:""
},
methods:{
check:function () {