美文网首页区块链eos区块链技术研究
(恒生)两步搞定Fabric,链码,跨链,白皮书

(恒生)两步搞定Fabric,链码,跨链,白皮书

作者: 大圣2017 | 来源:发表于2017-05-18 14:09 被阅读1333次

    2017-02-15 柳正龙 恒生电子 两步搞定Hyperledger区块链解决方案Fabric
    2017-04-13 柳正龙 恒生电子 链码开发精解来了,区块链世界还会远吗?
    2017-03-17 童世红 恒生电子 区块链下一风向标:跨链技术
    2016-12-15 童世红 恒生电子 恒生电子区块链技术白皮书官方剧透
    2017-05-18 平风 恒生电子 基于区块链探索新一代私募股权交易系统


    两步搞定Fabric

    区块链技术发展至今,形成了公有链和联盟链两种主流技术平台。

    **公有链 **面向大众,用户可以匿名参与,非常方便,账本数据也公开,加上强大的智能合约,因此公有链极大地促进了区块链概念和技术的普及,比如比特币、Ethereum平台等。

    **联盟链 **考虑到商业应用对安全、隐私、监管、审计、性能的需求,提高准入门槛,增加了安全、隐私、可监管审计等商业特性,是区块链技术在商业领域的应用探索。

    本文将通过系统介绍,帮你两步搞定符合Hyperledger协议规范的联盟链实现技术:Fabric。

    第一步:读懂系统设计

    Fabric系统主要由两个应用构成:Orderer和Peer,其中 Orderer 负责交易共识并生成区块,Peer节点负责模拟执行交易和记账。这种划分可以使整个平台拥有更好的弹性和扩展性。Peer和Orderer都是模块化设计,重要模块支持插拔,比如共识机制、合约执行环境、加密算法、证书服务模块等。模块化的设计让企业可以利用现有IT设施来替换部分Fabric模块。Fabric架构如下图:

    证书服务——共建信任

    上图中最左边是证书服务系统,主要提供会员注册和证书颁发功能,Fabric系统的参与方都必须经过授权,比如Orderer、Peer、Client等都需要拥有受信任的证书。证书一方面用于系统接入,另一方面用于交易签名。所以统一的证书服务非常重要。会员证书又分为注册证书和交易证书,注册证书与会员信息关联在一起,用于标识会员的身份,在必要的时候,还可以支持监管和审计;交易证书用于交易签名,之所以交易要用不同的证书,是为了避免会员的个人信息和交易信息被泄露,比如交易内容或者多笔交易之间的关联关系等,另外交易证书可以申请多份,甚至可以为每一笔交易申请一份交易证书。

    共识网络——独特何在?

    上图中最右侧为区块链共识网络,由Orderer集群组成,用于交易共识并生成区块。区块链是去中心化的,意味着需要多方一起参与交易排序,生成区块。Orderer目前支持SBFT和Kafka两种共识机制,其中SBFT是拜占庭容错算法PBFT的简化版,能够容忍部分节点故障,Kafka是一个中心化的排队服务,能提供更高的性能,两种共识算法分别适用于不同的场景,用户还可以定制自己的共识模块。和其他区块链系统不同的是,交易共识在Fabric中被独立成为单独的系统,这样一来,参与共识的节点数变少,共识速度得到提高,Fabric的共识网络支持多链,即多个区块链账本可以共用同一张共识网络,降低系统部署和运维成本。

    区块链节点——便捷调用

    区块链节点Peer主要功能是调用智能合约执行交易和记账。

    • 智能合约
      智能合约是运行于区块链上的应用程序,Fabric的智能合约称为链码,分为系统链码和用户链码,系统链码用来实现系统层面的功能,包括系统的配置,用户链码的部署、升级,用户交易的签名和验证策略等。用户链码实现用户的应用功能。
      链码被编译成一个独立的应用程序,运行于隔离的Docker容器中,在链码部署的时候会自动生成合约的Docker镜像。
      链码支持采用Go、Java、Nodejs编写,并提供相应的中间层供链码使用,链码可以使用GetState和PutState接口和Peer节点通信,存取K-V数据 。
    • 共享账本
      共享账本包括区块文件和K-V状态数据,区块文件存储在本地文件系统,由Peer节点负责写入,文件内容是排序后的区块数据,每个文件有大小限制,存储一定数量的区块,区块由交易共识系统产生,包含一条或多条交易。K-V状态数据提供给链码存取使用,采用LevelDB存储。

    第二步:熟悉交易流程

    • 客户端构造交易提案——客户端构造交易提案,发送给一个或多个Peer节点,交易提案中包含本次交易要调用的合约标识、合约方法和参数信息以及客户端签名等。
    • Peer节点模拟执行交易——Peer节点收到交易提案后,会模拟执行交易,然后将原始交易提案和执行结果打包到一起,进行签名并发回给客户端,其中在模拟执行交易期间产生的数据修改不会写到账本上。
    • 客户端打包——客户端收到各个Peer的应答后,打包到一起组成一个交易并签名,发送给Orderer。
    • 共识排序,生成新区块——Orderer对接收到的交易进行共识排序,然后按照区块生成策略,将一批交易打包到一起,生成新的区块,发送给Peer节点。
    • 交易校验——Peer节点收到区块后,会对区块中的每笔交易进行校验,检查交易依赖的输入输出是否符合当前区块链的状态,完成后将区块写入账本,并修改K-V状态数据。

    通过上面的介绍,读者能够了解到区块链平台的基本框架、关键组件以及交易流程,后续笔者将进一步介绍Fabric系统的使用,敬请关注。


    链码(chaincode)开发精解

    在上一篇《两步搞定Hyperledger主打区块链解决方案Fabric》中,我们对区块链平台的基本框架、关键组件以及交易流程有了较为详细的介绍。今天,笔者将进一步聊聊Fabric智能合约—链码(chaincode)的开发简介与个人经验分享。

    智能合约初印象

    随着区块链技术的应用和发展,区块链几大关键技术正在经历快速演进,如共识算法、智能合约、跨链事务、隐私保护等。而和用户最相关的是能为用户带来价值的、跑在区块链之上的智能合约。

    智能合约可以看做是一个跨学科的复合名词,合约取自法律上的合同概念,智能指的是能自动执行的计算机程序,合在一起的智能合约就是能像计算机程序一样自动执行的法律合同

    要实现智能合约,首先需要使用计算机语言编写合同中的条款,然后将编写的程序部署到区块链上去执行。从计算机用户的角度来看,智能合约可以限定为更好理解的智能合约代码。智能合约最早的形式是比特币中的扩展脚本,由于比特币设计之初并没有考虑智能合约,因此这种扩展脚本受到诸多限制,后来Ethereum平台设计了合约编程语言solidity,提供了执行合约的虚拟机,进一步提升了智能合约的表述能力。而fabric的智能合约,直接采用JAVA、GO这些传统编程语言编写,功能和权限更加强大。

    由于区块链智能合约在商业上应用面临法律效力问题,因此现有智能合约一般会在代码中存储一份相应的法律合同文本文件,以应对法律风险。到今天,除了法律合同,智能合约已经应用到了更多的场景中,比如数字化交易所、供应链、物流等。

    Fabric链码基础知识概要

    Fabric的智能合约称为链码(chaincode),分为系统链码和用户链码。

    • 系统链码用来实现系统层面的功能,包括系统的配置,用户链码的部署、升级,用户交易的签名和验证策略等。
    • 用户链码用于实现用户的应用功能。开发者编写链码应用程序并将其部署到网络上。终端用户通过与网络节点交互的客户端应用程序调用链码。

    链码被编译成一个独立的应用程序,运行于隔离的Docker容器中,在链码部署的时候会自动生成合约的Docker镜像。

    链码和数据隔离

    相较于以太坊,Fabric链码和底层账本是分开的,升级链码时并不需要迁移账本数据到新链码当中,真正实现了逻辑与数据的分离。

    链码支持采用Go、Java、Nodejs语言编写,对于大多数开发人员来说并不陌生,能快速上手。

    链码和Peer节点的交互

    Peer节点的主要功能是调用智能合约执行交易和记账。

    1. Fabric链码通过gprc与peer节点交互,当peer节点收到客户端请求的输入(propsal)后,会通过发送一个链码消息对象(带输入信息,调用者信息)给对应的链码。
    2. 链码调用ChaincodeBase里面的invoke方法,通过发送获取数据(getState)和写入数据(putState)消息,向peer节点获取账本状态信息和发送预提交状态。
    3. 链码发送最终输出结果给peer节点,节点对输入(propsal)和 输出(propsalreponse)进行背书签名,完成第一段签名提交。

    之后客户端收集所有peer节点的第一段提交信息,组装事务(transaction)并签名,发送事务到orderer节点排队,最终orderer产生区块,并发送到各个peer节点,把输入和输出落到账本上,完成第二段提交过程。

    本文只提供第一段交易peer与链码交易示意图,具体两段式提交,可以参考http://mt.sohu.com/20170206/n479988004.shtml 《Hyperledger Fabric 1.0架构概览》。

    链码开发基础

    链码开发的基础,一句话总结起来就是:一个基类,两个查询,一个写入

    • 一个基类:Java中ChaincodeBase是自定义链码的合约基类,里面的run(ChaincodeStub stub, String function, String[] args)方法是peer调用链码的入口函数,其中必须自定义一个init方法,用于合约初始化及升级初始化动作。
      GO由于其动态接口的特性,不需要特别声明实现合约接口。但是必须实现两个接口方法,Init(stub shim.ChaincodeStubInterface) 和 Invoke(stub shim.ChaincodeStubInterface)。init用于合约初始化及升级初始化动作, Invoke是peer调用链码的入口函数。
      ChaincodeStub里面包含丰富的账本操作,常用的有getCallerCertificate(), getState(k), putState(k,v), invokeChaincode(…), rangeQueryState(k1,k2), getTxId()等。
      因为fabric默认的状态数据库是个k-v库,常用到的方法就以下几个。
    • 两个查询:是指getState(k)和rangeQueryState(k1,k2)两个查询函数。
      • getState(k) 获取单独的key对应的value值。
      • rangeQueryState(k1,k2) 获取k1开始,k2结束的所有k-v对象, 返回的是个Map<String,String>对象, 其中k1,k2按字典序排序。
    • 一个写入:putState(k,v), 写入数据,此处要注意下,putState数据并不会马上落到账本上, 要等到第二段交易提交共识达成后,数据才会落地。

    链码开发经验分享

    1.以Json方式存储业务实体并在key上建立索引

    因为只有一个key-val状态数据库,value为Json的数据可以快速解析,key上加一些字段简单索引字段的值, 如Pk_TxId交易id_某字段值, 来实现范围查询。

    fabric的k-v库用的leveldb,插入的key值用的字典序,所以索引字段值必须固定长度,否则调用stub. rangeQueryState(k1,k2)进行范围查询, 会取出一堆不正确数据。如: stub. rangeQueryState(‘id12’, ’id1234’), 会取到id121111111的数据。

    2.写入的数据不能立即获取到

    通过putState写入的数据并不会立即落到账本上, 要等到第二段交易所有peer节点共识达成后,数据才会落地。因此不可以立即获取之前写入的值,比如批量插入数据,利用putState写入数据,再通过getState函数来判断主键是否重复。

    3.链码里面的方法需要加锁吗?

    不需要。peer节点已经实现了消息队列,发给链码的链码消息都是顺序执行的,不是并行执行的。

    链码展示—简单资产转让

    下面主要展现Java版源码,供参考:

    package com.hundsun.blockchain.cc;
    
    import org.apache.commons.logging.Log;
    import org.apache.commons.logging.LogFactory;
    import org.hyperledger.java.shim.ChaincodeBase;
    import org.hyperledger.java.shim.ChaincodeStub;
    
    /**
     * 自定义链码继承ChaincodeBase, 并重写run方法
     */
    public class SimpleChaincode extends ChaincodeBase{
        private static Log log = LogFactory.getLog(SimpleChaincode.class);
    
        /**
         * 链码调用的总入口
         * @param stub 链码桩
         * @param function 客户端调用链码的方法名
         * @param args 客户端调用链码的参数
         * @return
         */
        @Override
        public String run(ChaincodeStub stub, String function, String[] args) {
            switch (function) {
                case "init"://初始化资产
                    init(stub, function, args);
                    break;
                case "transfer"://转移资产
                    return transfer(stub, args);
                case "query"://查询资产
                    return queryAsset(stub, args);
            }
            return null;
        }
    
        /**
         * 资产转让, 需要输入的参数例子 a b 10, 表示a给b 10
         * peer chaincode invoke -C testchainid -l java -n testchainid -c '{"Args": ["transfer", "a", "b", "10"]}'
         */
        private String  transfer(ChaincodeStub stub, String[] args) {
            if(args.length!=3){
                System.out.println("Incorrect number of arguments:"+args.length);
                return "{\"Error\":\"Incorrect number of arguments. Expecting 3: from, to, amount\"}";
            }
            String fromName =args[0];
            String toName =args[1];
            String am =args[2];
            String toAm=stub.getState(toName);
            String fromAm=stub.getState(fromName);
    
            int valFrom = Integer.parseInt(fromAm) - Integer.parseInt(am);
            int valTo = Integer.parseInt(toAm) + Integer.parseInt(am);
            stub.putState(fromName, String.valueOf(valFrom));
            stub.putState(toName, String.valueOf(valTo));
            System.out.println("Transfer complete");
            return null;
    
        }
    
        /**
         * 资产初始化,需要输入的参数例子 a 100 b 200
         * peer chaincode deploy -C testchainid -n simple -l java -c '{"Args": ["init", "a","100", "b", "200"]}'
         */
        public String init(ChaincodeStub stub, String function, String[] args) {
            if(args.length!=4){
                return "{\"Error\":\"Incorrect number of arguments. Expecting 4\"}";
            }
            int valA = Integer.parseInt(args[1]);
            int valB = Integer.parseInt(args[3]);
            stub.putState(args[0], String.valueOf(valA));
            stub.putState(args[2], String.valueOf(valB));
            return null;
        }
    
        /**
         * 资产查询,需要输入的参数例子 a
         * peer chaincode query -C testchainid -n simple -l java -c '{"Args": ["a"]}'
         */
        public String queryAsset(ChaincodeStub stub, String[] args) {
            return stub.getState(args[0]);
        }
    
        @Override
        public String query(ChaincodeStub stub, String function, String[] args) {
            return null;
        }
    
        @Override
        public String getChaincodeID() {
            return "simple";
        }
    
        public static void main(String[] args) throws Exception {
            new SimpleChaincode().start(args);
        }
    }
    

    区块链下一风向标:跨链技术

    如果说,2016年是金融区块链联盟(或称“金融联盟链”)元年,那么2017年,蓄势待发的金融区块链联盟也应该发挥其价值了。在这一过程中,哪种技术将给予金融区块链联盟以新的力量?笔者认为,“跨链技术”将成为构筑金融联盟链价值网的重要推动力。

    什么是跨链技术?

    “如果说共识机制是区块链的灵魂核心,那么对于区块链特别是联盟链及私链来看,跨链技术就是实现价值网络的关键,它是把联盟链从分散单独的孤岛中拯救出来的良药,是区块链向外拓展和连接的桥梁。”
    ——《连接不同区块链的跨链技术介绍》

    目前,相对比较流行的区块链跨链技术包括侧链、整合比特币和以太坊的M2功能和基于以太坊核心开发Ethcore推出的第三代公开无需授权的Polkadot技术等。

    其中最出名的侧链技术,最初是以锚定比特币为基础的新型区块链,它以融合的方式实现新的金融生态目标和进一步扩展了比特币网络的应用场景。我们可以轻松的建立各种智能化的金融合约,例如股票、期货、衍生品等。

    理解金融联盟链架构,鸟瞰跨链技术

    区块链或金融联盟链,可能成为连接传统金融系统和未来金融基础设施的桥梁。区块链要得到广泛应用,资产数字化(或称“资产上链”)是前提;而跨链技术,则是支撑未来区块链金融基础设施的主要技术力量之一

    恒生电子提出的“分层多链”的金融联盟许可链模型,将未来金融基础设施划分为三层架构,包括核心信任层、业务协作层和应用层。其中

    • 核心信任层,为整个金融联盟链提供系统和业务支撑,包括会员管理、证书管理、节点管理、智能合约升级管理等;
    • 业务协作层,可支持多条安全隔离的业务链;
    • 应用层,与金融机构的现有金融应用系统打通。

    我们可以想象,未来的金融业务可能是基于多条小型业务链,而业务链的互联互通使得资产价值不再孤立,最终形成融合多种数字资产的业务链价值网

    截止目前,恒生区块链已经支持的主流区块链底层技术,包括Hyperledger Fabric、蚂蚁区块链、以太坊等,R3 Corda的分布式账本也在考虑范围内。

    资产已纷纷上链,跨链还会远吗

    都说互联网是传递信息的网络,而区块链是传递价值的网络。随着各类数字资产的出现和上链,金融业亟需成熟的区块链技术和足够支撑各类金融业务的金融联盟链。

    “跨链技术”的力量不容小觑,“跨链技术”的前行步伐也将继续加快。


    恒生电子区块链技术白皮书官方剧透

    恒生电子推出的共享账本技术,主要是针对金融行业机构通过联盟链进行信任协作的底层基础架构,可广泛应用于金融行业的商务合约、数字资产存管与交易、存在性证明等。本文将为你揭开恒生共享账本技术白皮书的神秘面纱。

    金融企业级的安全保障

    金融应用, 信息安全第一。

    恒生金融共享账本从物理网络、应用到数据各个维度提供全方位的安全解决方案,平衡金融业务一致性共识、私密性以及合规监管需求。

    ● 安全的运行网络:联盟链运行在有准入机制的安全网络。
    ● 有身份的区块链:所有参与环节均实名认证,包括会员、接入应用、以及所有各类节点。
    ● 安全数据传输:所有消息采用SSL,保障传输过程中的数据安全。
    ● 高强度加密:采用国际标准商密算法,提供抗解剖、抗能量攻击和抗定时攻击等防护能力。
    ● 实时风险监控:实时监控网络和节点运行状况,触发风险监控会立即吊销证书,将隐患扼杀在萌芽中。

    私密的共享账本

    账本信息需要共识、共享,但是并不是要将交易信息公开公示。机构间商务契约通常是商业机密,账本公开明显不符合企业的商业利益。

    恒生共享账本采用独创的多层分链信任模型两阶段三方审计共识算法,保证交易的安全性、不可篡改特性并同时提供高性能支持。

    有安全级别的数据:交易数据可设置安全级别,私密数据将会加密存储。
    逻辑隔离的业务链:恒生共享账本支持多个业务账本同时执行,同时支持业务账本之间的数据隔离。
    分层的安全账本:私密信息加密存储在私密账本,并仅在交易干系人和业务联盟指定的官方监管机构间共享。多层信任模型保持总分账一致性和不可篡改特性,有效防止对账本数据非法探测分析。
    最小范围的私密数据传播:私密数据仅在交易干系人和授权监管方之间传播并对数据和规则进行验证和共识,其他各方仅对交易行为和交易规则进行审计和验证。

    业务领域模型的智能合约

    智能合约是商务契约的信息化展现方式,编码方式的合约对业务用户来说技术复杂、难以阅读。合约规则在业务人员与编码开发人员的沟通过程以及编码转换过程中的损失、误解将会给后续带来重大隐患和成本增加。

    恒生共享账本采用面向业务人员的业务领域模型语言定义智能合约,最大限度减少合约规则理解在沟通和转换过程中的损失、误解。

    业务人员看得懂的合约:业务领域模型语言是业务化的规则和逻辑展现,最大限度减少可能产生的歧义。
    特定业务领域的建模:智能合约只能对指定的特定业务领域规则和函数进行编排定义,有效防止利用合约代码漏洞进行攻击。恒生共享账本的智能合约是非图灵完备的。
    法律文书锚定:智能合约支持与链外书面合约或其他法律文书进行锚定,提供基础法律支持,预防潜在的意外纠纷。
    升级、纠错的合约:书面商务合同也会有变更和纠错,恒生共享账本的智能合约支持在交易参与方达成共识的条件下,变更合约规则(条款)。

    开放的解决方案

    恒生共享账本还提供全方位的运营管理、开发SDK、外链整合等支持。同时,恒生共享账本在技术社区开源,诚邀共同完善和推进区块链技术在金融行业的应用。

    随着来年有更多区块链与金融业务场景的结合,恒生电子共享账本将会越来越接地气。让我们一起期待!

    相关文章

      网友评论

        本文标题:(恒生)两步搞定Fabric,链码,跨链,白皮书

        本文链接:https://www.haomeiwen.com/subject/ebssxxtx.html