步骤 :
首先打包chaincode:这个步骤可以由一个组织来完成,也可以由每个组织来完成。
在你的peer中安装chaincode:每个使用chaincode来签署交易或者查询分类账的组织都需要完成这个步骤。批准您的组织的chaincode定义:每个使用chaincode的组织都需要完成这个步骤。在可以在通道上启动chaincode之前,chaincode定义需要得到足够数量的组织的批准,以满足通道的生命周期许可策略(默认情况下是大多数)。将chaincode定义提交给通道:一旦通道上所需的组织数量得到批准,提交事务就需要由一个组织提交。提交者首先从已经批准的组织的足够多的同行那里收集背书,然后提交事务以提交chaincode定义。
//打包
LifecycleChaincodePackage lifecycleChaincodePackage = createLifecycleChaincodePackage(
// replace_label_with_name
chaincodeLabel,
chaincodeType,
Paths.get(System.getenv(REST_CFG_PATH)).toString(),
chaincodePath,
null);
//安装
private String lifecycleInstallChaincode(HFClient client, Collection<Peer> peers, LifecycleChaincodePackage lifecycleChaincodePackage) throws InvalidArgumentException, ProposalException, InvalidProtocolBufferException {
int numInstallProposal = 0;
numInstallProposal = numInstallProposal + peers.size();
LifecycleInstallChaincodeRequest installProposalRequest = client.newLifecycleInstallChaincodeRequest();
installProposalRequest.setLifecycleChaincodePackage(lifecycleChaincodePackage);
installProposalRequest.setProposalWaitTime(1080000);
Collection<LifecycleInstallChaincodeProposalResponse> responses = client.sendLifecycleInstallChaincodeRequest(installProposalRequest, peers);
assertNotNull(responses);
Collection<ProposalResponse> successful = new LinkedList<>();
Collection<ProposalResponse> failed = new LinkedList<>();
String packageID = null;
for (LifecycleInstallChaincodeProposalResponse response : responses) {
if (response.getStatus() == ProposalResponse.Status.SUCCESS) {
log.info("Successful install proposal response Txid: %s from peer %s", response.getTransactionID(), response.getPeer().getName());
successful.add(response);
if (packageID == null) {
packageID = response.getPackageId();
assertNotNull(format("Hashcode came back as null from peer: %s ", response.getPeer()), packageID);
} else {
assertEquals("Miss match on what the peers returned back as the packageID", packageID, response.getPackageId());
}
} else {
failed.add(response);
}
}
// }
log.info(format("Received %d install proposal responses. Successful+verified: %d . Failed: %d", numInstallProposal, successful.size(), failed.size()));
if (failed.size() > 0) {
ProposalResponse first = failed.iterator().next();
log.info("Not enough endorsers for install :" + successful.size() + ". " + first.getMessage());
}
assertNotNull(packageID);
assertFalse(packageID.isEmpty());
return packageID;
}
//查询已安装的链码
private JSONObject verifyNoInstalledChaincodes(HFClient client, Collection<Peer> peers) throws ProposalException, InvalidArgumentException {
JSONObject jsonObject = new JSONObject();
Collection<LifecycleQueryInstalledChaincodesProposalResponse> results = client.sendLifecycleQueryInstalledChaincodes(client.newLifecycleQueryInstalledChaincodesRequest(), peers);
assertNotNull(results);
assertEquals(peers.size(), results.size());
for (LifecycleQueryInstalledChaincodesProposalResponse result : results) {
final String peerName = result.getPeer().getName();
assertEquals(format("Peer returned back bad status %s", peerName), result.getStatus(), ChaincodeResponse.Status.SUCCESS);
log.info(format("Peer returned back bad status %s", peerName), result.getStatus(), ChaincodeResponse.Status.SUCCESS);
Collection<LifecycleQueryInstalledChaincodesProposalResponse.LifecycleQueryInstalledChaincodesResult> lifecycleQueryInstalledChaincodesResult = result.getLifecycleQueryInstalledChaincodesResult();
assertNotNull(format("Peer %s returned back null result.", peerName), lifecycleQueryInstalledChaincodesResult + "");
log.info(format("Peer %s returned back null result.", peerName), lifecycleQueryInstalledChaincodesResult + "");
// assertTrue(format("Peer %s returned back result with chaincode installed.", peerName), lifecycleQueryInstalledChaincodesResult.isEmpty());
log.info(format("Peer %s returned back result with chaincode installed.", peerName), lifecycleQueryInstalledChaincodesResult.isEmpty());
jsonObject.put(peerName, lifecycleQueryInstalledChaincodesResult);
}
return jsonObject;
}
long sequence = getSequence(chaincodeName, client, channel, org1MyPeers);
//Org1 also creates the endorsement policy for the chaincode. // also known as validationParameter !
LifecycleChaincodeEndorsementPolicy chaincodeEndorsementPolicy = LifecycleChaincodeEndorsementPolicy.fromSignaturePolicyYamlFile(Paths.get(System.getenv(REST_CFG_PATH) + "/chaincodeendorsementpolicy.yaml"));
ChaincodeCollectionConfiguration chaincodeConfiguration = ChaincodeCollectionConfiguration.fromYamlFile(new File(System.getenv(REST_CFG_PATH) + "/PrivateDataIT.yaml"));
final Peer anOrg1Peer = org1MyPeers.iterator().next();
log.info("Org1 approving chaincode definition for my org.");
BlockEvent.TransactionEvent transactionEvent = lifecycleApproveChaincodeDefinitionForMyOrg(client, channel,
Collections.singleton(anOrg1Peer), //support approve on multiple peers but really today only need one. Go with minimum.
sequence, chaincodeName, chaincodeVersion, chaincodeEndorsementPolicy, chaincodeConfiguration, false, orgChaincodePackageID)
.get(100100, TimeUnit.SECONDS);
//通过检查提交准备状态进行验证;用于检查有哪些机构同意,有哪些机构还没同意;
private JSONObject verifyByCheckCommitReadinessStatus(HFClient client, Channel channel, long definitionSequence, String chaincodeName,
String chaincodeVersion, LifecycleChaincodeEndorsementPolicy chaincodeEndorsementPolicy,
ChaincodeCollectionConfiguration chaincodeCollectionConfiguration, boolean initRequired, Collection<Peer> org1MyPeers,
) throws InvalidArgumentException, ProposalException {
JSONObject array = new JSONObject();
JSONObject approved = new JSONObject();
JSONObject unApproved = new JSONObject();
LifecycleCheckCommitReadinessRequest lifecycleCheckCommitReadinessRequest = client.newLifecycleSimulateCommitChaincodeDefinitionRequest();
lifecycleCheckCommitReadinessRequest.setSequence(definitionSequence);
lifecycleCheckCommitReadinessRequest.setChaincodeName(chaincodeName);
lifecycleCheckCommitReadinessRequest.setChaincodeVersion(chaincodeVersion);
if (null != chaincodeEndorsementPolicy) {
lifecycleCheckCommitReadinessRequest.setChaincodeEndorsementPolicy(chaincodeEndorsementPolicy);
}
if (null != chaincodeCollectionConfiguration) {
lifecycleCheckCommitReadinessRequest.setChaincodeCollectionConfiguration(chaincodeCollectionConfiguration);
}
lifecycleCheckCommitReadinessRequest.setInitRequired(initRequired);
Collection<LifecycleCheckCommitReadinessProposalResponse> lifecycleSimulateCommitChaincodeDefinitionProposalResponse = channel.sendLifecycleCheckCommitReadinessRequest(lifecycleCheckCommitReadinessRequest, org1MyPeers);
for (LifecycleCheckCommitReadinessProposalResponse resp : lifecycleSimulateCommitChaincodeDefinitionProposalResponse) {
final Peer peer = resp.getPeer();
assertEquals(ChaincodeResponse.Status.SUCCESS, resp.getStatus());
// assertEquals(format("Approved orgs failed on %s", peer), expectedApproved, resp.getApprovedOrgs());
log.info(format("Approved orgs %s on %s", peer, resp.getApprovedOrgs()));
approved.put(peer.getName(), resp.getApprovedOrgs());
//assertEquals(format("UnApproved orgs failed on %s", peer), expectedUnApproved, resp.getUnApprovedOrgs());
log.info(format("UnApproved orgs %s on %s", peer, resp.getUnApprovedOrgs()));
unApproved.put(peer.getName(), resp.getUnApprovedOrgs());
//assertEquals(format("UnApproved orgs failed on %s", peer), expectedUnApproved, resp.getUnApprovedOrgs());
}
array.put("Approved", approved);
array.put("UnApproved", unApproved);
return array;
}
long sequence = getSequence(chaincodeName, client, channel, channel.getPeers());
LifecycleCommitChaincodeDefinitionRequest lifecycleCommitChaincodeDefinitionRequest = client.newLifecycleCommitChaincodeDefinitionRequest();
lifecycleCommitChaincodeDefinitionRequest.setSequence(sequence);
lifecycleCommitChaincodeDefinitionRequest.setChaincodeName(chaincodeName);
lifecycleCommitChaincodeDefinitionRequest.setChaincodeVersion(chaincodeVersion);
LifecycleChaincodeEndorsementPolicy chaincodeEndorsementPolicy = LifecycleChaincodeEndorsementPolicy.fromSignaturePolicyYamlFile(Paths.get(System.getenv(REST_CFG_PATH) + "/chaincodeendorsementpolicy.yaml"));
ChaincodeCollectionConfiguration chaincodeConfiguration = ChaincodeCollectionConfiguration.fromYamlFile(new File(System.getenv(REST_CFG_PATH) + "/PrivateDataIT.yaml"));
if (null != chaincodeEndorsementPolicy) {
lifecycleCommitChaincodeDefinitionRequest.setChaincodeEndorsementPolicy(chaincodeEndorsementPolicy);
}
if (null != chaincodeConfiguration) {
lifecycleCommitChaincodeDefinitionRequest.setChaincodeCollectionConfiguration(chaincodeConfiguration);
}
Collection<Peer> org1MyPeers = channel.getPeers();
Collection<Peer> orgOtherPeers = Util.addOtherOrgPeers(client, channel, peerDomain);
Collection<Peer> endorsingPeers = Arrays.asList(org1MyPeers.iterator().next(), orgOtherPeers.iterator().next());
lifecycleCommitChaincodeDefinitionRequest.setInitRequired(initRequired);
Collection<LifecycleCommitChaincodeDefinitionProposalResponse> lifecycleCommitChaincodeDefinitionProposalResponses = channel.sendLifecycleCommitChaincodeDefinitionProposal(lifecycleCommitChaincodeDefinitionRequest,
endorsingPeers);
for (LifecycleCommitChaincodeDefinitionProposalResponse resp : lifecycleCommitChaincodeDefinitionProposalResponses) {
final Peer peer = resp.getPeer();
//requested sequence is 1, but new definition must be sequence 2
assertEquals(format("%s had unexpected status.", peer.toString()), ChaincodeResponse.Status.SUCCESS, resp.getStatus());
assertTrue(format("%s not verified.", peer.toString()), resp.isVerified());
}
CompletableFuture<BlockEvent.TransactionEvent> transactionEvent = channel.sendTransaction(lifecycleCommitChaincodeDefinitionProposalResponses);
private void verifyByQueryChaincodeDefinition(HFClient client, Channel channel, String chaincodeName, Collection<Peer> peers, long expectedSequence, boolean expectedInitRequired, byte[] expectedValidationParameter,
ChaincodeCollectionConfiguration expectedChaincodeCollectionConfiguration) throws ProposalException, InvalidArgumentException, ChaincodeCollectionConfigurationException {
final QueryLifecycleQueryChaincodeDefinitionRequest queryLifecycleQueryChaincodeDefinitionRequest = client.newQueryLifecycleQueryChaincodeDefinitionRequest();
queryLifecycleQueryChaincodeDefinitionRequest.setChaincodeName(chaincodeName);
Collection<LifecycleQueryChaincodeDefinitionProposalResponse> queryChaincodeDefinitionProposalResponses = channel.lifecycleQueryChaincodeDefinition(queryLifecycleQueryChaincodeDefinitionRequest, peers);
assertNotNull(queryChaincodeDefinitionProposalResponses);
assertEquals(peers.size(), queryChaincodeDefinitionProposalResponses.size());
for (LifecycleQueryChaincodeDefinitionProposalResponse response : queryChaincodeDefinitionProposalResponses) {
assertEquals(ChaincodeResponse.Status.SUCCESS, response.getStatus());
assertEquals(expectedSequence, response.getSequence());
if (expectedValidationParameter != null) {
byte[] validationParameter = response.getValidationParameter();
assertNotNull(validationParameter);
assertArrayEquals(expectedValidationParameter, validationParameter);
}
if (null != expectedChaincodeCollectionConfiguration) {
final ChaincodeCollectionConfiguration chaincodeCollectionConfiguration = response.getChaincodeCollectionConfiguration();
assertNotNull(chaincodeCollectionConfiguration);
assertArrayEquals(expectedChaincodeCollectionConfiguration.getAsBytes(), chaincodeCollectionConfiguration.getAsBytes());
}
ChaincodeCollectionConfiguration collections = response.getChaincodeCollectionConfiguration();
assertEquals(expectedInitRequired, response.getInitRequired());
assertEquals("escc", response.getEndorsementPlugin());
assertEquals("vscc", response.getValidationPlugin());
}
}