區塊鏈開發之Corda訓練營筆記12:Flow習題答案

一、IOUIssueFlow

1、類的成員與構造器

flow是用來定義tx的流轉過程的,用來新建tx,而後交給須要的人進行簽名,這只是第一步用來生成flow,最關鍵的仍是新建flow,來進行會話java

首先咱們先進行聲明,它擴展了抽象類flowLogic:網絡

kjkjpublic class IOUIssueFlow extends FlowLogic<SignedTransaction>

若是我如今想issue一個債券,須要指定給定、多少錢,爲何沒有issuer,就是誰調用它誰就是issuer?session

債券是幹嗎的?就是表示你欠我多少嘛,就是指定owner欠issuer多少錢,那麼響應flow的那個class是幹嗎的?ide

因此咱們能夠指定欠錢的人和欠的錢函數

private final Party owner;
private final int amunt;

而後是構造器:區塊鏈

public IOUIssueFlow(Party owner, int amount) {
        this.owner = owner;UIssueFlow
1、類的成員與構造器
flow是用來定義tx的流轉過程的,用來新建tx,而後交給須要的人進行簽名,這只是第一步用來生成flow,最關鍵的仍是新建flow,來進行會話

首先咱們先進行聲明,它擴展了抽象類flowLogic:


kjkjpublic class IOUIssueFlow extends FlowLogic<SignedTransaction> 
若是我如今想issue一個債券,須要指定給定、多少錢,爲何沒有issuer,就是誰調用它誰就是issuer?

債券是幹嗎的?就是表示你欠我多少嘛,就是指定owner欠issuer多少錢,那麼響應flow的那個class是幹嗎的?

因此咱們能夠指定欠錢的人和欠的錢


private final Party owner;
private final int amunt;
而後是構造器:


        this.amount = amount;
    }

這個類總共有三個數據成員,第三個就是一個progressTrackerui

private final ProgressTracker progressTracker = new ProgressTracker();

它不用用戶去指定,用戶不知道這些東西,你也不可能要求懂這些底層的東西!可是他有get方法this

@Override
public ProgressTracker getProgressTracker() {
    return progressTracker;
}

2、class()方法

咱們擴展了flowLogic類,這個類最重要的就是call方法,下面是這個函數的聲明google

@Suspendable
@Override
public signedTransaction call() throws FlowException

接下來是分爲三大步:debug

  1. 新建state
    • 將state及其contract加入到tx中去
    • notrary須要放在outputState以前
  2. 新建tx
    • 將command加入到tx中去
  3. tx的流轉

I、新建state

此外咱們還須要依靠公證人達成共識

Party issuer = getOurIdentity();

接下來是第一步,創建state:

一個iou須要issuer,誰啓動這個流、誰就是issuer,流也是由party啓動的!

IOUState iouState = new IOUState(issuer, owner, amount);
IOUContract.Commands.Issue command = new IOUContract.Commands.Issue();

II、新建tx

我我的感受,從便於理解的角度,整個corda,乃至全部的區塊鏈網絡,都是以tx爲核心的。

corda中的tx須要這些東西:

  • 公證人
  • 輸入輸出的state
  • 檢驗命令的contract的引用
  • 命令及其簽名者
Party notrary = getServiceHub().getNetworkMapCache().getNotraryIdentities(0);
tx.setNotrary(notrary);
notrary.setOutputState(iouState, IOUContact.ID);
List<PublicKey> requiredSigner = ImmutableList.of(IOUState.getIssuer().getOwingKey());
tx.addCommnad(command,requiredSigner);

III、發送流更新帳本

大體分爲如下幾步:

  • 經過servicehub來驗證tx
  • 新建一個會話
  • 將tx簽名認證
  • (————————————————————前方高能——————————————)
  • 這應該就開始和responder進行交互

徹底簽名的tx的意思是否是須要其餘方面的簽名以後的,因此咱們須要創建子流和其餘節點進行交互,

因此須要收前面全部簽名的流+會話,

最後返回的用徹底簽名流+單例會話造成的新的終止子流

等等,這張圖是否是就是前面那張圖的總結????????頗有可能啊!!!我只要能弄懂應答流的程序&這個流的交換過程&讀讀文獻我可能就打通了整個corda了!

根據contract驗證tx的合法性

txBuidler.verify(getServiceHub())

生成流會話

Flow Session = initiateFlow(owner);

用私鑰簽署這個交易讓它不可改變了

SignedTransaction signedTransaction = getSeriveHub().signInitialTransaction(txBuilder);

二、IOUIssueFlowResponder

2.一、類的聲明與構造器

做爲被啓動流,它必須打上註釋:

@InitiatedBy(IOUIssueFlow.class)

該類擴展flowLogic,返回的call的類型是Void

public class IOUIssueFlowResponder extends FlowLogic<Void> {
    
