Warm tip: This article is reproduced from serverfault.com, please click

blockchain-检索corda中的特定状态

(blockchain - Retrieving a specific state in corda)

发布于 2020-11-12 06:14:25

在My Corda项目中,我需要根据状态类的某些特定字段检索特定状态,我为每个状态设置了Unique。在Corda中如何做?执行状态如下:

@BelongsToContract(OfferContract.class)
public class OfferState implements LinearState {
    private final UniqueIdentifier linearID;
    private AnonymousParty sender;
    private AnonymousParty receiver;
    private final String policyID;
    private final double faceValue;
    private double offeredAmount;

    private boolean isActive;

    public OfferState(UniqueIdentifier linearID, AnonymousParty sender, AnonymousParty receiver, String policyID, double faceValue, double offeredAmount, boolean isActive) {
        this.linearID = linearID;
        this.sender = sender;
        this.receiver = receiver;
        this.policyID = policyID;
        this.faceValue = faceValue;
        this.offeredAmount = offeredAmount;
        this.isActive = isActive;
    }

    public UniqueIdentifier getLinearID() {
        return linearID;
    }

    public AnonymousParty getSender() {
        return sender;
    }

    public AnonymousParty getReceiver() {
        return receiver;
    }

    public String getPolicyID() {
        return policyID;
    }

    public double getFaceValue() {
        return faceValue;
    }

    public double getOfferedAmount() {
        return offeredAmount;
    }

    public boolean isActive() {
        return isActive;
    }

    @NotNull
    @Override
    public UniqueIdentifier getLinearId() {
        return linearID;
    }

    @NotNull
    @Override
    public List<AbstractParty> getParticipants() {
        return Arrays.asList(sender,receiver);
    }

    @Override
    public String toString() {
        return super.toString();
    }
}

我正在使用以下代码在API中进行查询,但是,在 Postman 输出中显示了[]之类的空括号。

@GetMapping(value = "/getOfferWithID",headers = "Content-Type=application/x-www-form-urlencoded")
    private List<StateAndRef<OfferState>> getOfferWithID(HttpServletRequest request) throws IllegalArgumentException {
        String s  = request.getParameter("PolicyID");
        return proxy.vaultQuery(OfferState.class).getStates().stream().filter(it->it.getState().getData().getPolicyID().equalsIgnoreCase(s)).collect(Collectors.toList());
    }

你能告诉我,如何在查询时过滤状态,这是怎么回事?是否有任何直接查询方法,以便我可以在rpc调用本身中对其进行过滤,或者我真的需要为此编写流程吗?

Questioner
Vishwa Dayal
Viewed
0
Adel Rustum 2020-12-04 04:43:46

为了能够通过状态之一来查询状态,你必须:

  • 为你的状态创建自定义架构,请参见此处此处的示例。
  • 使用VaultCustomQueryCriteria来对你的属性查询policyIdVaultCustomQueryCriteria 这里阅读(搜索该术语,并查找示例代码)。

你当前的方法(使用.filter(it->it.getState().getData().getPolicyID().equalsIgnoreCase(s)))非常糟糕,本质上是要带出所有状态的列表,然后过滤该列表。
当查询返回1000,000个状态时,你将怎么办?你正在创建1000,000个条目的列表,然后在该列表中循环查找包含你的policyId!!!的一条记录这只会耗尽Java Heap,降低应用程序的速度并使其崩溃。

始终通过在Corda中构造查询然后在数据库中运行查询(使用我已经概述的方法)来将搜索/查询委托给数据库,你当前正在做的是制作一个select * from some_table然后遍历所有结果的方法,我的方法Crafts select * from some_table where policyId = xxx,将返回一行。