Я следую учебнику Corda , чтобы создать приложение Corda. Вместо того, чтобы создавать его в Kotlin, я встроил его в Java.
Я следовал инструкциям, приведенным в do c, и ниже мой класс CarIssueInitiator.
package com.template.flows;
import co.paralleluniverse.fibers.Suspendable;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.template.contracts.CarContract;
import com.template.states.CarState;
import net.corda.core.contracts.Command;
import net.corda.core.contracts.UniqueIdentifier;
import net.corda.core.flows.*;
import net.corda.core.identity.Party;
import net.corda.core.transactions.SignedTransaction;
import net.corda.core.transactions.TransactionBuilder;
import net.corda.core.utilities.ProgressTracker;
import net.corda.core.utilities.ProgressTracker.Step;
import java.util.List;
import java.util.stream.Collectors;
// ******************
// * Initiator flow *
// ******************
@InitiatingFlow
@StartableByRPC
public class CarIssueInitiator extends FlowLogic<SignedTransaction> {
private final Party owningBank;
private final Party holdingDealer;
private final Party manufacturer;
private final String vin;
private final String licensePlateNumber;
private final String make;
private final String model;
private final String dealershipLocation;
private final Step GENERATING_TRANSACTION = new Step("Generating transaction based on new IOU.");
private final Step VERIFYING_TRANSACTION = new Step("Verifying contract constraints.");
private final Step SIGNING_TRANSACTION = new Step("Signing transaction with our private key.");
private final Step GATHERING_SIGS = new Step("Gathering the counterparty's signature.") {
@Override
public ProgressTracker childProgressTracker() {
return CollectSignaturesFlow.Companion.tracker();
}
};
private final Step FINALISING_TRANSACTION = new Step("Obtaining notary signature and recording transaction.") {
@Override
public ProgressTracker childProgressTracker() {
return FinalityFlow.Companion.tracker();
}
};
private final ProgressTracker progressTracker = new ProgressTracker(
GENERATING_TRANSACTION,
VERIFYING_TRANSACTION,
SIGNING_TRANSACTION,
GATHERING_SIGS,
FINALISING_TRANSACTION
);
public CarIssueInitiator(Party owningBank,
Party holdingDealer,
Party manufacturer,
String vin,
String licensePlateNumber,
String make,
String model,
String dealershipLocation){
this.owningBank = owningBank;
this.holdingDealer = holdingDealer;
this.manufacturer = manufacturer;
this.vin = vin;
this.licensePlateNumber = licensePlateNumber;
this.make = make;
this.model = model;
this.dealershipLocation = dealershipLocation;
}
@Override
public ProgressTracker getProgressTracker() {
return progressTracker;
}
@Suspendable
@Override
public SignedTransaction call() throws FlowException {
// Initiator flow logic goes here.
final Party notary = getServiceHub().getNetworkMapCache().getNotaryIdentities().get(0);
// Stage 1.
progressTracker.setCurrentStep(GENERATING_TRANSACTION);
// Generate an unsigned transaction.
Party me = getOurIdentity();
CarState carState = new CarState(this.owningBank,
this.holdingDealer,
this.manufacturer,
this.vin,
this.licensePlateNumber,
this.make,
this.model,
this.dealershipLocation,
new UniqueIdentifier());
final Command<CarContract.Commands.Issue> txCommand = new Command<CarContract.Commands.Issue>(new CarContract.Commands.Issue(),
ImmutableList.of(carState.getOwningBank().getOwningKey(), carState.getHoldingDealer().getOwningKey(), carState.getManufacturer().getOwningKey()));
final TransactionBuilder txBuilder = new TransactionBuilder(notary)
.addOutputState(carState, CarContract.ID)
.addCommand(txCommand);
// Stage 2.
progressTracker.setCurrentStep(VERIFYING_TRANSACTION);
// Verify that the transaction is valid.
txBuilder.verify(getServiceHub());
//Stage 3
progressTracker.setCurrentStep(SIGNING_TRANSACTION);
// Sign the transaction.
final SignedTransaction partSignedTx = getServiceHub().signInitialTransaction(txBuilder);
// Stage 4.
progressTracker.setCurrentStep(GATHERING_SIGS);
// Send the state to the counterparty, and receive it back with their signature.
List<FlowSession> sessions = carState.getParticipants().stream().map(a -> initiateFlow((Destination) a)).collect(Collectors.toList());
//FlowSession session = initiateFlow(me);
final SignedTransaction fullySignedTx = subFlow(
new CollectSignaturesFlow(partSignedTx, sessions, ImmutableList.of(me.getOwningKey()), CollectSignaturesFlow.Companion.tracker()));
// Stage 5.
progressTracker.setCurrentStep(FINALISING_TRANSACTION);
return subFlow(new FinalityFlow(fullySignedTx, sessions));
}
}
Я развернул CordApp и запустил поток. Но я закончил с ошибкой ниже
java.lang.IllegalArgumentException: The Initiator of CollectSignaturesFlow must pass in exactly the sessions required to sign the transaction.
at net.corda.core.flows.CollectSignaturesFlow.call(CollectSignaturesFlow.kt:164) ~[corda-core-4.3.jar:?]
at net.corda.core.flows.CollectSignaturesFlow.call(CollectSignaturesFlow.kt:67) ~[corda-core-4.3.jar:?]
at net.corda.node.services.statemachine.FlowStateMachineImpl.subFlow(FlowStateMachineImpl.kt:330) ~[corda-node-4.3.jar:?]
at net.corda.core.flows.FlowLogic.subFlow(FlowLogic.kt:326) ~[corda-core-4.3.jar:?]
at com.template.flows.CarIssueInitiator.call(CarIssueInitiator.java:129) ~[?:?]
at com.template.flows.CarIssueInitiator.call(CarIssueInitiator.java:23) ~[?:?]
at net.corda.node.services.statemachine.FlowStateMachineImpl.run(FlowStateMachineImpl.kt:270) ~[corda-node-4.3.jar:?]
at net.corda.node.services.statemachine.FlowStateMachineImpl.run(FlowStateMachineImpl.kt:46) ~[corda-node-4.3.jar:?]
at co.paralleluniverse.fibers.Fiber.run1(Fiber.java:1092) ~[quasar-core-0.7.10-jdk8.jar:0.7.10]
at co.paralleluniverse.fibers.Fiber.exec(Fiber.java:788) ~[quasar-core-0.7.10-jdk8.jar:0.7.10]
at co.paralleluniverse.fibers.RunnableFiberTask.doExec(RunnableFiberTask.java:100) ~[quasar-core-0.7.10-jdk8.jar:0.7.10]
at co.paralleluniverse.fibers.RunnableFiberTask.run(RunnableFiberTask.java:91) ~[quasar-core-0.7.10-jdk8.jar:0.7.10]
at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source) ~[?:1.8.0_192]
at java.util.concurrent.FutureTask.run(Unknown Source) ~[?:1.8.0_192]
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(Unknown Source) ~[?:1.8.0_192]
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(Unknown Source) ~[?:1.8.0_192]
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) ~[?:1.8.0_192]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) ~[?:1.8.0_192]
at net.corda.node.utilities.AffinityExecutor$ServiceAffinityExecutor$1$thread$1.run(AffinityExecutor.kt:63) ~[corda-node-4.3.jar:?]
Я не понимаю, что не так с кодом. Прошу вас, пожалуйста, помогите мне с этим.
ОБНОВЛЕНИЕ : с обновленным кодом, он работает для меня.
//Stage 3
progressTracker.setCurrentStep(SIGNING_TRANSACTION);
// Sign the transaction.
final PublicKey ourSigningKey = getServiceHub().getMyInfo().getLegalIdentities().get(0).getOwningKey();
final SignedTransaction partSignedTx = getServiceHub().signInitialTransaction(txBuilder, ourSigningKey);
// Stage 4.
progressTracker.setCurrentStep(GATHERING_SIGS);
// Send the state to the counterparty, and receive it back with their signature.
FlowSession HoldingDealerPartyFlow = initiateFlow(carState.getHoldingDealer());
FlowSession ManufacturerPartyFlow = initiateFlow(carState.getManufacturer());
final SignedTransaction fullySignedTx = subFlow(new CollectSignaturesFlow(
partSignedTx,
ImmutableSet.of(HoldingDealerPartyFlow, ManufacturerPartyFlow),
ImmutableList.of(ourSigningKey))
);
// Stage 5.
progressTracker.setCurrentStep(FINALISING_TRANSACTION);
return subFlow(new FinalityFlow(fullySignedTx, ImmutableSet.of(HoldingDealerPartyFlow, ManufacturerPartyFlow)));