Насколько я знаю, полезная нагрузка ProposalResponse может быть получена из класса TransactionActionInfo и возвращает массив byte [], который может быть декодирован с помощью служебного метода.
void blockWalker(Channel channel) throws InvalidArgumentException, ProposalException, IOException {
try {
BlockchainInfo channelInfo = channel.queryBlockchainInfo();
for (long current = channelInfo.getHeight() - 1; current > -1; --current) {
BlockInfo returnedBlock = channel.queryBlockByNumber(current);
final long blockNumber = returnedBlock.getBlockNumber();
out("current block number %d has data hash: %s", blockNumber, Hex.encodeHexString(returnedBlock.getDataHash()));
out("current block number %d has previous hash id: %s", blockNumber, Hex.encodeHexString(returnedBlock.getPreviousHash()));
out("current block number %d has calculated block hash is %s", blockNumber, Hex.encodeHexString(SDKUtils.calculateBlockHash(blockNumber, returnedBlock.getPreviousHash(), returnedBlock.getDataHash())));
final int envelopCount = returnedBlock.getEnvelopCount();
assertEquals(1, envelopCount);
out("current block number %d has %d envelope count:", blockNumber, returnedBlock.getEnvelopCount());
int i = 0;
for (BlockInfo.EnvelopeInfo envelopeInfo : returnedBlock.getEnvelopeInfos()) {
++i;
out(" Transaction number %d has transaction id: %s", i, envelopeInfo.getTransactionID());
final String channelId = envelopeInfo.getChannelId();
out(" Transaction number %d has channel id: %s", i, channelId);
out(" Transaction number %d has epoch: %d", i, envelopeInfo.getEpoch());
out(" Transaction number %d has transaction timestamp: %tB %<te, %<tY %<tT %<Tp", i, envelopeInfo.getTimestamp());
out(" Transaction number %d has type id: %s", i, "" + envelopeInfo.getType());
if (envelopeInfo.getType() == TRANSACTION_ENVELOPE) {
BlockInfo.TransactionEnvelopeInfo transactionEnvelopeInfo = (BlockInfo.TransactionEnvelopeInfo) envelopeInfo;
out(" Transaction number %d has %d actions", i, transactionEnvelopeInfo.getTransactionActionInfoCount());
out(" Transaction number %d isValid %b", i, transactionEnvelopeInfo.isValid());
out(" Transaction number %d validation code %d", i, transactionEnvelopeInfo.getValidationCode());
int j = 0;
for (BlockInfo.TransactionEnvelopeInfo.TransactionActionInfo transactionActionInfo : transactionEnvelopeInfo.getTransactionActionInfos()) {
++j;
out(" Transaction action %d has response status %d", j, transactionActionInfo.getResponseStatus());
out(" Transaction action %d has response message bytes as string: %s", j,
printableString(new String(transactionActionInfo.getResponseMessageBytes(), "UTF-8")));
out(" Transaction action %d has %d endorsements", j, transactionActionInfo.getEndorsementsCount());
for (int n = 0; n < transactionActionInfo.getEndorsementsCount(); ++n) {
BlockInfo.EndorserInfo endorserInfo = transactionActionInfo.getEndorsementInfo(n);
out("Endorser %d signature: %s", n, Hex.encodeHexString(endorserInfo.getSignature()));
out("Endorser %d endorser: %s", n, new String(endorserInfo.getEndorser(), "UTF-8"));
}
out(" Transaction action %d has %d chaincode input arguments", j, transactionActionInfo.getChaincodeInputArgsCount());
for (int z = 0; z < transactionActionInfo.getChaincodeInputArgsCount(); ++z) {
out(" Transaction action %d has chaincode input argument %d is: %s", j, z,
printableString(new String(transactionActionInfo.getChaincodeInputArgs(z), "UTF-8")));
}
out(" Transaction action %d proposal response status: %d", j,
transactionActionInfo.getProposalResponseStatus());
out(" Transaction action %d proposal response payload: %s", j,
printableString(new String(transactionActionInfo.getProposalResponsePayload())));
TxReadWriteSetInfo rwsetInfo = transactionActionInfo.getTxReadWriteSet();
if (null != rwsetInfo) {
out(" Transaction action %d has %d name space read write sets", j, rwsetInfo.getNsRwsetCount());
for (TxReadWriteSetInfo.NsRwsetInfo nsRwsetInfo : rwsetInfo.getNsRwsetInfos()) {
final String namespace = nsRwsetInfo.getNaamespace();
KvRwset.KVRWSet rws = nsRwsetInfo.getRwset();
int rs = -1;
for (KvRwset.KVRead readList : rws.getReadsList()) {
rs++;
out(" Namespace %s read set %d key %s version [%d:%d]", namespace, rs, readList.getKey(),
readList.getVersion().getBlockNum(), readList.getVersion().getTxNum());
if ("bar".equals(channelId) && blockNumber == 2) {
if ("example_cc_go".equals(namespace)) {
if (rs == 0) {
assertEquals("a", readList.getKey());
assertEquals(1, readList.getVersion().getBlockNum());
assertEquals(0, readList.getVersion().getTxNum());
} else if (rs == 1) {
assertEquals("b", readList.getKey());
assertEquals(1, readList.getVersion().getBlockNum());
assertEquals(0, readList.getVersion().getTxNum());
} else {
fail(format("unexpected readset %d", rs));
}
TX_EXPECTED.remove("readset1");
}
}
}
rs = -1;
for (KvRwset.KVWrite writeList : rws.getWritesList()) {
rs++;
String valAsString = printableString(new String(writeList.getValue().toByteArray(), "UTF-8"));
out(" Namespace %s write set %d key %s has value '%s' ", namespace, rs,
writeList.getKey(),
valAsString);
if ("bar".equals(channelId) && blockNumber == 2) {
if (rs == 0) {
assertEquals("a", writeList.getKey());
assertEquals("400", valAsString);
} else if (rs == 1) {
assertEquals("b", writeList.getKey());
assertEquals("400", valAsString);
} else {
fail(format("unexpected writeset %d", rs));
}
TX_EXPECTED.remove("writeset1");
}
}
}
}
}
}
}
}
if (!TX_EXPECTED.isEmpty()) {
// fail(TX_EXPECTED.get(0));
}
} catch (InvalidProtocolBufferRuntimeException e) {
throw e.getCause();
}
}
Метод служебной программы printableString ()
static String printableString(final String string) {
int maxLogStringLength = 10000;
if (string == null || string.length() == 0) {
return string;
}
String ret = string.replaceAll("[^\\p{Print}]", "\n");
ret = ret.substring(0, Math.min(ret.length(), maxLogStringLength)) + (ret.length() > maxLogStringLength ? "..." : "");
return ret;
}