昨天讨论的借贷模式是基于真实世界身份的----更准确的说,是链下身份。因为链上也是另一种数字化的真实。
这个版本基本是按照现有的业务逻辑优化而来的,尽量复用已有的模块(包括流程,风控手段,以太坊合约)。这样设计出来的东西,难免很多地方会受到现有条件的局限(在业务模式上,更在技术层面),不能算一个一步到位的解决方案。
那么, 我们来试试做一个不基于链下身份的借贷吧。这意味着,在借款的事情只会考察这个链上账号,而完全不管他背后是一个人,一条狗,还是一台机器。
在此以前,我们先抛出来关于账户价值的三个结论:
1.账号的单边性----密钥持有者可以证明账户是自己的,也可以假装不是(遗弃账号);
2.总体余额非负----相互绑定的账户总价值不能为负:其中可以存在负余额的账户,但总和必须为正。而不与其他账户绑定的单个账户,是不能出现负余额的。否则账号会被遗弃;
3.账户的非经济价值----之所以存在无抵押的纯粹信用贷,依靠的是大量“非经济”账户。一定程度上说,这些无变现价值的账户,成为了一种特殊的抵押物,
基于这三点,可以来设计不同的模式
第一种模式:账户内抵押模式
这是一种纯链上的,单账户借款,通过保证这个单账户价值为正,保证账户不被遗弃。
这句话有点绕,一点一点说。
首先,这是纯粹基于链上的,彻底跟链下的身份、账号说拜拜,更不要提法币,面签。这意味着这种信贷业务不止可以对公司,个人,也能对任何的智能设备,甚至抽象的合约-----比如一辆每月有租金收入的共享单车借款支付修理费,一片太阳能电池板,或者一个域名借款给自己续费。
其次,这个借款针对的是“账户”本身----而不是他背后的“身份”。这样,就避免了“单边性”的问题,因为出借人针对的就是账号本身,所以也就不用考虑“如果账号持有人不要这个账号怎么办”。这跟ABS的思路有点类似: 信用是针对一个特定SPV的,理想情况下,你完全不用再考虑背后的主体。
因为账号背后没有身份,也就没有绑定到其他账号。这意味着需要受到“余额非负”的限制:这个账户里面既然要存在负债,就必须同时存在更多的资产(任何有价值的东西),以保证整体余额是正的。
具体的操作上,最简单的版本是用配资智能合约来实现:
合约基本结构如下(伪代码,不要纠结语法):
Contract leveragedInv{ //这个类可以认为是一个优先劣后级的SPV。
address seniorHolder; //优先级账号----也就是出借方
address juniorHolder; //劣后级账号----也就是借款人
uint totalAmt; //总投资额;
uint juniorAmt; //劣后级投资者
date origDate;//投资生效日期;
uint intRate; //利率
string status;// SPV当前状态。
function investmentInstruction;//这个是具体的投资指令,双方认可以后自动执行----
//劣后级不能修改-----比如直接转账到某个地址参与ICO。
function extiInstruction;//这个是双方约定好的退出策略;
modifer onlyJunior{//某些操作是只允许劣后级做的;
require(msg.sender==juniorHolder);
_ ;
}
modifer checkStatus(string _status){ //只有某种状态下才能执行;
require(status==_status);
_;
}
function leveragedInv(function _investInstruction, function _exitInstruction){
//建立SPV
juniorHolder=msg.sender;//由劣后级发起SPV;
juniorAmt=msg.value;// 劣后级需要在合约成立的时候先把劣后级份额放入spv;
investInstruction=_investInstruction; //投资指令和退出指令是一开始就约定好的。
exitInstruction=_exitInstruction; //
status="waiting for senior";
}
function cancelSPV() onlyJunior checkStatus("waiting for senior") {//在合约成立
//以前,junior可以取消,并且拿走投资额;
juniorHolder.transfer(juniorAmt); //转出金额
juniorAmt=0; //修改状态
status="canceled";
}
function seniorCommit() checkStatus("waiting for senior") { //优先级投资者对这个
//合约的投资标的;各方出资额;利率等方面都满意,就可以出资参与;
require(msg.value==totalAmt-JuniorAmt);//优先级出资额应等于总投资额减劣后级出资额;
seniorHolder=msg.sender;
call investInstruction()//执行事先约定好的投资指令;
origDate=today;//项目的成立日期,从这一天开始计息
status="deal closed";
}
function liquidate() onlyJunior checkStatus("deal closed"){//退出投资,偿还本息;
call exitInstruction()//执行事先约定好的退出指令;
uint period=today - origDate;//计息天数
uint seniorAmt=totalAmt-juniorAmt;
uint intDue=seniorAmt * intRate / 365; //应计利息
uint totalDue=seniorAmt+intDue;//本息合计
transferToSenior=min(totalDue, balance);//先满足优先级本息
seniorHolder.transfer(transferToSenior);
juniorHOlder.transfer(balance);//剩下给劣后
status="liquidated";
}
}
假设某账号Alice希望做一笔投资,比如参与ICO,用100个ETH购买20w个新发行的NBC。他希望为了这一笔投资借款80个ETH,也就是说,他自己出资20ETH,剩下的80个ETH外借。这时候他可以用下面的方式操作:
- 成立这么一个合约,填入投资指令(参加NBC的ICO),利率。存入劣后级的投资额;
- 去一个链上公告板合约里把他这个合约的地址提出来;所有关注了这个公告板的人,就能看到这个合约;
- 投资者Bob认为NBC项目风险不大,并且配资利率也不错,愿意投资。Bob往合约账户转入优先级出资金额,调用seniorCommit指令。
- 合约自动验证Bob的请求,确认无误后,把Bob的信息也计入合约,并自动执行投资指令参加ICO。至此,借款成立。
- 过了3个月,NBC上涨了5倍,Alice认为是时候退出了。他执行liquidate()指令,合约自动卖掉NBC,先支付给Alice本金和利息,剩下的部分转给Bob;
这种模式的特点是,Bob这个账号里面里面既有负债(A的配资),也同时有资产(购买的NBC),并且资产总是大于负债的。这保证了借款的安全。
使用类似的合约应该可以为去中心化的交易所提供杠杆服务(中心化交易所就别提了)。也可以可以为非交易所的交易提供配资,比如ICO,ENS等。
这个借贷因为只是关注帐号本身,所以后面是机器人也无所谓。比如某个量化交易的算法,在需要还用杠杆的时候,也可以按照上面的流程来申请配资。
局限性:以上的方法虽然已经抛开了对线下的依赖,但其实还是某种变相的抵押借款,不算真正的信贷。
那么要如何实现线上的纯信用贷呢?
待续...
下一部分会讨论在链上实现信用贷,不基于链下身份的信用贷
网友评论