如何检索要在 corda 中使用的状态

How to retrieve the state to be consumed in corda

我需要在 Corda 中更新一个状态,一旦它被创建。我为此使用 LinearState class,它有一个 UniqueIdentifier 类型的 LinearID 字段。我面临一个问题,即如何将要使用的状态的 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));
        }
 }

谁能帮我解决这个问题?我已经在这里卡了一个多星期了

  • 不要在流的构造函数中使用 UniqueIdentifier 输入参数,而是使用 String
    public UpdateOffer(String linearID...
    
  • 然后在您的流程中您可以这样查询:
    LinearStateQueryCriteria linearCriteria = new LinearStateQueryCriteria()
                        .withExternalId(Collections.singletonList(linearId));
    
  • 由于您的输入参数现在是 String,您可以轻松地从终端传递它。