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; }
咱們擴展了flowLogic類,這個類最重要的就是call方法,下面是這個函數的聲明google
@Suspendable @Override public signedTransaction call() throws FlowException
接下來是分爲三大步:debug
此外咱們還須要依靠公證人達成共識
Party issuer = getOurIdentity();
接下來是第一步,創建state:
一個iou須要issuer,誰啓動這個流、誰就是issuer,流也是由party啓動的!
IOUState iouState = new IOUState(issuer, owner, amount); IOUContract.Commands.Issue command = new IOUContract.Commands.Issue();
我我的感受,從便於理解的角度,整個corda,乃至全部的區塊鏈網絡,都是以tx爲核心的。
corda中的tx須要這些東西:
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);
大體分爲如下幾步:
徹底簽名的tx的意思是否是須要其餘方面的簽名以後的,因此咱們須要創建子流和其餘節點進行交互,
因此須要收前面全部簽名的流+會話,
最後返回的用徹底簽名流+單例會話造成的新的終止子流
等等,這張圖是否是就是前面那張圖的總結????????頗有可能啊!!!我只要能弄懂應答流的程序&這個流的交換過程&讀讀文獻我可能就打通了整個corda了!
根據contract驗證tx的合法性
txBuidler.verify(getServiceHub())
生成流會話
Flow Session = initiateFlow(owner);
用私鑰簽署這個交易讓它不可改變了
SignedTransaction signedTransaction = getSeriveHub().signInitialTransaction(txBuilder);
做爲被啓動流,它必須打上註釋:
@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 }
說來也奇怪,這個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
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))); } }
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; } }