首先更新链码
新增PrivateCat.java
package org.example.demo;
import lombok.Data;
import lombok.experimental.Accessors;
import org.hyperledger.fabric.contract.annotation.DataType;
import org.hyperledger.fabric.contract.annotation.Property;
/**
* @Author: kingtao
* @Date: 2023-04-24-18:33
* @Description:
*/
@Data
@DataType
@Accessors(chain = true)
public class PrivateCat {
@Property
private Cat cat;
@Property
private String collection;
}
在controller新加
@Transaction
public byte[] queryPrivateCatHash(final Context ctx, final String key) {
ChaincodeStub stub = ctx.getStub();
String collection = getCollectionName(stub);
byte[] hash = stub.getPrivateDataHash(collection, key);
if (ArrayUtils.isEmpty(hash)) {
String err = String.format("Private Cat %s does not exist", key);
log.log(Level.WARNING, err);
throw new ClassCastException(err);
}
return hash;
}
@Transaction
public PrivateCat queryPrivateCat(final Context ctx, final String collection, final String key) {
ChaincodeStub stub = ctx.getStub();
log.info(String.format("查询到私有数据, collection [$s] key [%s], mspId [%s]", collection, stub.getMspId(), key));
String catState = stub.getPrivateDataUTF8(collection, key);
if (StringUtils.isBlank(catState)) {
String err = String.format("Private cat %s does not exist", key);
log.log(Level.WARNING, err);
throw new ChaincodeException(err);
}
return JSON.parseObject(catState, PrivateCat.class);
}
@Transaction
public PrivateCat createPrivateCat(final Context ctx, final String collection, final String key, String name, Integer age, String color, String breed) {
ChaincodeStub stub = ctx.getStub();
log.info(String.format("创建私有数据, collection [%s], mspId [%s], key [%s] name [%s] age [%s] color [%s] breed [%s]", collection, stub.getMspId(), key, name, age, color, breed));
String catState = stub.getPrivateDataUTF8(collection, key);
if (StringUtils.isNotBlank(catState)) {
String err = String.format("Private Cat %s 已经存在");
log.log(Level.WARNING, err);
throw new ChaincodeException(err);
}
PrivateCat privateCat = new PrivateCat();
Cat cat = new Cat();
cat.setColor(color).setName(name).setBreed(breed).setAge(age);
privateCat.setCat(cat).setCollection(collection);
String json = JSON.toJSONString(privateCat);
log.info(String.format("要保存的数据 %s", json));
stub.putPrivateData(collection, key, json);
return privateCat;
}
@Transaction
public PrivateCat updatePrivateCat(final Context ctx, final String collection, final String key, String name, Integer age, String color, String breed) {
ChaincodeStub stub = ctx.getStub();
log.info(String.format("创建私有数据, collection [%s], mspId [%s], key [%s] name [%s] age [%s] color [%s] breed [%s]", collection, stub.getMspId(), key, name, age, color, breed));
String catState = stub.getPrivateDataUTF8(collection, key);
if (StringUtils.isBlank(catState)) {
String err = String.format("Private Cat %s 不存在,无法更新");
log.log(Level.WARNING, err);
throw new ChaincodeException(err);
}
PrivateCat privateCat = new PrivateCat();
Cat cat = new Cat();
cat.setColor(color).setName(name).setBreed(breed).setAge(age);
privateCat.setCat(cat).setCollection(collection);
String json = JSON.toJSONString(privateCat);
log.info(String.format("要保存的数据 %s", json));
stub.putPrivateData(collection, key, json);
return privateCat;
}
@Transaction
public PrivateCat deletePrivateCat(final Context ctx, final String collection, final String key) {
ChaincodeStub stub = ctx.getStub();
log.info(String.format("删除私有数据 , collection [%s] , mspId [%s] , key [%s] ", collection, stub.getMspId(), key));
String catState = stub.getPrivateDataUTF8(collection, key);
if (StringUtils.isBlank(catState)) {
String err = String.format("Private Cat %s 不存在");
log.log(Level.WARNING, err);
throw new ChaincodeException(err);
}
stub.delPrivateData(collection, key);
return JSON.parseObject(catState, PrivateCat.class);
}
@Transaction
public String getCollectionName(final ChaincodeStub stub) {
String name = "collection" + stub.getMspId() + "Cats";
log.info(String.format("私有数据集合名称:[%s]", name));
return name;
}
然后打包链码
peer lifecycle chaincode package demo.tar.gz --path /opt/code/java-chaincode-demo/ --lang java --label demo_2
安装链码
# 设置以下环境变量,以Org1管理员的身份操作peer CLI。
export CORE_PEER_TLS_ENABLED=true
export CORE_PEER_LOCALMSPID="Org1MSP"
export CORE_PEER_TLS_ROOTCERT_FILE=${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt
export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp
export CORE_PEER_ADDRESS=localhost:7051
peer lifecycle chaincode install demo.tar.gz
# 以Org2管理员的身份操作peer CLI。
export CORE_PEER_LOCALMSPID="Org2MSP"
export CORE_PEER_TLS_ROOTCERT_FILE=${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt
export CORE_PEER_TLS_ROOTCERT_FILE=${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt
export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp
export CORE_PEER_ADDRESS=localhost:9051
peer lifecycle chaincode install demo.tar.gz
# 查询包ID
peer lifecycle chaincode queryinstalled
# 使用包标签找到新链码的包ID,并将其另存为新的环境变量:
export NEW_CC_PACKAGE_ID=demo_2:e02692960b761e583b772c73571eec676f663e832e78914430965e909f806660
# 因为已经设置了环境变量为peer CLI作为Orig2管理员进行操作,所以我们可以以Org2组织级别将 demo 的链码定义通过。使用 peer lifecycle chaincode approveformyorg命令通过链码定义:
peer lifecycle chaincode approveformyorg -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --channelID mychannel --name demo --version 2.0 --package-id $NEW_CC_PACKAGE_ID --sequence 2 --tls --cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
# Org1管理员身份运行,通过链码定义
export CORE_PEER_LOCALMSPID="Org1MSP"
export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp
export CORE_PEER_TLS_ROOTCERT_FILE=${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt
export CORE_PEER_ADDRESS=localhost:7051
peer lifecycle chaincode approveformyorg -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --channelID mychannel --name demo --version 2.0 --package-id $NEW_CC_PACKAGE_ID --sequence 2 --tls --cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
# 将链码定义提交给通道,使用peer lifecycle chaincode checkcommitreadiness命令来检查通道成员是否已批准相同的链码定义:
peer lifecycle chaincode checkcommitreadiness --channelID mychannel --name demo --version 2.0 --sequence 2 --tls --cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem --output json
# 升级链码:
peer lifecycle chaincode commit -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --channelID mychannel --name demo --version 2.0 --sequence 2 --tls --cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem --peerAddresses localhost:7051 --tlsRootCertFiles ${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt --peerAddresses localhost:9051 --tlsRootCertFiles ${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt
# 可以使用peer lifecycle chaincode querycommitted命令来确认链码定义已提交给通道。
peer lifecycle chaincode querycommitted --channelID mychannel --name demo --cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem