Advertisement

Fisco-Bcos区块链java应用开发

阅读量:

基于Fisco-Bcos的java应用开发

工具

  • IDEA
  • 一台linux服务器或linux虚拟机

一:搭建区块链网络

搭建第一个区块链网络

官方文档

这一个看文档就可以了,没什么需要特别注意的

搭建完之后,启动节点

复制代码
    cd ~/fisco/console
    bash nodes/127.0.0.1/start_all.sh

启动成功后会输出

复制代码
    try to start node0
    try to start node1
    try to start node2
    try to start node3
     node1 start successfully
     node2 start successfully
     node0 start successfully
     node3 start successfully

二:将sol合约编译成java文件

官方文档

准备一个智能合约,官方在fisco/console/contracts/solidity中提供了HelloWorld.sol智能合约,现在使用sol2java.sh将contracts/solidity下的所有合约编译产生bin,abi,java工具类

复制代码
    cd ~/fisco/console
    bash sol2java.sh org.com.fisco

得到返回

复制代码
    *** Compile solidity TableTest.sol*** 
    INFO: Compile for solidity TableTest.sol success.
    *** Convert solidity to java  for TableTest.sol success *** *** Compile solidity KVTableTest.sol*** 
    INFO: Compile for solidity KVTableTest.sol success.
    *** Convert solidity to java  for KVTableTest.sol success *** *** Compile solidity HelloWorld.sol*** 
    INFO: Compile for solidity HelloWorld.sol success.
    *** Convert solidity to java  for HelloWorld.sol success *** *** Compile solidity Table.sol*** 
    INFO: Compile for solidity Table.sol success.
    *** Convert solidity to java  for Table.sol success *** *** Compile solidity ShaTest.sol*** 
    INFO: Compile for solidity ShaTest.sol success.
    *** Convert solidity to java  for ShaTest.sol success ***

看一下新生成的目录结构

复制代码
    cd ~/fisco/console/contracts
    tree sdk
    sdk
    ├── abi
    │   ├── Asset.abi
    │   ├── HelloWorld.abi
    │   ├── KVTableTest.abi
    │   ├── ShaTest.abi
    │   ├── sm
    │   │   ├── Asset.abi
    │   │   ├── HelloWorld.abi
    │   │   ├── KVTableTest.abi
    │   │   ├── ShaTest.abi
    │   │   ├── Table.abi
    │   │   └── TableTest.abi
    │   ├── Table.abi
    │   └── TableTest.abi
    ├── bin
    │   ├── Asset.bin
    │   ├── HelloWorld.bin
    │   ├── KVTableTest.bin
    │   ├── ShaTest.bin
    │   ├── sm
    │   │   ├── Asset.bin
    │   │   ├── HelloWorld.bin
    │   │   ├── KVTableTest.bin
    │   │   ├── ShaTest.bin
    │   │   ├── Table.bin
    │   │   └── TableTest.bin
    │   ├── Table.bin
    │   └── TableTest.bin
    └── java
    └── org
        ├── com
        │   └── fisco
        │       ├── Asset.java
        │       ├── HelloWorld.java
        │       ├── KVTableTest.java
        │       ├── ShaTest.java
        │       ├── Table.java
        │       └── TableTest.java
        └── fisco
            └── bcos
                └── asset
                    └── contract
                        ├── Asset.java
                        ├── HelloWorld.java
                        ├── KVTableTest.java
                        ├── ShaTest.java
                        ├── Table.java
                        └── TableTest.java
    
    12 directories, 36 files

上面就是编译生成的java文件以及abi,bin目录

三:在Idea创建项目以及创建各种配置文件

  1. 创建一个Gradle工程
    在这里插入图片描述

  2. 在build.gradle中加入以下依赖

    • Spring
    • fisco-bcos
复制代码
    plugins {
    id 'java'
    }
    
    group 'org.example'
    version '1.0-SNAPSHOT'
    
    repositories {
    mavenCentral()
    }
    
    //需要加入的↓
    def spring_version = "4.3.27.RELEASE"
    List spring = [
        "org.springframework:spring-core:$spring_version",
        "org.springframework:spring-beans:$spring_version",
        "org.springframework:spring-context:$spring_version",
        "org.springframework:spring-tx:$spring_version",
    ]
    //需要加入的↑
    
    dependencies {
    testImplementation 'org.junit.jupiter:junit-jupiter-api:5.6.0'
    testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine'
    //需要加入的↓
    compile ('org.fisco-bcos.java-sdk:fisco-bcos-java-sdk:2.7.1')
    compile spring
    compile ('org.slf4j:slf4j-log4j12:1.7.25')
    runtime ('org.slf4j:slf4j-log4j12:1.7.25')
    //需要加入的↑
    }
    
    test {
    useJUnitPlatform()
    }
  1. 将sol2java.sh生的java文件放到工程中,目录结构如下:
    在这里插入图片描述

  2. 将节点证书以及生成的abi、bin目录放到资源目录下
    在这里插入图片描述

