美文网首页Hyperledger Fabric开发实战
Hyperledger Fabric开发实战-08 供应链金融实

Hyperledger Fabric开发实战-08 供应链金融实

作者: 史圣杰 | 来源:发表于2018-12-09 00:03 被阅读0次

    本文是在阅读《区块链开发实战-Hyperledger Fabric关键技术与案例分析》一书的同时,在实践中记录的一些经验与分享。

    供应链金融本质上是一种金融服务,围绕核心企业,管理上下游中小企业的资金流和物流,并把单个企业的不可控风险转变为供应链企业整体的可控风险,通过获取各类信息,将风险控制在最低的金融服务。
    在整个供应链运行中,各个企业都使用赊销作为交易的主流方式,导致处于供应链中上游的供应商,很难通过"传统"的信贷方式获得银行的资金支持,而资金短缺又会直接导致后续环节的停滞,甚至出现"断链"。供应链金融的出现可以使供应商企业通过其应收账款,贸易数据等信息进行融资。
    在供应链运行过程中,各类信息分散保存在各个环节中,供应商的货物信息存储在供应商的仓储信息中,发货信息掌握在物流公司手中,自己信息分布在银行系统中,信息流由核心企业掌握,整个供应链信息不透明,各个参与发都有自己的相关系统,导致整个过程非常繁琐,针对这个问题,区块链的出现给解决这些问题到来了曙光。

    系统设计

    在应收账款融资场景中,通常设计核心企业,供应商,金融机构这三个参与方。供应商发起供货交易时,向超级账本发送供货交易,核心企业和金融机构签名并确认后,才能记账成功。

    组织

    我们按照如下规则为三个组织命名:

    机构名称 组织标识符 组织ID 组织域名
    核心企业 CoreOrg CoreMSP core.jianshu.com
    供应商 SupplierOrg SupplierMSP supplier.jianshu.com
    金融机构 BankOrg BankMSP bank.jianshu.com

    生成证书

    配置crypto-config.yaml,使用cryptogen可以生成相关证书

    OrdererOrgs:
        - Name: Orderer
          Domain: jianshu.com
          Specs:
                - Hostname: orderer
    PeerOrgs:
        - Name: Core
          Domain: core.jianshu.com
          Template:
                Count: 2
          Users:
                Count: 2
        - Name: Supplier
          Domain: supplier.jianshu.com
          Template:
              Count: 2
          Users:
              Count: 2
        - Name: Bank
          Domain: bank.jianshu.com
          Template:
              Count: 2
          Users:
              Count: 2
    

    启动系统

    规划好系统之后,整个启动过程与之前的一样,不过这次我们将orderer和三个peer分别部署在4台服务器上,服务器可以在UCloud上按小时付费临时使用。
    具体可以参见Hyperledger Fabric开发实战-02简单网络的整个流程。

    Chaincode

    Chaincode中主要是调用方法,有三个:
    putvalue方法,会设置资产的价格
    getlastvalue方法用于获取资产的价格
    gethistory方法用于获取资产的历史

    package main
    
    import (
       "github.com/hyperledger/fabric/core/chaincode/shim"
            pb "github.com/hyperledger/fabric/protos/peer"
            "fmt"
            "encoding/json"
            "time"
    )
    
    var asset_name = "asset_name_a"
    type scfinancechaincode struct {
        
    }
    
    func (t *scfinancechaincode) Init(stub shim.ChaincodeStubInterface) pb.Response {
        fmt.Printf(" init success")
        return shim.Success([]byte("init success"))
    }
    
    func (t *scfinancechaincode) Invoke(stub shim.ChaincodeStubInterface) pb.Response{
    
        _,args := stub.GetFunctionAndParameters()
        var opttype = args[0]
        var assetname = args[1]
        var optcontent = args[2]
    
        fmt.Printf("param is %s %s %s \n",opttype,assetname,optcontent)
        if opttype == "putvalue"{
            stub.PutState(assetname,[]byte(optcontent))
            return shim.Success([]byte("success put" + optcontent))
        }else if opttype == "getlastvalue"{
            var kv []byte
            var err error
            kv,err = stub.GetState(assetname)
            if(err != nil){
                return shim.Error("find error!")
            }
            return shim.Success(kv)
        }else if opttype == "gethistory"{
            keysIter,err := stub.GetHistoryForKey(assetname)
            if err != nil {
                return shim.Error(fmt.Sprintf("GetHistoryForKey failed,Error state: %s",err))
            }
            defer keysIter.Close()
            var keys []string
            for keysIter.HasNext(){
                response,iterErr := keysIter.Next()
                if iterErr != nil {
                    return shim.Error(fmt.Sprintf("GetHistoryForKey operation failed,Error state: %s",err))
                }
    
                txid := response.TxId 
                txvalue := response.Value
                txstate := response.IsDelete
                txtimestamp := response.Timestamp
                tm := time.Unix(txtimestamp.Seconds,0)
                datestr := tm.Format("2006-01-02 03:04:05 PM")
    
                fmt.Printf(" Tx info - txid: %s value: %s if delete: %t datetime: %s\n",txid,string(txvalue),txstate,datestr)
                keys = append(keys,txid)
            }
    
            jsonKeys,err := json.Marshal(keys)
            if err != nil {
                return shim.Error(fmt.Sprintf("query operation failed,error is %s",err))
            }
            return shim.Success(jsonKeys)
        }else{
            return  shim.Success([]byte("success invoke and No operation"))
        }
    }
    
    func main() {
            err := shim.Start(new(scfinancechaincode))
            if err != nil {
                    fmt.Printf("Error starting Simple chaincode: %s", err)
            }
    }
    

    客户端开发

    下面是发送交易的代码,channel首先通过sendTransactionProposal发送提案,获取响应之后,如果所有请求都成功,通过sendTransaction发送交易。

    var sendTransaction = function(chaincodeId,func,chaincode_args,channelname){
        let tx_id = null;
        return getOrgUser4Local().then((user) =>{
            tx_id = client.newTransactionID();
            var request = {
                chaincodeId:"supplychain-chaincode",
                fcn:func,
                args:chaincode_args,
                chainId:"cmbcchannel666",
                txId:tx_id
            };
            return channel.sendTransactionProposal(request);
        },(err) => {
            console.log("error",e);
        }).then((chaincodeInvokeResult) => {
            var proposalResponse = chaincodeInvokeResult[0];
            var proposal = chaincodeInvokeResult[1];
            var header = chaincodeInvokeResult[2];
            var all_good = true;
            for(var i in proposalResponse){
                let one_good = false;
                if(proposalResponse && proposalResponse[i].response &&
                proposalResponse[i].response.status === 200){
                    one_good = true;
                    console.log("transaction is good");
                }else{
                    console.error("transaction is bad");
                }
                all_good = all_good & one_good;
            }
            if(all_good){
                    /*console.info(util.format(
            
                    'successfullly: status - %s,message - "%s",metadata - "%s",endorsemenet signature:"%s"',
                    proposalResponse[0].response.status,proposalResponse[0].response.message,
                    proposalResponse[0].response.payload,proposalResponse[0].response.endorsement.signature
                ));*/
            
            
                var request = {
                    proposalResponses:proposalResponse,
                    proposal:proposal,
                    header:header
                }
            
                var transactionID = tx_id.getTransactionID();
                return channel.sendTransaction(request);
        
            }
        },(err) => {
            console.log("error",err);
        }).then((sendtransresult) => {
            return sendtransresult;
        },(err) =>{
            console.log("error",err);
        });
        
    }
    

    相关文章

      网友评论

        本文标题:Hyperledger Fabric开发实战-08 供应链金融实

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