    @Override
    @Suspendable
    public Void call() throws Exception {
        
    }
}

它只有一個私有成員,就是另外一邊發來的會話?

private final FlowSession otherSide

而後Alt + Insert生成構造器

public IOUIssuerFlowResponder(FlowSession otherSide) {
    this.other = otherSide
}

2.2 call()方法

說來也奇怪,這個call方法我徹底看不懂嘞、、、

首先是生成一個stx,生成的方法是subFlow、、,subFlow就是調用子流的意思,一旦子流和它裏面的call方法完成,生成結果就調用它唄

/*
*
*/
@Suspendable
    @Throws(FlowException::class)
    open fun <R> subFlow(subLogic: FlowLogic<R>): R {
        subLogic.stateMachine = stateMachine
        maybeWireUpProgressTracking(subLogic)
        logger.debug { "Calling subflow: $subLogic" }
        val result = stateMachine.subFlow(subLogic)
        logger.debug { "Subflow finished with result ${result.toString().abbreviate(300)}" }
        return result
    }

傳進去的也是flowLogic

三、完整代碼

3.1 IOUIssueFlow

package bootcamp;

import co.paralleluniverse.fibers.Suspendable;
import com.google.common.collect.ImmutableList;
import net.corda.core.flows.*;
import net.corda.core.identity.Party;
import net.corda.core.transactions.SignedTransaction;
import net.corda.core.transactions.TransactionBuilder;
import net.corda.core.utilities.ProgressTracker;

import java.security.PublicKey;
import java.util.List;

import static java.util.Collections.singletonList;

@InitiatingFlow
@StartableByRPC
public class IOUIssueFlow extends FlowLogic<SignedTransaction> {
    private final Party owner;
    private final int amount;

    public IOUIssueFlow(Party owner, int amount) {
        this.owner = owner;
        this.amount = amount;
    }

    private final ProgressTracker progressTracker = new ProgressTracker();

    @Override
    public ProgressTracker getProgressTracker() {
        return progressTracker;
    }

    @Suspendable
    @Override
    public SignedTransaction call() throws FlowException {
        // We choose our transaction's notary (the notary prevents double-spends).
        Party notary = getServiceHub().getNetworkMapCache().getNotaryIdentities().get(0);
        // We get a reference to our own identity.
        Party issuer = getOurIdentity();

        /* ============================================================================
         *         TODO 1 - Create our TokenState to represent on-ledger tokens!
         * ===========================================================================*/
        // We create our new TokenState.
        IOUState IOUState = new IOUState(issuer, owner, amount);
        IOUContract.Commands.Issue command = new IOUContract.Commands.Issue();


        /* ============================================================================
         *      TODO 3 - Build our token issuance transaction to update the ledger!
         * ====================ommand(command, IOUState.getIssuer().getOwningKey());    //step5,把命令加到tx
        transactionBuilder.setN=======================================================*/
        // We build our transaction.
        TransactionBuilder transactionBuilder = new TransactionBuilder();
        transactionBuilder.setNotary(notary);
        transactionBuilder.addOutputState(IOUState, IOUContract.ID);    //把IOUState加上跟IOUStateContract的參考值,而後加到transactionBuilder
        List<PublicKey> requiredSigners = ImmutableList.of(IOUState.getIssuer().getOwningKey(), owner.getOwningKey());
        transactionBuilder.addCommand(command, requiredSigners);    //step5,把命令加到tx


        /* ============================================================================
         *          TODO 2 - Write our TokenContract to control token issuance!
         * ===========================================================================*/
        transactionBuilder.verify(getServiceHub());
        FlowSession session = initiateFlow(owner);
        SignedTransaction signedTransaction = getServiceHub().signInitialTransaction(transactionBuilder);

        SignedTransaction fullySignedTransaction = subFlow(new CollectSignaturesFlow(signedTransaction,
                singletonList(session)));
        return subFlow(new FinalityFlow(fullySignedTransaction, singletonList(session)));
    }
}

3.2 IOUIssueFlowResponder

package bootcamp;

import co.paralleluniverse.fibers.Suspendable;
import net.corda.core.flows.*;
import net.corda.core.transactions.SignedTransaction;

@InitiatedBy(IOUIssueFlow.class)
public class IOUIssuerFlowResponder extends FlowLogic<Void> {

    private final FlowSession otherSide;

    public IOUIssuerFlowResponder(FlowSession otherSide) {
        this.otherSide = otherSide;
    }

    @Override
    @Suspendable
    public Void call() throws FlowException {
        SignedTransaction signedTransaction = subFlow(new SignTransactionFlow(otherSide) {
            @Suspendable
            @Override
            protected void checkTransaction(SignedTransaction stx) throws FlowException {

            }
        });
        subFlow(new ReceiveFinalityFlow(otherSide, signedTransaction.getId()));
        return null;
    }
}
相關文章
相關標籤/搜索