首页 > 解决方案 > 序列化失败方向=“反序列化”,corda

问题描述

这是我在运行我的 Corda 发起程序流时遇到的错误。

amqp.DeserializationInput. - Serialization failed direction="Deserialize", 
type="net.corda.core.contracts.Amount", msg="Described type with descriptor 
net.corda:7mttgXO2HdBLwATyV7pCpg== was expected to be of type class 
net.corda.core.contracts.Amount but was class net.corda.core.transactions.SignedTransaction

当我检查启动器节点日志时,它显示 java.lang.IllegalArgumentException: Payload invalid

我使用的 Corda 版本是 4.4。
代币版本:1.2。
账户版本:1.0.2

运行时,未创建帐户,不会引发此类错误。

发起人流程:

public class InitiateTicketMovementFlow extends FlowLogic<String> {
    private final String buyer;
    private final String issuer;
    private final StateRef assetReference;

public InitiateTicketMovementFlow(String buyer, String issuer, String hash, int index) {
    this.buyer = buyer;
    this.issuer = issuer;
    this.assetReference = new StateRef(SecureHash.parse(hash), index);
}

@Override
@Suspendable
public String call() throws FlowException {

    final Party notary = getServiceHub().getNetworkMapCache().getNotaryIdentities().get(0);

    AccountInfo issuerAccountInfo = UtilitiesKt.getAccountService(this)
            .accountInfo(issuer).get(0).getState().getData();

    AnonymousParty issuerAccount = subFlow(new RequestKeyForAccount(issuerAccountInfo));

    AccountInfo receiverAccountInfo = UtilitiesKt.getAccountService(this)
            .accountInfo(buyer).get(0).getState().getData();

    AnonymousParty buyerAccount = subFlow(new RequestKeyForAccount(receiverAccountInfo));

    QueryCriteria.VaultQueryCriteria queryCriteria = new QueryCriteria.VaultQueryCriteria()
            .withStateRefs(ImmutableList.of(assetReference));

    StateAndRef<CustomTicket> ticketStateStateAndRef = getServiceHub().getVaultService()
            .queryBy(CustomTicket.class, queryCriteria).getStates().get(0);

    CustomTicket ticketState = ticketStateStateAndRef.getState().getData();

    TransactionBuilder txBuilder = new TransactionBuilder(notary);

    MoveTokensUtilities.addMoveNonFungibleTokens(txBuilder, getServiceHub(),
            ticketState.toPointer(CustomTicket.class), receiverAccountInfo.getHost());

    FlowSession buyerSession = initiateFlow(receiverAccountInfo.getHost());
            buyerSession.send(ticketState.getValuation());

    List<StateAndRef<FungibleToken>> inputs = subFlow(new ReceiveStateAndRefFlow<>(buyerSession));
    
    List<FungibleToken> moneyReceived = buyerSession.receive(List.class).unwrap(value -> value);

    MoveTokensUtilities.addMoveTokens(txBuilder, inputs, moneyReceived);

    SignedTransaction selfSignedTransaction = getServiceHub()
            .signInitialTransaction(txBuilder, ImmutableList.of(issuerAccountInfo.getHost().getOwningKey()));

    SignedTransaction signedTransaction = subFlow(new CollectSignaturesFlow(
            selfSignedTransaction, ImmutableList.of(buyerSession, initiateFlow(issuerAccountInfo.getHost())), Collections.singleton(issuerAccountInfo.getHost().getOwningKey())));

    SignedTransaction stx = subFlow(new FinalityFlow(
            signedTransaction, ImmutableList.of(buyerSession)));
    subFlow(new UpdateDistributionListFlow(stx));

    return "\nTicket is sold to "+ buyer;
    }
}

接收器流:

public class ResponderTicketFlow extends FlowLogic<SignedTransaction> {
private final FlowSession otherPartySession;

public ResponderTicketFlow(FlowSession otherPartySession) {
    this.otherPartySession = otherPartySession;
}

@Override
@Suspendable
public SignedTransaction call() throws FlowException {

    Amount<Currency> price =  otherPartySession.receive(Amount.class).unwrap(amount -> amount);

    Amount<TokenType> priceToken = new Amount<>(price.getQuantity(),
            FiatCurrency.Companion.getInstance(price.getToken().getCurrencyCode()));

    PartyAndAmount<TokenType> partyAndAmount = new PartyAndAmount<>(otherPartySession.getCounterparty(), priceToken);

    Selector selector = new DatabaseTokenSelection(getServiceHub());

    Pair<List<StateAndRef<FungibleToken>>, List<FungibleToken>> inputsAndOutputs = selector
                    .generateMove(Collections.singletonList(new Pair<>(otherPartySession.getCounterparty(), priceToken)), getOurIdentity());

    subFlow(new SendStateAndRefFlow(otherPartySession, inputsAndOutputs.getFirst()));
    otherPartySession.send(inputsAndOutputs.getSecond());

    subFlow(new SignTransactionFlow(otherPartySession) {
        @Override
        protected void checkTransaction(@NotNull SignedTransaction stx) throws FlowException {
            // Custom Logic to validate transaction.
        }
    });
    return subFlow(new ReceiveFinalityFlow(otherPartySession));
   }
}

任何想法?

标签: corda

解决方案


正如 Alessandro 所说,我会查看其他 stackoverflow 问题,因为可能会发现您的应用程序出了什么问题。

另一件需要注意的可能会导致序列化问题的事情是,当您在已添加到 Corda 状态的类上没有 @CordaSerializable 指令时。

因此,如果您的状态使用自定义 java 类,或者您的类上没有正确的标记,则当 corda 尝试解包您的对象时可能会导致问题。请注意此 Corda 状态下的“ConstructorForDeserialization”。

例如:

@ConstructorForDeserialization
private IOUState(Amount<Currency> amount, Party lender, Party borrower, Amount<Currency> paid, UniqueIdentifier linearId){
    this.amount = amount;
    this.lender = lender;
    this.borrower = borrower;
    this.paid = paid;
    this.linearId = linearId;
}

来源:https ://github.com/corda/samples-java/blob/master/Advanced/obligation-cordapp/contracts/src/main/java/net/corda/samples/obligation/states/IOUState.java#L34


推荐阅读