区块链(ubuntu)-Hyperledger Fabric实验环境搭建,修改chaincode,部署chaincode以及测试chaincode(JAVA)

Posted Ferron Zhu

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了区块链(ubuntu)-Hyperledger Fabric实验环境搭建,修改chaincode,部署chaincode以及测试chaincode(JAVA)相关的知识,希望对你有一定的参考价值。

文章目录

发文不易,求观众老爷们觉得这篇文章对你们有帮助的话能不能一键三连一下,谢谢!!!

1、环境准备

  • 安装公共依赖

    sudo apt-get install -y apt-transport-https ca-certificates software-properties-common 
    sudo apt-get install -y unzip git  curl wget vim tree jq
    
  • 安装gradle

    cd /tmp && wget https://services.gradle.org/distributions/gradle-6.4-bin.zip
    unzip gradle-6.4-bin.zip
    sudo mv gradsle-6.4 /usr/local/gradle
    #修改配置文件
    sudo cat >> ~/.bashrc <<EOF
    export PATH=$PATH:/usr/local/gradle/bin
    EOF
    #使配置文件生效
    source ~/.bashrc 
    
  • 需要安装的七个docker镜像(版本不确定是否有影响)

  • 下载docker-compose

    wget https://get.daocloud.io/docker/compose/releases/download/1.25.3/docker-compose-`uname -s`-`uname -m`
    sudo mv docker-compose-`uname -s`-`uname -m` /usr/local/bin/docker-compose
    sudo chmod +x /usr/local/bin/docker-compose
    docker-compose -v #检查是否安装成功
    
  • java环境

    java -version
    #如果没有java环境,用下列命令安装
    sudo apt-get install -y openjdk-8-jdk
    
  • 下载workspace工作目录(将下载的workspace放在用户的home目录下即可)

    git clone https://gitlab.com/qubing/blockchain_lab_v2.git ~/workspace
    

    确保workspace下有以下的文件和文件夹

  • 为了开发和单元测试方便,可以在服务器或虚拟机上安装IDEA进行chaincode的开发。

  • 使用虚拟机进行实验可安装gui,使用云服务器进行实验可以在云服务器上安装gui然后通过vnc进行连接,安装gui过程参见AWS Ubuntu安装可视化操作桌面和VS Code,Code Server

2、example01项目

  • 因为workspace目录下的chaincode目录下有一个example01项目,主要是让大家熟悉chaincode怎么编写。

  • 使用IDEA打开example01下的java项目,该项目是一个gradle项目,等待项目建立完成之后,打开MyContract.java文件,查看初始的智能合约代码。

  • workspace文件夹下使用下列命令来体验如何部署一个区块链网络

    #检测区块链网络的环境,初始化区块链网络,并且建立每个区块链网络的结点
    . ./init.sh 
    #检测结点是否正常运行(当执行startup脚本时出现docker镜像问题时,是因为startup脚本本身的问题)
    . ./startup.sh
    #部署example01的chaincode
    . scripts/deploy_chaincode.sh java $PWD/chaincode/chaincode_example01/java mycc_java
    #测试example01的chaincode
    . scripts/test_example01.sh mycc_java
    #清空区块链网络环境
    . ./teardown.sh
    
  • 解决startup.sh脚本执行错误:更改startup.sh中的DB_IMAGE_TAG,将原来的DB_IMAGE_TAG替换成DB_VERSION

3、修改example01项目

  • 为了更好的熟悉这个项目,我们来新增一个GetValueSetValue方法,并将其部署区块链网络上

    /**
    *SetValue
    *@param ctx context
    *@param key key
    *@param value value
    */
    @Transaction(name = "SetValue",intent = Transaction.TYPE.SUBMIT)
    public void SetValue(final Context ctx, final String key, final String value)
        ChaincodeStub stub = ctx.getStub();
        stub.putStringState(key,value);
    
    
    /**
    *GetValue
    *@param ctx context
    *@param key key
    *@return value state in ledger
    */
    @Transaction(name = "GetValue",intent = Transaction.TYPE.EVALUATE)
    public String GetValue(final Context ctx, final String key)
        ChaincodeStub stub = ctx.getStub();
        return stub.getStringState(key);
    
    
  • 进行单元测试(需要进行实际的测试,看单元测试是否通过)

    @Nested
    class InvokeSetValueTransaction 
        @Test
        public void SetValue() 
            MyContract contract = new MyContract();
            Context ctx = mock(Context.class);
            ChaincodeStub stub = mock(ChaincodeStub.class);
            String key = "truth";
            String value = "ferron is a good boy";
    
            when(ctx.getStub()).thenReturn(stub);
    
            contract.SetValue(ctx,key,value);
            InOrder inOrder = inOrder(stub);
            inOrder.verify(stub).putStringState(key, value);
        
    
    
    @Nested
    class InvokeGetValueTransaction 
        @Test
        public void GetValue() 
            MyContract contract = new MyContract();
            Context ctx = mock(Context.class);
            ChaincodeStub stub = mock(ChaincodeStub.class);
            String key = "truth";
            when(ctx.getStub()).thenReturn(stub);
    
            when(stub.getStringState(key)).thenReturn("ferron is a good boy");
            assertThat(contract.GetValue(ctx,key).equals("ferron is a good boy"));
        
    
    
  • 重新部署example01目录下的java项目(不需要进行测试chaincode),具体部署方式参见第二部分,部署之前一定要确保已经执行过teardown.sh脚本

  • scripts目录下新建一个的new_test_example01.sh脚本,并且将原来的test_example01.sh脚本复制到新建的脚本内,并且修改脚本,新增GetvalueSetValue方法的脚本

  • 测试部署的chaincode

    . scripts/new_test_example01.sh mycc_java
    

