java链码的编写很容易,如下2个:pom以及java代码:
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>mckay</groupId> <artifactId>test1</artifactId> <version>1.0-SNAPSHOT</version> <dependencies> <dependency> <groupId>org.hyperledger.fabric-chaincode-java</groupId> <artifactId>fabric-chaincode-shim</artifactId> <version>1.4.4</version> <exclusions> <exclusion> <groupId>com.github.everit-org.json-schema</groupId> <artifactId>org.everit.json.schema</artifactId> </exclusion> </exclusions> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.1</version> <configuration> <source>1.8</source> <target>1.8</target> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> <version>3.1.0</version> <executions> <execution> <phase>package</phase> <goals> <goal>shade</goal> </goals> <configuration> <finalName>chaincode</finalName> <transformers> <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"> <mainClass>tech.test1.MyChaincode</mainClass> </transformer> </transformers> <filters> <filter> <!-- filter out signature files from signed dependencies, else repackaging fails with security ex --> <artifact>*:*</artifact> <excludes> <exclude>META-INF/*.SF</exclude> <exclude>META-INF/*.DSA</exclude> <exclude>META-INF/*.RSA</exclude> </excludes> </filter> </filters> </configuration> </execution> </executions> </plugin> </plugins> </build> </project>
package tech.test1;
import com.google.protobuf.ByteString;
import io.netty.handler.ssl.OpenSsl;
import io.netty.util.internal.StringUtil;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hyperledger.fabric.shim.ChaincodeBase;
import org.hyperledger.fabric.shim.ChaincodeStub;
import java.util.List;
import static com.google.common.base.Charsets.UTF_8;
public class MyChaincode extends ChaincodeBase {
private static Log _logger = LogFactory.getLog(MyChaincode.class);
public static void main(String[] args) {
System.out.println("OpenSSL avaliable: " + OpenSsl.isAvailable());
new MyChaincode().start(args);
}
@Override
public Response init(ChaincodeStub chaincodeStub) {
return newSuccessResponse();
}
@Override
public Response invoke(ChaincodeStub stub) {
try {
_logger.info("Invoke java simple chaincode");
String func = stub.getFunction();
List<String> params = stub.getParameters();
if (func.equals("invoke")) {
return invoke(stub, params);
}
else if (func.equals("query")) {
return query(stub, params);
}
return newErrorResponse("Invalid invoke function name. Expecting one of: [\"invoke\", \"delete\", \"query\"]");
} catch (Throwable e) {
return newErrorResponse(e);
}
}
private Response invoke(ChaincodeStub stub, List<String> args) {
if (args.size() != 2) {
return newErrorResponse("Incorrect number of arguments. Expecting 3");
}
String key = args.get(0);
String json = args.get(1);
if(StringUtil.isNullOrEmpty(key) || StringUtil.isNullOrEmpty(json)){
return newErrorResponse("arguments error");
}else{
stub.putStringState(key,json);
return newSuccessResponse("put success!");
}
}
// query callback representing the query of a chaincode
private Response query(ChaincodeStub stub, List<String> args) {
if (args.size() != 1) {
return newErrorResponse("Incorrect number of arguments. Expecting name of the person to query");
}
String key = args.get(0);
//byte[] stateBytes
String val = stub.getStringState(key);
if (val == null) {
return newErrorResponse(String.format("Error: state for %s is null", key));
}
_logger.info(String.format("Query Response:\nName: %s, Amount: %s\n", key, val));
return newSuccessResponse(val, ByteString.copyFrom(val, UTF_8).toByteArray());
}
}
然后把一整个带pom文件的目录全部上传到fabric机器的chaincode目录下:

进入cli容器中(docker exec cli /bin/bash),进行链码的安装和初始化:
peer chaincode install -n mckaytest1 -v 1.0 -p /opt/gopath/src/github.com/chaincode/test1 -l java peer chaincode instantiate -o orderer.example.com:7050 --tls --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C mychannel -n mckaytest1 -v 1.0 -c ‘{"Args":["init"]}‘ -P "AND (‘Org1MSP.peer‘)"
做些命令行级别的测试:
peer chaincode invoke -o orderer.example.com:7050 --tls --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C mychannel -n mckaytest1 -c ‘{"Args":["invoke","a","bb"]}‘ peer chaincode invoke -o orderer.example.com:7050 --tls --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C mychannel -n mckaytest1 -c ‘{"Args":["query","a"]}‘
当改动链码代码后,需要升级,此时执行如下:
#升级 1.1 peer chaincode install -n mckaytest1 -v 1.1 -p /opt/gopath/src/github.com/chaincode/test1 -l java peer chaincode upgrade -o orderer.example.com:7050 --tls --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C mychannel -n mckaytest1 -v 1.1 -c ‘{"Args":["init"]}‘ -P "AND (‘Org1MSP.peer‘)"
用java代码调用链码(调用端需要改下hosts文件,以便识别orderer这些fabric节点的ip):
UserContext userContext = new UserContext();
userContext.setAffiliation("Org1");
userContext.setMspId("Org1MSP");
userContext.setAccount("李伟");
userContext.setName("admin");
Enrollment enrollment = UserUtils.getEnrollment(keyFolderPath, keyFileName, certFoldePath, certFileName);
userContext.setEnrollment(enrollment);
FabricClient fabricClient = new FabricClient(userContext);
Peer peer0 = fabricClient.getPeer("peer0.org1.example.com","grpcs://peer0.org1.example.com:7051",tlsPeerFilePath);
List<Peer> peers = new ArrayList<>();
peers.add(peer0);
Orderer order = fabricClient.getOrderer("orderer.example.com","grpcs://orderer.example.com:7050",tlsOrderFilePath);
String initArgs[] = {"a", "4444555555555"};
fabricClient.invoke("mychannel", TransactionRequest.Type.JAVA,"mckaytest1",order,peers,"invoke",initArgs);
记得要把fabric中这个带密钥的文件夹都复制到java工程里哦

源代码下载:https://files.cnblogs.com/files/aarond/fabric.rar
hyperledger fabric链码(java)编写以及调用
原文:https://www.cnblogs.com/aarond/p/12173797.html