查看原文
其他

供应链金融平台的架构演进【文末有惊喜,不看后悔一年】

周迁 中生代架构 2019-05-15

架构师成长的好伙伴连接技术 接力价值


作者:周迁

铸融链信息科技有限公司,首席架构师,前迅雷架构师,前糗事百科平台组负责人,前葡萄藤网络科技技术合伙人,做过电信、游戏、互联网等不同业务,目前对探索区块链在金融平台的落地充满兴趣和热情


 第51篇架构好文:6262字 | 12分钟阅读


大家好。首先简单自我介绍一下,我叫周迁,现在在铸融链负责后端架构,然后主要是在直接负责区块链团队。在这之前我在迅雷,糗事百科做过几年的技术组件。更早之前我是做了几年的游戏

简单介绍一下我们的业务,因为有一句话说是“没有最好的架构,只有最合适的架构”。不管是在做技术选型,还是在做深入实践的时候,技术基本上都是围绕着业务在转

我们的平台叫铸融链,就是我们是在基于区块链做供应链金融,就是很多中小企业融资难、融资慢、利率特别高的问题,可能大家都听说过,或者有了解过。我们就是要解决整个供应链资金的周转问题。

我们的产品叫铸融信,就是在铸融链这个平台上的一种数字资产,它具有可以拆分、可以流转、可以融资的特点。可以理解为一种token,但是它是作为一种价值计算的单位,而不是一种代币

我简单举个例子,给大家介绍一下我们的业务模式。比如一个核心企业,跟一个一级供应商之间发生了一笔贸易,但是他并不是货到了就会付款。这中间是有账期。

比如说你是一个做手机屏幕的厂商,然后你给富士康发了一批货,然后富士康可能要等到把iPhone生产出来,然后交付给苹果,苹果把iPhone卖了,把钱打到富士康账户之后。富士康才会把钱给这个厂商。

当然这个具体的账期肯定不是这样的,我只是做了一个假设,方便大家来理解一下。在这个账期内,这个供应商就会非常难受,因为他的货已经交了,然后钱没拿到。同时他要去继续扩大生产,维持生产运作。

所以之前的解决方案就是他拿到这个应收账款去找银行融资,那就会有很多的问题,比如说银行审查会比较漫长,而且他会看供应商的资质,他也担心如果你破产了怎么办?然后如果你的资质不是特别好,利率就会特别高。

我们提供的解决方案是,核心企业在跟供应商发生了一笔交易之后,他就会来我们的平台开一个对应金额的铸融信,就是直接用铸融信支付给这个供应商,然后供应商可以拿着铸融信直接找我们平台入驻的资金方进行融资,也可以用铸融信直接去支付给他的下级供应商。

支付的过程中这个铸融信是可以拆分的,比如说你有100万的铸融信,你只需要支付80万给你下级供应商,那你可以把它拆成两笔,一笔80万,一笔20万,然后把那笔80万的支付掉。

在账期结束的时候,就是账期到期的时候,核心企业就会把钱还上,然后我们平台会出一个清分的列表,资金方那边就会去做清分。

对于整条供应链而言,它的风险更少了,因为资金方需要承担的风险是核心企业的信用的风险。这样效率也得到了提高,因为不管这个token怎么拆分的,它的根始终是核心企业跟供应商之间的那笔交易,然后流转的都是核心企业的信用。

基本的流程就是供应商、核心企业、资金方先来平台入驻,入住的时候,我们会有一个平台的审核,在核心企业和供应商之间发生了一笔交易后,核心企业就可以基于这笔真实的交易去开立铸融信。

开立的过程中我们是有审核的,就是你需要上传对应的发票,还有票据电子复印件之类的,就是要确保你这笔交易是真实的。

然后供应商有了这个铸融信之后,他就可以去融资,也可以直接去支付给他的下属供应商。帐期到了之后,平台会出清分列表。

这个是我们第二版的架构。因为我们第一版其实是没有区块链的,只有一个单纯的业务系统和一个运营系统。我觉得我们第一版架构没有什么太多可以分享,所以就直接跳过了。

第二版架构设计主要是基于的考虑是我们要屏蔽对合作方暴露那些区块链的细节。我们定了一个协议叫OpenAPI,然后我们自己实现这个SDK,直接把这个SDK交给合作方去用。