4、example02项目

  • example02项目是一个钱包的chaincode,初始java代码中包含InitQueryTransfer三种方法,功能分别是初始化钱包账户和余额,查询钱包余额,两个钱包之间进行转账。

  • 现在我们新增一个Recharge方法,用于给一个账户充值。

    @Transaction(name = "Recharge", intent = Transaction.TYPE.SUBMIT)
    public void recharge(final Context ctx, final String keyAccount, final String valueTrans)
        ChaincodeStub stub = ctx.getStub();
        //get value of account
        String value = stub.getStringState(keyAccount);
    
        // account not existing
        if (value.isEmpty()) 
            String errorMessage = String.format(Message.ACCOUNT_NOT_EXISTING.template(), keyAccount);
            System.out.println(errorMessage);
            throw new ChaincodeException(errorMessage);
        
    
        //type conversion
        int intValue = Integer.parseInt(value);
        int intValueTrans = Integer.parseInt(valueTrans);
        intValue+=intValueTrans;
        stub.putStringState(keyAccount,String.valueOf(intValue));
    
    
    
  • 进行单元测试

    @Nested
    class InvokeRechargeTransaction 
        @Test
        public void whenAccountExists() 
            MyContract contract = new MyContract();
            Context ctx = mock(Context.class);
            ChaincodeStub stub = mock(ChaincodeStub.class);
            String keyAccount = "A";
            String valueRech = "100";
    
            when(ctx.getStub()).thenReturn(stub);
            when(stub.getStringState("A")).thenReturn("100");
    
            Throwable thrown = catchThrowable(() ->
                contract.recharge(ctx,keyAccount,valueRech);
            );
    
            assertThat(thrown).isNull();
        
    
        @Test
        public void whenAccountNotExists()
            MyContract contract = new MyContract();
            Context ctx = mock(Context.class);
            ChaincodeStub stub = mock(ChaincodeStub.class);
            String keyAccount = "A";
            String valueRech = "100";
    
            when(ctx.getStub()).thenReturn(stub);
            when(stub.getStringState("A")).thenReturn("");
    
            Throwable thrown = catchThrowable(() ->
                contract.recharge(ctx,keyAccount,valueRech);
            );
    
            assertThat(thrown)
                .isInstanceOf(ChaincodeException.class)
                .hasNoCause()
                .hasMessage(String.format(MyContract.Message.ACCOUNT_NOT_EXISTING.template(),"A"));
        
    
    
    
  • 部署chaincode

    . scripts/deploy_chaincode.sh java $PWD/chaincode/chaincode_example02/java mycc_java02
    
  • 将原来的test_example02.sh复制一份并且进行以下修改

  • 测试chaincode

    . scripts/new_test_example02.sh mycc_java02
    

以上是关于区块链(ubuntu)-Hyperledger Fabric实验环境搭建,修改chaincode,部署chaincode以及测试chaincode(JAVA)的主要内容,如果未能解决你的问题,请参考以下文章

区块链(ubuntu)-Hyperledger Fabric的Java SDK开发

区块链(ubuntu)-Hyperledger Fabric的Java SDK开发

区块链(ubuntu)-Hyperledger Fabric的Java SDK开发

区块链(ubuntu)-Hyperledger Fabric的隐私保护

区块链(ubuntu)-Hyperledger Fabric的隐私保护

区块链(ubuntu)-Hyperledger Fabric的隐私保护