Как получить состояние, которое будет использоваться в corda

#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 , вы можете легко передать его из терминала.