时间:20200309:2157
链码准备
存储私有数据链码
private Response putPrivateRecord(ChaincodeStub stub, List<String> args){
int argsNeeded = 3;
if (args.size() != argsNeeded){
return newErrorResponse("Incorrect number of arguments.Got" + args.size() + ", Expecting " + argsNeeded);
}
String uuid = args.get(0);
String jsonStr = args.get(1);
String collection = args.get(2);
stub.putPrivateData(collection, uuid, jsonStr);
return newSuccessResponse("Invoke finished successfully.");
}
读取私有数据链码
private Response getPrivateRecordByKey(ChaincodeStub stub, List<String> args) {
int argsNeeded = 2;
if (args.size() != argsNeeded){
return newErrorResponse("Incorrect number of arguments.Got" + args.size() + ", Expecting " + argsNeeded);
}
String key = args.get(0);
String collection = args.get(1);
byte[] val = stub.getPrivateData(collection, key);
if (val == null) {
return newErrorResponse(String.format("Error: state for %s is null", key));
}
String message = "Query key->\"" + key + "\" successfully";
return newSuccessResponse(message, val);
}
参数说明:存储与读取私有数据时的 collection
即定义私有数据的 name
属性
定义私有数据
要想使用私有数据,首先是定义私有数据
私有数据的 yaml
格式定义如下,解释如下
- StaticCollectionConfig: # protobuf oneof identifies type. At this time the only option.
name: "COLLECTION_FOR_A"
blockToLive: 9999
maximumPeerCount: 0
requiredPeerCount: 0
SignaturePolicyEnvelope:
identities:
- user1: {"role": {"name": "member", "mspId": "OrgA"}} #name can be: member, admin, client, or peer
- user2: {"role": {"name": "member", "mspId": "OrgB"}}
policy:
1-of: # must be signed by at least one of these (OR) can be 2-of for both (AND).
- signed-by: "user1" #reference to user1 in identities section must sign
- signed-by: "user2" #reference to user2 in identities section must sign
- StaticCollectionConfig:
name: "COLLECTION_FOR_C"
blockToLive: 9999
maximumPeerCount: 0
requiredPeerCount: 0
SignaturePolicyEnvelope:
identities:
- user1: {"role": {"name": "member", "mspId": "OrgC"}}
# - user2: {"role": {"name": "member", "mspId": "OrgB"}}
policy:
1-of:
- signed-by: "user1"
# - signed-by: "user2"
name
:私有数据的名字,自定义
blockToLive
:以块为单位,指定隐私数据再side数据库的存活时间,隐私数据在指定的块上保留,此后将被清除,从而在链上删除隐私数据,无法通过链码查询,也无法在节点上得到隐私数据,如果想无限期地保留隐私数据,可将blockToLive属性设置成0。
maximumPeerCount
:背书节点分发私有数据给peer的最大数量。如果设置成0,则所有具有隐私数据权限的节点,会在交易commit时,从授权节点拉取数据。
requiredPeerCount
:背书节点必须成功分发隐私数据给peer的最小数量,当小于这个值时,交易失败。确保了当背书节点不可用,私有数据也可以正常使用。requiredPeerCout设置成0,当背书节点不可用,隐私数据会丢失。
SignaturePolicyEnvelope
:定义私有数据属于那些组织或节点
java SDK 安装链码
在定义生成交易信息 transactionProposalRequest
时,需做如下定义
Map<String, byte[]> transientMap = new HashMap<>();
// transent 传递加密数据 (必须设置)
transientMap.put("key", "yourprivatekey".getBytes(UTF_8));
try {
transactionProposalRequest.setTransientMap(transientMap); // transent 传递加密数据 tmap.put("key", "yourprivatekey".getBytes());
} catch (InvalidArgumentException e) {
e.printStackTrace();
}
在实例化链码时需做如下定义
// 定义私有数据
ChaincodeCollectionConfiguration chaincodeCollectionConfiguration = null;
try {
File privateFile = new File("PrivateDataIT.yaml");
chaincodeCollectionConfiguration = ChaincodeCollectionConfiguration.fromYamlFile(privateFile);
} catch (ChaincodeCollectionConfigurationException e) {
e.printStackTrace();
}
instantiateProposalRequest.setChaincodeCollectionConfiguration(chaincodeCollectionConfiguration);