这个SDK主要就是负责数据上链的事情。另外我们要确保我们的合作方的数据都是私密的,就是你写的数据不会被原封不动地同步到所有的节点。

所以我们中间做middeware层,我们会把上链前数据进行加密,密钥是存在你本地的DB里面,然后把加密后的数据在上链,每个节点通过区块链同步到的数据都是加密后的密文。

如果你需要得到明文的话,那你就需要找加密方授权。加密方如果授权通过之后,通过中间Agent层会自动的把密钥同步给你。密钥的同步是找Agent那一层的HPS,并不是找区块链,你找到区块链的话,相当于你就把密钥暴露了。

然后最底下就是区块链,其实区块链上面还有一层没有画出来,是有一层网关层,就是真正来做数据上链的事情。

这网关层当时设计的时候叫R2,他是用来调用合约的,然后做数据上链的事情。然后我们还做了一些异常收集。

比如说这个区块链节点的块高有一定的差距,或者说有节点停止了挖矿,或者整个区块链网络发生了分差,这些都会自动告知。

后来我们在迭代的过程中发现这个架构会有很多的问题。

就是首先我们需要去对接各种合作方的系统,比如说我们要对接核心企业的业务系统,需要去对接资金方的业务系统,然后我们还需要去调用很多的第三方的合作平台,比如说电子签章、短信、文件存储等等。

另外我们一开始的时候,开发人员很少,只有两三个开发,但人慢慢变多之后,就会有很多协作上的麻烦。而且很多本来是逻辑上是独立的东西都偶合在一起。

另外一个问题是以太坊智能合约的问题,就是它的数据跟它的合约地址是绑定在一起的。另外就是我们的之前有好几个合作方,然后每一方的权限其实没有做的很完善。

当时的做法就是把我们的节点可以去添加或者删除一些节点,但是每一个其他的节点,它的权限没有做的特别细,我们只是做了一些约束,就是有些数据能写出,那些数据不该你写。

另外就是以太坊本身有很多的问题,因为以太坊本身是一个针对于公链场景的设计,一个典型的例子,就是它在解决评级问题的时候,是给每个运算带上来运算费。

我稍微解释一下这个问题,如果你的合约里面有一个死循环,你的每一个节点在跑这个合约的时候可能都会被夯住,因为都在跑死循环。但是以太坊它是一个公链的设计,它的设计的之初就需要考虑一点,就是你没法去控制所有的节点,因为节点都是用户可以随意加入随意退出的。你不能强制他去干一些什么事情。

那如果你所有的节点都夯住了,对整条链来说,这是一个致命性的问题。而且也有开发已经指出了,就是你没法证明你的程序里面是否存在这种问题。

所以以太坊的解决方案就是他自己开发了一个虚拟机叫EVM,然后他那个虚拟机里面执行的每一个指令都是确定的。然后每一个指令,比如说你是在做一些运算或做一些存储,都是有运算费的。

就相当于汽车的运行需要消耗汽油,如果你的油箱里面的汽油被消耗完了,那汽车自然就没法开了,所以它是通过这种方式来解决那个评级问题的。那对我们来讲,如果你写一个很复杂的合约,你的整个运算可能会超过上限。

还有一些evm的栈深只有1024,然后他的那个账号需要绑一个nonce等各种各样的问题。

然后针对这些问题我们做了一些调整,就是首先我们把一个单体的应用拆成了一些独立的服务。

其实那些灰色的其实是我们规划的,但是目前还没有实现的,还没去做。

主要的逻辑都在那个交易核心里面,就是我们把那个铸融信的开立、转让、融资、核销的主要过程的逻辑都放在交易核心里面。

然后资产平台就是主要存放一些资产的数据,合同平台,就是我们会去对接一些电子签单的服务,也把它独立了出来,就是因为我们会需要去考虑要不要切换合作方,或者说引入多家合作方。

用户中心就是供应商,核心企业还有资金方,他们的一些资质等各方面的数据放在里面,风控系统,风控目前我们做的还是比较简单,就是我们目前做的就限制一些融资额度,或者说临时冻结铸融信,就是,如果供应商或者核心企业出了一些什么问题,可以冻结,他不让你再流转或者去做融资。

另外就是之前我们提到,合约地址跟数据反映的问题,就是我们需要去解决这个问题,怎么保证你的合约是可以无痛的升值?

这个问题其实以太网社区也总结出来一些最佳实践,就是首先你需要把合约的逻辑和数据分开,这个其实跟面向对象的做法是反过来的,就是你需要把合约把逻辑跟数据放在不同的合约里。

因为你的数据结构通常是稳定的,但你的业务逻辑变更通常对应的是去调整那些算法。所以如果你的逻辑合约变了,但是你引用的数据合约的地址没变,那你就不用做数据迁移这个事情。

因为数据迁移毕竟还是很痛苦的一件事情,而且还可能会出错。另外就是即使你把逻辑和数据分开了,那你的逻辑合约不可避免,是总是会被修改的。

如果你每次修改了逻辑合约,你的上层变通关系层需要去做合约调用的时候,你是需要知道合约地址的,但是你的合约历史会经常变化,那你的每更新一次上一层也要跟着去更新一次,这个也是很麻烦的,而且有可能是两个不同的团队不想做这种饱和的事情。

其实社区也有了一些总结,但是在很早之前,每一家的做法不太一样,基本上的思路就是引入代理合约。

代理合约你可以理解成依赖注入,就是你的合约地址虽然会变,但是我引入了一个代理合约,就是这个合约其实相当于暴露了一个接口,它会指向具体的逻辑合约。

虽然你逻辑合约变了,但是对应用层暴露的是那个代理合约,那个合约就相当于如果你API是稳定的,那应用层就不需要关心你后面做了什么变化。当然如果如果整个API都变掉了,那肯定也是要跟着改的。

还有就是区块链网络本身我们也做了一些调整。我们之前的做法就是就是跟公链一样的设计,用POW共识。

POW在联盟链产品上其实有个很大的问题,就是首先联盟链的产品上,它的节点数是有限的,如果你想做的话,也可以达到超过50%以上算力的。

另外如果他所有的节点都是可信的话,那你去算哈希其实也不是特别有必要。而且因为挖矿这个事情导致你的出块时间也是不可控的。

POA我不知道大家有没有听说过,就是以太网的测试网络就是POA共识。

在POW场景下是大家所有的网络里的节点都去算哈斯,然后选出一个节点,它来做出块,他来打包,但POA他的想法是我不需要去做这个运算的事情,我就直接指定几个可信的账号,让他的出块比较好。

如果你选择这些节点,这些担保觉得里面有一个人做了怎么办?那其他的节点会做的任何事情在区块链上是透明的,那其他节点方能做到的就是,他可以把你从这个担保节点里面剔掉,就相当于我不带你玩了。

这样的好处就是你的出块,时间是可控的,比如说你可以自己去设置块速设成,五秒出一个块或者一秒出一个快,这样整个区块链这一层的TPS会更高一些。另外就是你也不需要所有的节点去算哈希。

然后我们重新设置了一个监控的组件,就是我们会从eth-netstats WebSocket的接口里面去读取所要注册节点的相关信息,然后去自动的发现区块链网络的异常并告知。另外就是如果你需要做一些查询的事情。

比如说你有一个根token,然后被拆分,被流转了很多次,你需要根据这个根token去查询整个拆分交易的整个树的话,在以太坊实际上是非常麻烦的。因为你的数据分散在不不同的账户上,而且以太坊是没法支持递归查询的。

所以我们做法就是我们开发了smeargle,监听以太坊制定合约事件,将事件转化为Node & Link 写入图数据库中,用于后续相关性查询,就是你做一些复杂的查询,你可以在链外来做,这样对查询和存储都是有很大的优化。

之前其实我们的第一个版本的实际上是供应商要做交易的话,是要通过核心企业的系统。就是我们当时的做法是我们只是一个支付宝,比如说你要发起笔交易,你可能要通过淘宝或者天猫的入口。

后来我们是自己开发的门户,就是包括资金单,包括核心企业,包括供应商,所以它可以通过我们的平台来发起交易。那他入住的时候就会生成对应的以太坊账号。

这个Nonce不是算哈希那个Nonce,是以太坊的账号发起交易的时候都要带上一个Nonce,其实就是一个交易编号。

但是他对这个交易编号有一些限制,它需要这个交易编号是连续的,而且是他的设计就是从零开始,每次加一,就是这样严格加一的递增上去的。而且中间是不能有空洞的。如果不自己去维护这个Nonce,这里面这里面有很多的坑。

