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创建项目以及创建各种配置文件
-
创建一个Gradle工程

-
在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()
}
-
将sol2java.sh生的java文件放到工程中,目录结构如下:

-
将节点证书以及生成的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
最后创建完的项目的目录结构如下所示

在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的更多内容请看官方文档
