encrypt-type: # 0:普通, 1:国密
encrypt-type: 0 #集群使用的加密类型
group-channel-connections-config:
caCert: classpath:fiscobcos-${spring.profiles.active}/ca.crt #链证书
sslCert: classpath:fiscobcos-${spring.profiles.active}/sdk.crt #机构证书
sslKey: classpath:fiscobcos-${spring.profiles.active}/sdk.key #机构私钥
gmCaCert: classpath:fiscobcos-${spring.profiles.active}/gmca.crt #集群为国密版,则需要配置
gmEnSslCert: classpath:fiscobcos-${spring.profiles.active}/gmensdk.crt
gmEnSslKey: classpath:fiscobcos-${spring.profiles.active}/gmensdk.key
gmSslCert: classpath:fiscobcos-${spring.profiles.active}/gmsdk.crt
gmSslKey: classpath:fiscobcos-${spring.profiles.active}/gmsdk.key
all-channel-connections:
- group-id: 1 # sdk实际连接的群组
connections-str:
# 若节点小于v2.3.0版本,查看配置项listen_ip:channel_listen_port
- 192.168.160.136:20200
- 192.168.160.136:20201
#- group-id: 2
#connections-str:
#- 192.168.160.130:20200
#- 192.168.160.130:20201
#- 192.168.160.135:20202
#- 192.168.160.135:20203
channel-service:
group-id: 1 # sdk实际连接的群组
agency-name: fisco # 机构名称
accounts:
pem-file: classpath:fiscobcos-${spring.profiles.active}/0x9ff96dcf17f27ddd643c23bc1236733aa92a1f20.pem #账户
# p12-file: 0x98333491efac02f8ce109b0c499074d47e7779a6.p12
# password: 123456
contract-address:
kVPerson: "0x3cc40ecd5000f58c3458fef29b91114bd5e18da3"#合约地址
引用fisco-bcos-web3sdk的2.6.1版本
deploy KVPerson
transaction hash: 0x72908963644b7e897bf03d0a9ddb9f76428f5b1684aee89eb251d0adf15bdb75
contract address: 0x3cc40ecd5000f58c3458fef29b91114bd5e18da3
把合约地址复制到项目的application-dev.yml配置文件里,通过合约地址来加载合约,获取合约对象。
使用web3sdk api将合约转换成java文件。执行SolidityGeneratorTest的compileSolFilesToJava(),在com.fish1208.temp包下生成java文件。
@Test
public void compileSolFilesToJava() throws IOException {
File solFile = new File("D:\\_CodeSource\\java\\fish1208-fiscobcos-web3sdk\\contract\\solidity\\KVPerson.sol");
SolidityCompiler.Result res = SolidityCompiler.compile(solFile, false, true, ABI, BIN, INTERFACE, METADATA);
log.info("Out: '{}'" , res.getOutput());
log.info("Err: '{}'" , res.getErrors());
CompilationResult result = CompilationResult.parse(res.getOutput());
log.info("contractname {}" , solFile.getName());
String contractname = solFile.getName().split("\\.")[0];
CompilationResult.ContractMetadata a = result.getContract(solFile.getName().split("\\.")[0]);
log.info("abi {}" , a.abi);
log.info("bin {}" , a.bin);
FileUtils.writeStringToFile(new File("src/test/resources/solidity/" + contractname + ".abi"), a.abi);
FileUtils.writeStringToFile(new File("src/test/resources/solidity/" + contractname + ".bin"), a.bin);
String binFile;
String abiFile;
String tempDirPath = new File("src/test/java/").getAbsolutePath();
String packageName = "com.fish1208.temp";
String filename = contractname;
abiFile = "src/test/resources/solidity/" + filename + ".abi";
binFile = "src/test/resources/solidity/" + filename + ".bin";
SolidityFunctionWrapperGenerator.main(Arrays.asList(
"-a", abiFile,
"-b", binFile,
"-p", packageName,
"-o", tempDirPath
).toArray(new String[0]));
}
将转换后的java文件复制到项目com.fish1208.contract包里
通过application-dev.yml配置文件的accounts项,获取签名,Credentials对象
package com.fish1208.bcos.config;
import org.fisco.bcos.channel.client.P12Manager;
import org.fisco.bcos.channel.client.PEMManager;
import org.fisco.bcos.web3j.crypto.Credentials;
import org.fisco.bcos.web3j.crypto.ECKeyPair;
import org.fisco.bcos.web3j.crypto.EncryptType;
import org.fisco.bcos.web3j.crypto.gm.GenCredential;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.io.IOException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
import java.security.spec.InvalidKeySpecException;
@Configuration
@ConfigurationProperties(prefix = "accounts")
public class AccountConfig {
private String pemFile;
private String p12File;
private String password;
private static final Logger log = LoggerFactory.getLogger(AccountConfig.class);
@Autowired
private EncryptType encryptType;
@Bean
public Credentials getCredentials()
throws UnrecoverableKeyException, KeyStoreException, NoSuchAlgorithmException,
InvalidKeySpecException, NoSuchProviderException, CertificateException,
IOException {
return loadPemAccount();
//return GenCredential.create();
// return loadP12Account();
}
// load pem account file
private Credentials loadPemAccount()
throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException,
NoSuchProviderException, InvalidKeySpecException, UnrecoverableKeyException {
log.info("pem accounts : {}", pemFile);
PEMManager pem = new PEMManager();
pem.setPemFile(pemFile);
pem.load();
ECKeyPair keyPair = pem.getECKeyPair();
Credentials credentials = GenCredential.create(keyPair.getPrivateKey().toString(16));
log.info("credentials address : {}", credentials.getAddress());
return credentials;
}
// load p12 account file
private Credentials loadP12Account()
throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException,
NoSuchProviderException, InvalidKeySpecException, UnrecoverableKeyException {
log.info("p12 accounts : {}", p12File);
P12Manager p12Manager = new P12Manager();
p12Manager.setP12File("classpath:" + p12File);
p12Manager.setPassword(password);
p12Manager.load();
ECKeyPair keyPair = p12Manager.getECKeyPair();
Credentials credentials = GenCredential.create(keyPair.getPrivateKey().toString(16));
System.out.println(credentials.getAddress());
return credentials;
}
/**
* @return the pemFile
*/
public String getPemFile() {
return pemFile;
}
/**
* @param pemFile the pemFile to set
*/
public void setPemFile(String pemFile) {
this.pemFile = pemFile;
}
/**
* @return the p12File
*/
public String getP12File() {
return p12File;
}
/**
* @param p12File the p12File to set
*/
public void setP12File(String p12File) {
this.p12File = p12File;
}
/**
* @return the password
*/
public String getPassword() {
return password;
}
/**
* @param password the password to set
*/
public void setPassword(String password) {
this.password = password;
}
}
通过application-dev.yml配置文件的group-channel-connections-config项,获取群组连接信息
package com.fish1208.bcos.config;
import org.fisco.bcos.channel.handler.ChannelConnections;
import org.fisco.bcos.channel.handler.GroupChannelConnectionsConfig;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.Resource;
import java.util.ArrayList;
import java.util.List;
@Configuration
@ConfigurationProperties(prefix = "group-channel-connections-config")
public class GroupChannelConnectionsPropertyConfig {
List allChannelConnections = new ArrayList<>();
private Resource caCert;
private Resource sslCert;
private Resource sslKey;
private Resource gmCaCert;
private Resource gmEnSslCert;
private Resource gmEnSslKey;
private Resource gmSslCert;
private Resource gmSslKey;
@Bean
public GroupChannelConnectionsConfig getGroupChannelConnections() {
GroupChannelConnectionsConfig groupChannelConnectionsConfig =
new GroupChannelConnectionsConfig();
groupChannelConnectionsConfig.setCaCert(caCert);
groupChannelConnectionsConfig.setSslCert(sslCert);
groupChannelConnectionsConfig.setSslKey(sslKey);
//gm
groupChannelConnectionsConfig.setGmCaCert(gmCaCert);
groupChannelConnectionsConfig.setGmEnSslCert(gmEnSslCert);
groupChannelConnectionsConfig.setGmEnSslKey(gmEnSslKey);
groupChannelConnectionsConfig.setGmSslCert(gmSslCert);
groupChannelConnectionsConfig.setGmSslKey(gmSslKey);
groupChannelConnectionsConfig.setAllChannelConnections(allChannelConnections);
return groupChannelConnectionsConfig;
}
/**
* @return the caCert
*/
public Resource getCaCert() {
return caCert;
}
/**
* @param caCert the caCert to set
*/
public void setCaCert(Resource caCert) {
this.caCert = caCert;
}
/**
* @return the sslCert
*/
public Resource getSslCert() {
return sslCert;
}
/**
* @param sslCert the sslCert to set
*/
public void setSslCert(Resource sslCert) {
this.sslCert = sslCert;
}
/**
* @return the sslKey
*/
public Resource getSslKey() {
return sslKey;
}
/**
* @param sslKey the sslKey to set
*/
public void setSslKey(Resource sslKey) {
this.sslKey = sslKey;
}
public Resource getGmCaCert() {
return gmCaCert;
}
public void setGmCaCert(Resource gmCaCert) {
this.gmCaCert = gmCaCert;
}
public Resource getGmEnSslCert() {
return gmEnSslCert;
}
public void setGmEnSslCert(Resource gmEnSslCert) {
this.gmEnSslCert = gmEnSslCert;
}
public Resource getGmEnSslKey() {
return gmEnSslKey;
}
public void setGmEnSslKey(Resource gmEnSslKey) {
this.gmEnSslKey = gmEnSslKey;
}
public Resource getGmSslCert() {
return gmSslCert;
}
public void setGmSslCert(Resource gmSslCert) {
this.gmSslCert = gmSslCert;
}
public Resource getGmSslKey() {
return gmSslKey;
}
public void setGmSslKey(Resource gmSslKey) {
this.gmSslKey = gmSslKey;
}
/**
* @return the allChannelConnections
*/
public List getAllChannelConnections() {
return allChannelConnections;
}
/**
* @param allChannelConnections the allChannelConnections to set
*/
public void setAllChannelConnections(List allChannelConnections) {
this.allChannelConnections = allChannelConnections;
}
}
通过application-dev.yml配置文件的channel-service项,获取Service对象
package com.fish1208.bcos.config;
import com.fish1208.common.constant.ConnectConstants;
import org.fisco.bcos.channel.client.Service;
import org.fisco.bcos.channel.handler.GroupChannelConnectionsConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @author ASUS
*/
@Configuration
@ConfigurationProperties(prefix = "channel-service")
public class ServiceConfig {
private String agencyName;
private int groupId;
private static final Logger log = LoggerFactory.getLogger(ServiceConfig.class);
@Bean
public Service getService(GroupChannelConnectionsConfig groupChannelConnectionsConfig) {
Service channelService = new Service();
channelService.setConnectSeconds(ConnectConstants.CONNECT_SECONDS);
channelService.setOrgID(agencyName);
log.info("agencyName : {}", agencyName);
channelService.setConnectSleepPerMillis(ConnectConstants.CONNECT_SLEEP_PER_MILLIS);
channelService.setGroupId(groupId);
channelService.setAllChannelConnections(groupChannelConnectionsConfig);
return channelService;
}
/**
* @return the agencyName
*/
public String getAgencyName() {
return agencyName;
}
/**
* @param agencyName the agencyName to set
*/
public void setAgencyName(String agencyName) {
this.agencyName = agencyName;
}
/**
* @return the groupId
*/
public int getGroupId() {
return groupId;
}
/**
* @param groupId the groupId to set
*/
public void setGroupId(int groupId) {
this.groupId = groupId;
}
}
获取web3j对象
package com.fish1208.bcos.config;
import com.fish1208.common.constant.ConnectConstants;
import org.fisco.bcos.channel.client.Service;
import org.fisco.bcos.web3j.protocol.Web3j;
import org.fisco.bcos.web3j.protocol.channel.ChannelEthereumService;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class Web3jConfig {
@Bean
public Web3j getWeb3j(Service service) throws Exception {
ChannelEthereumService channelEthereumService = new ChannelEthereumService();
service.run();
channelEthereumService.setChannelService(service);
channelEthereumService.setTimeout(ConnectConstants.TIME_OUT);
return Web3j.build(channelEthereumService, service.getGroupId());
}
}
通过application-dev.yml配置文件的contract-address得到合约地址,用来加载合约,获取合约对象
package com.fish1208.bcos.config;
import com.fish1208.bcos.ContractAddress;
import com.fish1208.common.constant.GasConstants;
import com.fish1208.contract.KVPerson;
import lombok.extern.slf4j.Slf4j;
import org.fisco.bcos.web3j.crypto.Credentials;
import org.fisco.bcos.web3j.protocol.Web3j;
import org.fisco.bcos.web3j.tx.gas.StaticGasProvider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Slf4j
@Configuration
@ConfigurationProperties(prefix = "contract-address")
public class ContractConfig {
private String kVPerson;
@Autowired
private Web3j web3j;
@Autowired
private Credentials credentials;
@Bean
public KVPerson loadTokenERC20(){
return KVPerson.load(kVPerson, web3j, credentials, new StaticGasProvider(GasConstants.GAS_PRICE, GasConstants.GAS_LIMIT));
}
@Bean
public ContractAddress setAddress(){
log.info("kVPerson={}", kVPerson);
ContractAddress contractAddress = new ContractAddress();
contractAddress.setKVPerson(kVPerson);
return contractAddress;
}
public String getkVPerson() {
return kVPerson;
}
public void setkVPerson(String kVPerson) {
this.kVPerson = kVPerson;
}
}
调用合约的set、get方法,进行数据上链、链上数据查询。
package com.fish1208.controller;
import com.alibaba.fastjson.JSON;
import com.fish1208.common.response.Result;
import com.fish1208.contract.KVPerson;
import lombok.extern.slf4j.Slf4j;
import org.fisco.bcos.web3j.protocol.core.methods.response.TransactionReceipt;
import org.fisco.bcos.web3j.tuples.generated.Tuple4;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.math.BigInteger;
import java.util.Map;
@Slf4j
@RestController
@RequestMapping("/contract/person")
public class PersonController {
@Autowired
private KVPerson person;
/**
*
* @param id
* @return
* @throws Exception
*/
@RequestMapping(value = "/get", method = RequestMethod.GET)
public Result> get(@RequestParam String id) throws Exception {
if (person != null) {
log.info("KVPerson address is: {}", person.getContractAddress());
Tuple4 tuple = person.get(id).send();
return Result.data(tuple);
}
return Result.fail("执行KVPerson合约失败");
}
@RequestMapping(value = "/set", method = RequestMethod.POST)
public Result> set(@RequestBody Map param) throws Exception {
if (person != null) {
log.info("KVPerson address is: {}", person.getContractAddress());
String id = (String)param.get("id");
String name = (String) param.get("name");
BigInteger age = BigInteger.valueOf((Integer) param.get("age"));
String sex = (String) param.get("sex");
TransactionReceipt receipt = person.set(id, name, age, sex).send();
log.info("KVPerson receipt = {}", JSON.toJSONString(receipt));
return Result.data(receipt);
}
return Result.fail("执行KVPerson合约失败");
}
}
http://127.0.0.1:7022/contract/person/set
请求
POST /contract/person/set HTTP/1.1
Content-Type: application/json
{
"id":"3",
"name":"成功",
"age":1000,
"sex":"女"
}
http://127.0.0.1:7022/contract/person/get?id=3
请求
GET /contract/person/get HTTP/1.1
id=3
https://github.com/hongfish/fish1208-fiscobcos-web3sdk