假定你有以下基础:
- 会通过fiscobcos的控制台部署合约,
deploy contractName
- 知道部署的合约地址。
源代码见:https://github.com/hongfish/fish1208-fiscobcos-javasdk
框架:springboot
包管理器:maven
先来介绍项目的目录,如下树状图所示:会依次对这些文件等结构信息进行注释。
本篇文章,旨在深入浅出的介绍入门基础。
├── conf //根目录下的配置包含了账户私钥文件,sdk连接的根证书,私钥等文件。
│ ├── 0x08291097f477935d2cf807083561b91aa816d4b5.pem //账户私钥文件,在console/account(s)中,通过get_account.sh获取。
│ ├── ca.crt//SSL连接根证书
│ ├── sdk.crt//SSL链接证书
│ ├── sdk.key//SSL链接证书私钥
│ └── sdk.publickey//SSL链接证书公钥
├── contract//合约文件
│ └── solidity
│ ├── HelloWorld.sol//合约源代码文件
├── mvnw
├── mvnw.cmd
├── pom.xml//maven的配置文件
├── src//项目源代码、资源文件
│ ├── main
│ │ ├── java
│ │ │ └── com
│ │ │ └── example
│ │ │ └── fiscobcosjava
│ │ │ ├── bcos//包
│ │ │ │ └── config//配置包
│ │ │ │ ├── BcosSDKConfig.java//BCosSDK组件
│ │ │ │ ├── ClientConfig.java//Client组件,可以理解为BCosSDK的客户端
│ │ │ │ └── ContractConfig.java//合约组件,用于加载合约的实例。
│ │ │ ├── contract
│ │ │ │ ├── HelloWorld.java//通过sol2java.sh生成的合约Java代码
│ │ │ ├── controller
│ │ │ │ └── ValuesController.java
│ │ │ └── FiscobcosJavaApplication.java
│ │ └── resources
│ │ ├── application-dev.yml//application-xxx.yml配置文件(多环境配置),记录了配置包中所需要的一些配置。
│ │ ├── application.yml//总配置,应用哪一个application-xxx.yml配置文件。
│ │ ├── config.toml//fiscobcos-sdk连接的配置文件,记录了证书位置,连接的节点,账户,私钥等文件。
│ │ └── templates
│ │ ├── login.html
│ │ └── result.html
我们需要在pom.xml中,引入fiscobcos的相关包。
<dependency>
<groupId>org.fisco-bcos.java-sdk</groupId>
<artifactId>fisco-bcos-java-sdk</artifactId>
<version>2.9.1</version>
<exclusions>
<exclusion>
<artifactId>slf4j-log4j12</artifactId>
<groupId>org.slf4j</groupId>
</exclusion>
<exclusion>
<groupId>org.ethereum</groupId>
<artifactId>solcJ-all</artifactId>
</exclusion>
</exclusions>
</dependency>
前置知识
通过分析,我发现最重要的部分就是组件部分,以及配置文件部分。组件通过@Configuration
+@Bean
还有一个@ConfigurationProperties(prefix = "config-toml")
来进行注册。
在程序运行前期,它会默认的根据指定的前缀"config-toml"在yml配置文件中获取该前缀下面的所有配置。而这个配置正是application-dev.yml文件。
BcosSDKConfig.java配置文件
@Configuration
@ConfigurationProperties(prefix = "config-toml")//指定在resource配置文件中,该bcos的核心配置文件路径。核心配置包含了sdk证书文件等。
public class BcosSDKConfig {
private Resource configPath;
@Bean
public BcosSDK getBcosSDK() throws Exception{
//根据给定的bcos配置文件路径,创建一个相应的bcos-sdk。这个配置文件包含了之前复制的节点证书,以及连接节点和账户等重要信息。
return BcosSDK.build(getFilePath(configPath));
}
private String getFilePath(Resource resource) throws Exception{
File tempFile= File.createTempFile(resource.getFilename().split("\\.")[0], "." + resource.getFilename().split("\\.")[1]);
InputStream in = resource.getInputStream();
try {
FileUtils.copyInputStreamToFile(in,tempFile);
}finally {
in.close();
}
return tempFile.getPath();
}
public Resource getConfigPath(){
return configPath;
}
public void setConfigPath(Resource configPath) {
this.configPath = configPath;
}
}
这里需要解释的是getBcosSDK()
,里边的BcosSDK.build()
需要传递一个配置文件路径,这个配置文件就是记录了SSL的链根证书,账户私钥,节点连接信息等配置。然后返回一个BcosSDK,configPath
的变量是Resource的,也就是说,在运行初期这里就已经被赋值了。
ClientConfig.java是根据已经注册好的BcosSDK组件,来为其创建一个指定组id的Client。配置与上述类似,不过它所用到的配置yml文件模块中的channel-service
。
@Configuration
@ConfigurationProperties(prefix = "channel-service")
public class ClientConfig {
private Integer groupId;
@Autowired
private BcosSDK sdk;
@Bean
public Client getClient(){
return sdk.getClient(groupId);
}
public Integer getGroupId() {
return groupId;
}
public void setGroupId(Integer groupId) {
this.groupId = groupId;
}
}
可以看到在sdk.getClient(groupId);
中就是通过组id获取相应的client。
有了模板BcosSDK和根据组id创建出相关的实例之后,我们还需要一个合约组件来完成最后一步。
配置文件前缀为:contract-address
它记录这HelloWorld部署后合约地址,通过这个合约地址可以访问它响应的abi和bin文件,其次通账户获取相关的账户私钥文件,来绑定该合约。
ContractConfig.java
@Slf4j
@Configuration
@ConfigurationProperties(prefix = "contract-address")
public class ContractConfig {
private String helloWorld;
@Bean
public HelloWorld loadHelloWorld(Client client){
return HelloWorld.load(helloWorld,client,client.getCryptoSuite().getCryptoKeyPair());
}
public static Logger getLog() {
return log;
}
public String getHelloWorld() {
return helloWorld;
}
public void setHelloWorld(String helloWorld) {
this.helloWorld = helloWorld;
}
}
关于这三个配置的Java文件(BCosSDKConfig,ClientConfig,ContractConfig),它们的先后顺序为:
上面所讲的配置前缀,都是通过application-dev.yml来实现的,配置如下:
channel-service: ##服务配置组建类bcos.config/ClientConfig
group-id: 1 # sdk实际连接的群组
config-toml: ##服务配置组建类:bcos.config/BcosSDKConfig
config-path: classpath:config.toml #区块链集群的配置文件
contract-address:
HelloWorld: "0x9e91097b9063475e64236822fc90ab733ad60cea" #合约地址
通过application.yml配置文件来进行选择:
spring:
profiles:
active: dev
这个是关于fiscobcos的配置文件config.toml
,如下:
[cryptoMaterial]
certPath = "conf"
caCert = "conf/ca.crt" #链证书
sslCert = "conf/sdk.crt" #机构证书
sslKey = "conf/sdk.key" #机构私钥
#enSslCert = "conf/gm/gmensdk.crt" #集群为国密版,则需要配置
#enSslKey = "conf/gm/gmensdk.key"
[network]
peers=["127.0.0.1:20200", "127.0.0.1:20201","127.0.0.1:20202","127.0.0.1:20203","127.0.0.1:20204"] #节点ip:port
[account]
keyStoreDir = "account"
accountFilePath = "conf/0x08291097f477935d2cf807083561b91aa816d4b5.pem"
accountFileFormat = "pem"
accountAddress = "0x08291097f477935d2cf807083561b91aa816d4b5" #账户