#corda
#corda
Вопрос:
Мне нужно обновить состояние в Corda один раз после его создания. Для этого я использую класс LinearState, который имеет поле LinearID типа UniqueIdentifier. Я столкнулся с проблемой, связанной с тем, как передать UniqueIdentifier состояния, которое будет использоваться, конструктору UpdateFlow в терминале узла. Код для моего потока обновлений выглядит следующим образом:
@InitiatingFlow
@StartableByRPC
public static class UpdateOffer extends FlowLogic<SignedTransaction> {
private final ProgressTracker.Step GENERATING_TRANSACTION = new ProgressTracker.Step("Generating transaction.");
private final ProgressTracker.Step ADDING_NEW_OFFER = new ProgressTracker.Step("Adding the New Offer State.");
private final ProgressTracker.Step VERIFYING_TRANSACTION = new ProgressTracker.Step("Verifying contract constraints.");
private final ProgressTracker.Step SIGNING_TRANSACTION = new ProgressTracker.Step("Signing transaction with our private key.");
private final ProgressTracker.Step GATHERING_SIGS = new ProgressTracker.Step("Gathering the counterparty's signature.") {
@Override
public ProgressTracker childProgressTracker() {
return CollectSignaturesFlow.Companion.tracker();
}
};
private final ProgressTracker.Step FINALISING_TRANSACTION = new ProgressTracker.Step("Obtaining notary signature and recording transaction.") {
@Override
public ProgressTracker childProgressTracker() {
return FinalityFlow.Companion.tracker();
}
};
private final ProgressTracker progressTracker = new ProgressTracker(
GENERATING_TRANSACTION,
ADDING_NEW_OFFER,
VERIFYING_TRANSACTION,
SIGNING_TRANSACTION,
GATHERING_SIGS,
FINALISING_TRANSACTION
);
@Override
public ProgressTracker getProgressTracker() {
return progressTracker;
}
//Class Variables
private final UniqueIdentifier linearID;
private final String sender;
private final String receiver;
private final String policyID;
private final double faceValue;
private final double offeredAmount;
public UpdateOffer(UniqueIdentifier linearID, String sender, String receiver, String policyID, double faceValue, double offeredAmount) {
this.linearID = linearID;
this.sender = sender;
this.receiver = receiver;
this.policyID = policyID;
this.faceValue = faceValue;
this.offeredAmount = offeredAmount;
}
@Override
public SignedTransaction call() throws FlowException {
List<UUID> listOfLinearIds = new ArrayList<>();
listOfLinearIds.add(linearID.getId());
QueryCriteria queryCriteria = new QueryCriteria.LinearStateQueryCriteria(null, listOfLinearIds);
// 2. Get a reference to the inputState data that we are going to settle.
Vault.Page results = getServiceHub().getVaultService().queryBy(OfferState.class, queryCriteria);
StateAndRef inputStateAndRefToTransfer = (StateAndRef) results.getStates().get(0);
OfferState inputStateToTransfer = (OfferState) inputStateAndRefToTransfer.getState().getData();
AccountService accountService = getServiceHub().cordaService(KeyManagementBackedAccountService.class);
//Owner Account
AccountInfo lspAccountInfo = accountService.accountInfo(sender).get(0).getState().getData();
PublicKey lspKey = subFlow(new NewKeyForAccount(lspAccountInfo.getIdentifier().getId())).getOwningKey();
AnonymousParty lspAccount = subFlow(new RequestKeyForAccount(lspAccountInfo));
//Insurance Company Account
AccountInfo sellerAccountInfo = accountService.accountInfo(receiver).get(0).getState().getData();
AnonymousParty sellerAccount = subFlow(new RequestKeyForAccount(sellerAccountInfo));
final Party notary = getServiceHub().getNetworkMapCache().getNotaryIdentities().get(0);
final OfferState output = new OfferState(inputStateToTransfer.getLinearId(), lspAccount,sellerAccount,policyID,faceValue,offeredAmount, true);
progressTracker.setCurrentStep(GENERATING_TRANSACTION);
TransactionBuilder builder = new TransactionBuilder(notary);
progressTracker.setCurrentStep(ADDING_NEW_OFFER);
builder.addInputState(inputStateAndRefToTransfer);
builder.addOutputState(output,OfferContract.ID);
builder.addCommand(new OfferContract.Commands.Send(), Arrays.asList(lspKey,sellerAccount.getOwningKey()));
progressTracker.setCurrentStep(SIGNING_TRANSACTION);
builder.verify(getServiceHub());
SignedTransaction locallySignedTx = getServiceHub().signInitialTransaction(builder,Arrays.asList(getOurIdentity().getOwningKey(),lspKey));
progressTracker.setCurrentStep(GATHERING_SIGS);
FlowSession session = initiateFlow(sellerAccountInfo.getHost());
List<TransactionSignature> accountToMoveToSignature = (List<TransactionSignature>) subFlow(new CollectSignatureFlow(locallySignedTx,
session,sellerAccount.getOwningKey()));
SignedTransaction signedByCounterParty = locallySignedTx.withAdditionalSignatures(accountToMoveToSignature);
progressTracker.setCurrentStep(FINALISING_TRANSACTION);
return subFlow(new FinalityFlow(signedByCounterParty, session));
}
}
Кто-нибудь может мне помочь с этим? Я застрял здесь уже больше недели.
Ответ №1:
- Вместо того, чтобы иметь
UniqueIdentifier
входной параметр в конструкторе вашего потока, используйтеString
:public UpdateOffer(String linearID...
- Затем внутри вашего потока вы можете запросить следующим образом:
LinearStateQueryCriteria linearCriteria = new LinearStateQueryCriteria() .withExternalId(Collections.singletonList(linearId));
- Поскольку ваш входной параметр теперь равен a
String
, вы можете легко передать его из терминала.