基于智能合约的银行借贷方案设计与实现

Posted 宋罗世家技术屋

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了基于智能合约的银行借贷方案设计与实现相关的知识,希望对你有一定的参考价值。

摘要 

针对银行借贷方式中个人、小微企业借款困难的现象,以及银行承担较高的资金风险,工作人员在借贷审核方面受主观因素影响较大的问题,基于区块链技术,提出一个基于智能合约的银行借贷方案。首先设计EBBI借贷投资模型,以及基于深度学习的智能风控评估算法;然后设计新增标的、投资、还款、代偿等智能合约算法,并加以验证;最后以小微企业贷款进行了案例分析。采用拍拍贷公开的数据集进行测试评估,算法准确率达到94.33%;在交易达到500笔时,系统平均查询处理时间为0.23s。实验结果表明,该智能风控评估模型具有较高可靠性,智能合约算法的性能满足系统运行高效性的要求,在不影响银行原有信贷业务的情况下可以帮助借款方快速借款。

关键词

以太坊; 区块链; 智能合约; 银行借贷; 智能风控

0 引言

市场上的理财借贷平台能使一些个人投资者、小微企业等的资金流动更加灵活,在一定程度上满足其快速借款的需求,从而推动市场经济发展。然而,由于缺乏监管,相关平台涌现大量问题,如借款人恶意逃债、平台资金去向不明等[1]。据网贷天眼数据显示,仅2019年出现问题的借贷平台就新增了763家。现有的银行贷款多由银行独自放贷并承担风险,借款用户和储蓄投资用户没有直接的资金交易,用户将钱存进银行后,由银行决定存款的使用方式,银行放贷的资金来自于储蓄用户的存款,储户的收益普遍较低。银行贷款在每个时期有一定的倾向性,目前更倾向于向政府扶持发展的行业发放贷款,致使部分个人、小微企业借款困难[2],同样导致了市场资金流动缓慢。

区块链技术凭借其去中心化、可追溯、不可篡改等特点[3],不仅在房屋租

区块链项目实战 - 使用以太坊/智能合约solidity,全栈开发区块链借贷记账小应用,含完整源码

本文使用区块链平台以太坊+智能合约实现一个区块链记账的功能,具体为:

  • 借款人和贷款人以及数额被记录在区块链中。使用区块链地址来表示借款人或者贷款人。
  • 若一个借款人多次向一个贷款人借钱,更新所有的数额之和并记录在区块链中。
  • 智能合约保存所有用户的借贷信息,包括他们的区块链地址和数额
  • 只有借款人才能向智能合约中添加借款记录。
  • 若一个人既是借款人,也是贷款人,那么最终下图中的“Total Owed”只显示他总的欠款。因此,如果他借出去的钱比借来的钱多,那么这个字段为0,表示他不欠任何人钱。
  • 一个UI界面方便用户使用该应用。

除了智能合约部分的代码逻辑,还需要实现后台的UI和交互。这里使用JavaScript和html来实现。执行使用ganache在本地节点中来创建一个以太坊的测试环境。先看最终的html页面:

下面是执行环境安装和完整的源码的地址。

执行环境搭建

  • 下载安装node.js (使用到了web3.js)
  • 安装ganache-cli (用来模拟以太坊的本地环境)
  • 通过下面的链接进入remix 的IDE: https://remix.ethereum.org/
  • 编写智能合约,具体的智能合约见文末;
  • 在本地电脑中启动ganache-cli。在cmd中输入命令“ganache-cli”,回车即可。
  • 为了部署写好的智能合约,选择下图编号为1的选项,选择web3 Provider;点击Deploy按钮就可以将编译好的智能合约部署到本地的ganache-cli节点了。
  • 点击上图编号3的图标复制智能合约的地址,(粘贴)作为代码script.js文件的contractAddress变量的值。
  • 使用浏览器打开index.html文件,即可看到第一张图效果。

需要注意的内容
这里的代码只是一个demo,目的是演示一个全栈的以太坊智能合约应用,因此没有优化性能。这里的性能主要指的是js代码跟本地节点交互的成本。其次,为了减少智能合约的存储和计算开销,这里把大部分逻辑和存储放到了本地的js代码中。在目前的以太坊的mainnet中,交易费是很贵的。相比之下,js代码和本地节点的交互反而是很便宜的。特别的,调用“只读”的智能合约函数是不需要交易费的,因为这个过程只是js代码和本地节点的交互,并没有往区块链中写入或者修改区块链的数据。因此,script.js中的函数“downloadAll()”是不需要手续费的。

完整的源码下载:
https://github.com/liangyihuai/LearnBlockchainByCoding

完整的智能合约代码:

pragma solidity 0.6.6;

contract Splitwise
    struct CreditAcc
        address creditor; //the person who lends money
        uint32 amount; //
    
    
    //debtor address => creditor infor
    mapping (address => CreditAcc[]) creditAccMap;
    address[] users; //store all registered user's addresses.
    
    function getUsers() public view returns(address[] memory)
        return users;
    
    
    //The debtor borrows money from the creditor
    function lookup(address debtor, address creditor) public view returns (uint32 ret)
        if(existCreditor(debtor, creditor))
            CreditAcc[] memory ca = creditAccMap[debtor];
            for(uint i = 0; i < ca.length; i++)
                if(ca[i].creditor == creditor)
                    return ca[i].amount;
                
            
        
        
        return 0;
    
    
    function add_IOU(address creditor, uint32 amount)public 
        require(amount > 0);
        require(msg.sender != creditor);
        
        if(!existAnyCreditor(msg.sender))
            CreditAcc[] storage creditAccArray;
            creditAccArray.push(CreditAcc(creditor, amount));
            creditAccMap[msg.sender] = creditAccArray;
        else if(!existCreditor(msg.sender, creditor))
            creditAccMap[msg.sender].push(CreditAcc(creditor, amount));
        else 
            CreditAcc[] storage caArr = creditAccMap[msg.sender];
            for(uint i = 0; i < caArr.length; i++)
                if(caArr[i].creditor == creditor)
                    caArr[i].amount += amount;
            
        
        
        if(!existUser(creditor)) users.push(creditor);
        if(!existUser(msg.sender)) users.push(msg.sender);
    
    
    //----------------------------------------------------------
    //helper functions
    //----------------------------------------------------------
    function existAnyCreditor(address debtor) private view returns(bool)
        if(creditAccMap[debtor].length == 0) return false;
        return true;
    
    
    function existCreditor(address debtor, address creditor) private view returns(bool)
        if(!existAnyCreditor(debtor)) return false;
        CreditAcc[] memory caArr = creditAccMap[debtor];
        for(uint i = 0; i < caArr.length; i++)
            if(caArr[i].creditor == creditor)
                return true;
        
        return false;
    
    
    function existUser(address u)private view returns(bool)
        for(uint i = 0; i < users.length; i++)
            if(users[i] == u) return true;
                
        return false;
    

以上是关于基于智能合约的银行借贷方案设计与实现的主要内容,如果未能解决你的问题,请参考以下文章

区块链项目实战 - 使用以太坊/智能合约solidity,全栈开发区块链借贷记账小应用,含完整源码

数字人民币与智能合约

基于Solidity的XX项目智能合约架构设计

去中心化借贷,Compound应用架构

基于区块链的投票系统的设计与实现

数字资产抵押借贷系统开发,合约交易系统开发