节点证书就是fisco/nodes/127.0.0.1/sdk目录下的所有文件

创建配置文件config-example.toml,放在resources目录下

复制代码
    [cryptoMaterial]

    
    certPath = "conf"                           # The certification path
    
    # The following configurations take the certPath by default if commented
    # caCert = "conf/ca.crt"                    # CA cert file path
    # If connect to the GM node, default CA cert path is ${certPath}/gm/gmca.crt
    
    # sslCert = "conf/sdk.crt"                  # SSL cert file path
    # If connect to the GM node, the default SDK cert path is ${certPath}/gm/gmsdk.crt
    
    # sslKey = "conf/sdk.key"                   # SSL key file path
    # If connect to the GM node, the default SDK privateKey path is ${certPath}/gm/gmsdk.key
    
    # enSslCert = "conf/gm/gmensdk.crt"         # GM encryption cert file path
    # default load the GM SSL encryption cert from ${certPath}/gm/gmensdk.crt
    
    # enSslKey = "conf/gm/gmensdk.key"          # GM ssl cert file path
    # default load the GM SSL encryption privateKey from ${certPath}/gm/gmensdk.key
    
    [network]
    peers=["192.168.160.66:20200", "192.168.160.66:20201"]    # The peer list to connect
    
    
    # AMOP configuration
    # You can use following two methods to configure as a private topic message sender or subscriber.
    # Usually, the public key and private key is generated by subscriber.
    # Message sender receive public key from topic subscriber then make configuration.
    # But, please do not config as both the message sender and the subscriber of one private topic, or you may send the message to yourself.
    
    # Configure a private topic as a topic message sender.
    # [[amop]]
    # topicName = "PrivateTopic"
    # publicKeys = [ "conf/amop/consumer_public_key_1.pem" ]    # Public keys of the nodes that you want to send AMOP message of this topic to.
    
    # Configure a private topic as a topic subscriber.
    # [[amop]]
    # topicName = "PrivateTopic"
    # privateKey = "conf/amop/consumer_private_key.p12"         # Your private key that used to subscriber verification.
    # password = "123456"
    
    
    [account]
    keyStoreDir = "account"         # The directory to load/store the account file, default is "account"
    # accountFilePath = ""          # The account file path (default load from the path specified by the keyStoreDir)
    accountFileFormat = "pem"       # The storage format of account file (Default is "pem", "p12" as an option)
    
    # accountAddress = ""           # The transactions sending account address
    # Default is a randomly generated account
    # The randomly generated account is stored in the path specified by the keyStoreDir
    
    # password = ""                 # The password used to load the account file
    
    [threadPool]
    # channelProcessorThreadSize = "16"         # The size of the thread pool to process channel callback
    # Default is the number of cpu cores
    
    # receiptProcessorThreadSize = "16"         # The size of the thread pool to process transaction receipt notification
    # Default is the number of cpu cores
    
    maxBlockingQueueSize = "102400"             # The max blocking queue size of the thread pool

内容基本不用修改,主要是network下的节点peers,我是运行在虚拟机的,虚拟机ip地址和端口是192.168.160.66:20000,192.168.160.66:20001,如果是运行在本机就改成127.0.0.1就可以了,端口同理,有修改的就该

创建一个log4j.properties文件在resource目录下,内容如下:

复制代码
    ### set log levels ###

    log4j.rootLogger=DEBUG, file
    
    ### output the log information to the file ###
    log4j.appender.file=org.apache.log4j.DailyRollingFileAppender
    log4j.appender.file.DatePattern='_'yyyyMMddHH'.log'
    log4j.appender.file.File=./log/sdk.log
    log4j.appender.file.Append=true
    log4j.appender.file.filter.traceFilter=org.apache.log4j.varia.LevelRangeFilter
    log4j.appender.file.layout=org.apache.log4j.PatternLayout
    log4j.appender.file.layout.ConversionPattern=[%p] [%-d{yyyy-MM-dd HH:mm:ss}] %C{1}.%M(%L) | %m%n
    
    ###output the log information to the console ###
    log4j.appender.stdout=org.apache.log4j.ConsoleAppender
    log4j.appender.stdout.Target=System.out
    log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
    log4j.appender.stdout.layout.ConversionPattern=[%p] [%-d{yyyy-MM-dd HH:mm:ss}] %C{1}.%M(%L) | %m%n