还有就是区块链本身是没有事务这个概念的,就是如果我发起了多笔交易,不会是这多笔交易要么同时成功,要么同时失败。但是你的那个网络异常,或者说节点挂的这些位置的问题,这是不可避免的。

所以我们花了很多的时间在做这个容错的事情上面,主要的想法就是我们需要保证交易是幂等,然后出错或者节点退出会以指数避退的方式retry,然后保证数据最终一致就OK了。

我把我们现在在做的事情简单的列了一下,因为我们还是一个创业公司,成立还不久,所以我们的业务系统还是在摸索和完善的过程中。

另外就是我们还有很多的业务系统需要对接,比如说合作方的各种业务系统,包括未来可能跟资金方的对接。

另外我们在做的一个很重大的事情,就是我们要把以太坊换成hyperledger fabic,为什么要这么做呢?就是本质上我们在做的业务就是供应链金融这个事情,其实跟许可链是更贴合的。

因为大家都知道,很多的资产其实都是需要登记的,比如说你的房产、债券这些,它并不是像比特币那样,或者说你捡到了十块钱,那十块钱就是你的了,那这种设计肯定是不行的。

因为整个公链的设计图其实都是基于一个命名资产的方式,然后他也没有准入机制,然后一些没有必要的设计点,会让整个的TPS变得更长,让他扩展扩展性变得更差。

那为什么不一开始就用hyperledger fabic呢?其实当时我们在做第二个版本迭代的时候,就是要做区块链的时候,其实区块链团队还只有我一个人,然后我们当时的想法是我们要快速的把东西做完,然后让整个系统给用起来。

而且hyperledger fabic,他的那个网络拓朴,节点的准入,证书的生成,合约的升级,各方面都是很麻烦的,因为它不像公链那样,当到了一个节点上来,然后直接添加进去就OK了。

它需要准备一堆的证书,一堆的配置,然后对我们来说,可能很多的精力就需要花在证书生成、配置编排各种各样的事情上面。

所以我们当时的想法是我们先快速把它实现了,而且当时我们也不太确定整个网络拓扑会是怎么样。

因为在一开始做的时候,整个业务场景也不是特别清晰,所以有点类似于先弄一个原型出来,然后让他可用,等他稳定了,然后我们再去做重构,大概是这么一个思路。这里有一个就是地址

https://github.com/eddyzhou/hyperledger-fabric-swarm

是一个最小可用的测试网。

然后这个是我们未来计划要做的事情。

首先是围绕价值记录和传递,设计多方参与的链上治理模型。其实这个事情我觉得可能还需要一段时间的探索,因为你只有累积了一定的经验,然后对整个场景有更大的把控,然后你的话语权更大的时候,可能设计出来的方案才更可行。

另外就是从双写到Dapp,这个事情我个人觉得是必要的,但是这取决于区块链的普及程度。因为目前阶段来讲,可能供应商更关心的是他能不能在我们平台快速高效,然后低成本的融资。

最后BAAS这个我觉得肯定是有需求的,因为本质上你要搭网络的话,你肯定要去做这些事情。但我们肯定是先贴着业务来做,然后不会像很多云厂商那样说,我要做一个服务,然后说可以单独给第三方来用,肯定不会做的这么完善,而且我们会贴着社区来做,因为对于一个创业公司来讲,借助社区的力量也是很很有必要的。

大概就这些,谢谢吧


1024

中生代社区携手送礼神器、程序猿茶

为大家送上1024大礼包

扫描下方二维码,参与抽奖

下位“锦鲤”就是你

1024

GitChat出品,必定让你满载而归

机会是留给扫了码的人

不扫你永远不会中奖

想要加入中生代架构群的小伙伴,请添加群助手小姜的微信

申请备注(姓名+公司+技术方向)才能通过哦!


突破是中生代社区新上架的图书,签名版仅在送礼神器销售,余50本,先到先得



推荐阅读



* 敏捷协作如何应对研发交付过程中的墙

* 如何改变Redis用不好的误区

* 无服务计算架构

* 了解“分布式事务一致性”看这篇就够了

* 阿里资深技术专家:云时代软件研发的终局猜想


    您可能也对以下帖子感兴趣

    文章有问题?点此查看未经处理的缓存