在Corda中上传和下载包含文本文件的zip附件无效
试图手动附加和下载zip文件,还尝试使用代理通过客户端RPC发送附件。
流代码:
public class IOUFlow extends FlowLogic<Void> {
private final Integer iouValue;
private final Party otherParty;
private final SecureHash attachmentHash;
public IOUFlow(Integer iouValue, Party otherParty,SecureHash attachmentHash) {
this.iouValue = iouValue;
this.otherParty = otherParty;
this.attachmentHash=attachmentHash;
}
@Override
public ProgressTracker getProgressTracker() {
return progressTracker;
}
private static final Step ID_OTHER_NODES = new Step("Identifying other nodes on the network.");
private static final Step SENDING_AND_RECEIVING_DATA = new Step("Sending data between parties.");
private static final Step EXTRACTING_VAULT_STATES = new Step("Extracting states from the vault.");
private static final Step OTHER_TX_COMPONENTS = new Step("Gathering a transaction's other components.");
private static final Step TX_BUILDING = new Step("Building a transaction.");
private static final Step TX_SIGNING = new Step("Signing a transaction.");
private static final Step TX_VERIFICATION = new Step("Verifying a transaction.");
private static final Step SIGS_GATHERING = new Step("Gathering a transaction's signatures.") {
// Wiring up a child progress tracker allows us to see the
// subflow's progress steps in our flow's progress tracker.
@Override
public ProgressTracker childProgressTracker() {
return CollectSignaturesFlow.tracker();
}
};
private static final Step VERIFYING_SIGS = new Step("Verifying a transaction's signatures.");
private static final Step FINALISATION = new Step("Finalising a transaction.") {
@Override
public ProgressTracker childProgressTracker() {
return FinalityFlow.tracker();
}
};
private final ProgressTracker progressTracker = new ProgressTracker(
ID_OTHER_NODES,
SENDING_AND_RECEIVING_DATA,
EXTRACTING_VAULT_STATES,
OTHER_TX_COMPONENTS,
TX_BUILDING,
TX_SIGNING,
TX_VERIFICATION,
SIGS_GATHERING,
FINALISATION
);
@Suspendable
@Override
public Void call() throws FlowException {
progressTracker.setCurrentStep(ID_OTHER_NODES);
// We retrieve the notary identity from the network map.
Party notary = getServiceHub().getNetworkMapCache().getNotaryIdentities().get(0);
progressTracker.setCurrentStep(SENDING_AND_RECEIVING_DATA);
// We create the transaction components.
IOUState outputState = new IOUState(iouValue, getOurIdentity(), otherParty);
List<PublicKey> requiredSigners = Arrays.asList(getOurIdentity().getOwningKey(), otherParty.getOwningKey());
Command command = new Command<>(new IOUContract.Create(), requiredSigners);
TimeWindow ourAfter = TimeWindow.fromOnly(Instant.MIN);
progressTracker.setCurrentStep(TX_BUILDING);
// We create a transaction builder and add the components.
TransactionBuilder txBuilder = new TransactionBuilder(notary)
.addOutputState(outputState, IOUContract.ID)
.addCommand(command)
.addAttachment(attachmentHash);
// Verifying the transaction.
txBuilder.verify(getServiceHub());
progressTracker.setCurrentStep(TX_SIGNING);
// Signing the transaction.
SignedTransaction signedTx = getServiceHub().signInitialTransaction(txBuilder);
// Creating a session with the other party.
FlowSession otherPartySession = initiateFlow(otherParty);
// Obtaining the counterparty's signature.
SignedTransaction fullySignedTx = subFlow(new CollectSignaturesFlow(
signedTx, Arrays.asList(otherPartySession), CollectSignaturesFlow.tracker()));
progressTracker.setCurrentStep(TX_VERIFICATION);
// Finalising the transaction.
subFlow(new FinalityFlow(fullySignedTx, otherPartySession));
return null;
}
}
客户代码:
public class Client {
private static final Logger logger = LoggerFactory.getLogger(Client.class);
public static void main(String[] args) throws Exception {
// Create an RPC connection to the node.
if (args.length != 3) throw new IllegalArgumentException("Usage: Client <node address> <rpc username> <rpc password>");
final NetworkHostAndPort nodeAddress = parse(args[0]);
final String rpcUsername = args[1];
final String rpcPassword = args[2];
final CordaRPCClient client = new CordaRPCClient(nodeAddress);
final CordaRPCOps proxy = client.start(rpcUsername, rpcPassword).getProxy();
// Interact with the node.
// For example, here we print the nodes on the network.
final List<NodeInfo> nodes = proxy.networkMapSnapshot();
logger.info("{}", nodes);
InputStream inputstream = new FileInputStream("corda.zip");
SecureHash hashId= proxy.uploadAttachment(inputstream);
System.out.println(hashId);
CordaX500Name x500Name = CordaX500Name.parse("O=ICICI,L=New York,C=US");
final Party otherParty = proxy.wellKnownPartyFromX500Name(x500Name);
/* proxy
.startFlowDynamic(IOUFlow.class, "10", otherParty,hashId)
.getReturnValue()
.get();*/
InputStream stream = proxy.openAttachment(hashId);
JarInputStream in = new JarInputStream(stream);
BufferedReader br =new BufferedReader(new InputStreamReader(in));
System.out.println("Output from attachment : "+br.readLine());
}
}
输出:
任务:clients:runTemplateClient I 16:36:28 1 RPCClient.logElapsedTime-启动花费了2066毫秒 I 16:36:28 1 Client.main-[NodeInfo(地址= [localhost:10005],legalIdentitiesAndCerts = [O = PNB,L =伦敦,C = GB],platformVersion = 4,序列号= 1559037129874),NodeInfo(地址= [localhost:10002],legalIdentitiesAndCerts = [O =公证人,L =伦敦,C = GB],platformVersion = 4,序列号= 1559037126875),NodeInfo(地址= [localhost:10008],legalIdentitiesAndCerts = [O = ICICI,L =纽约,C = US],platformVersion = 4,序列号= 1559037128218)]
DF3C198E05092E52F47AE8EAA0D5D26721F344B3F5E0DF80B5A53CA2B7104C9C 附件的输出:null
另一个输出:尝试使用RPC从客户端发送附件时
任务:clients:runTemplateClient I 16:41:46 1 RPCClient.logElapsedTime-启动花费了2045毫秒 I 16:41:47 1 Client.main-[NodeInfo(地址= [localhost:10005],legalIdentitiesAndCerts = [O = PNB,L =伦敦,C = GB],platformVersion = 4,序列号= 1559037129874),NodeInfo(地址= [localhost:10002],legalIdentitiesAndCerts = [O =公证人,L =伦敦,C = GB],platformVersion = 4,序列号= 1559037126875),NodeInfo(地址= [localhost:10008],legalIdentitiesAndCerts = [O = ICICI,L =纽约,C = US],platformVersion = 4,序列号= 1559037128218)] B7F5F70FC9086ED594883E6EB8B0B53B666B92CC4412E27FF3D6531446E9E40C 线程“主”中的异常net.corda.core.CordaRuntimeException:net.corda.core.flows.IllegalFlowLogicException:由于缺少参数的构造函数,无法为com.template.flows.IOUFlow类型的FlowLogic构造FlowLogicRef:[class java.lang.String,类net.corda.core.identity.Party,类net.corda.core.crypto.SecureHash $ SHA256]
答案 0 :(得分:1)
A FlowLogicRef cannot be constructed for FlowLogic of type com.template.flows.IOUFlow: due to missing constructor for arguments: [class java.lang.String, class net.corda.core.identity.Party, class net.corda.core.crypto.SecureHash$SHA256]
startFlowDynamic(IOUFlow.class, "10", otherParty,hashId)
您的IOUFlow似乎需要一个整数,而您正在发送一个字符串?
答案 1 :(得分:1)
感谢提出这个问题。这绝对是我们可以改善开发人员体验的东西。
基本上,将附件添加到TX有两个步骤。
SecureHash attachmentHash = getServiceHub().getAttachments().importAttachment(INPUT-FILE, getOurIdentity().getName().toString(), INPUT-FILE.getName());
用Java File实例替换INPUT-FILE。
.addAttachment(attachmentHash);
您可以通过流程逻辑显式地简化第一步,也可以像此处一样使用RPC代理。
对于您列出的第二个错误:
但是,您发布的异常与调用IOUFlow的方式有关。 IOUFlow期望将Integer作为第一个参数,但是我们提供了一个String-这导致IllegalFlowLogicException。尝试提供一个Int或更改IOUFlow以期望将字符串输入转换为Int。