最后创建完的项目的目录结构如下所示

6qtjeK.png

在Idea中调用合约以及查看块的信息

在Test中创建一个BcosSDKTest

使用到的类有

复制代码
    org.fisco.bcos.sdk.client.Client;

该类用来与群组通信

复制代码
    org.fisco.bcos.sdk.client.protocol.response.BcosBlock

该类包含块的信息,包括哈希值、群组ID、交易哈希等信息

复制代码
    org.fisco.bcos.sdk.crypto.CryptoSuite

群组密码学接口,用来解析交易回执中的信息

复制代码
    org.fisco.bcos.sdk.crypto.keypair.CryptoKeyPair

用来部署合约

复制代码
    org.fisco.bcos.sdk.model.TransactionReceipt

交易回执,在Client类中通过交易哈希可以取得交易回执

BcosSDKTest代码如下

复制代码
    package org.com.fisco;
    
    import org.fisco.bcos.sdk.BcosSDK;
    import org.fisco.bcos.sdk.client.Client;
    import org.fisco.bcos.sdk.client.protocol.request.Transaction;
    import org.fisco.bcos.sdk.client.protocol.response.BcosBlock;
    import org.fisco.bcos.sdk.client.protocol.response.BcosTransactionReceipt;
    import org.fisco.bcos.sdk.client.protocol.response.BlockNumber;
    import org.fisco.bcos.sdk.crypto.CryptoSuite;
    import org.fisco.bcos.sdk.crypto.keypair.CryptoKeyPair;
    import org.fisco.bcos.sdk.model.TransactionReceipt;
    import org.fisco.bcos.sdk.transaction.codec.decode.TransactionDecoderInterface;
    import org.fisco.bcos.sdk.transaction.codec.decode.TransactionDecoderService;
    import org.fisco.bcos.sdk.transaction.manager.AssembleTransactionProcessor;
    import org.fisco.bcos.sdk.transaction.manager.TransactionProcessorFactory;
    import org.fisco.bcos.sdk.transaction.model.dto.CallResponse;
    import org.fisco.bcos.sdk.transaction.model.dto.TransactionResponse;
    import org.junit.jupiter.api.Test;
    
    import java.io.FileNotFoundException;
    import java.util.*;
    
    
    public class BcosSDKTest {
    // 获取配置文件路径
    public final String configFile = BcosSDKTest.class.getClassLoader().getResource("config-example.toml").getPath();
    @Test
    public void testClient() throws Exception {
        // 初始化BcosSDK
        BcosSDK sdk =  BcosSDK.build(configFile);
        // 为群组1初始化client
        Client client = sdk.getClient(Integer.valueOf(1));
    		 // 向群组1部署HelloWorld合约
        CryptoKeyPair cryptoKeyPair = client.getCryptoSuite().getCryptoKeyPair();
        HelloWorld helloWorld = HelloWorld.deploy(client, cryptoKeyPair);
    
         //调用HelloWorld合约的get接口
        //String getValue = helloWorld.get();
    
        // 调用HelloWorld合约的set接口
        TransactionReceipt receipt = helloWorld.set("Hello, fisco");
       // System.out.println(getValue);
        // 获取群组1的块高
        BlockNumber blockNumber = client.getBlockNumber();
    
        BcosBlock block = client.getBlockByNumber(blockNumber.getBlockNumber(), false); //得到块的信息
        Object o = block.getBlock().getTransactions().get(0).get(); //在块中得到交易哈希
        BcosTransactionReceipt transactionReceipt = client.getTransactionReceipt((String) o); //通过交易哈希得到交易回执
        // 获取当前群组对应的密码学接口
        CryptoSuite cryptoSuite = client.getCryptoSuite();
    		// 构造TransactionDecoderService实例,传入是否密钥类型参数。
        TransactionDecoderInterface decoder = new TransactionDecoderService(cryptoSuite);
    
        //events = decoder.decodeEvents("main/abi/sm/HelloWorld.abi", transactionReceipt.getResult().getLogs());
        String s = decoder.decodeReceiptMessage(transactionReceipt.getResult().getInput());
        System.out.println(blockNumber.getBlockNumber());
        System.out.println(s);
    }
    }

运行之后输出如下:

复制代码
    111
    Hello, fisco

块高以及交易时的Input都解码得到了,关于TransactionReceipt、TransactionDecoderInterface的更多内容请看官方文档

交易回执解析

全部评论 (0)

还没有任何评论哟~