// package Ġkr . co . bus an bank . b mt . flow Ċ // Ċ // import Ġnet . cord a . core . contracts . require That Ċ // Ċ // import Ġjava . math . BigInteger Ċ // import Ġjava . security . PublicKey Ċ // import Ġjava . util . ArrayList Ċ // Ċ // import Ġcom . google . common . collect . ImmutableList Ċ // import Ġcom . google . common . collect . ImmutableList . Builder Ċ // import Ġcom . google . common . collect . Immutable Set Ċ // Ċ // import Ġco . parallel universe . fib ers . Suspend able Ċ // import Ġkr . co . bus an bank . b mt . contract . Digital Asset Contract Ċ // import Ġkr . co . bus an bank . b mt . schema . Asset Token Schema V 1 Ċ // import Ġkr . co . bus an bank . b mt . state . Asset Token State Ċ // import Ġnet . cord a . core . contracts . Command Ċ // import Ġnet . cord a . core . contracts . Contract State Ċ // import Ġnet . cord a . core . contracts . State And Ref Ċ // import Ġnet . cord a . core . contracts . Unique Identifier Ċ // import Ġnet . cord a . core . crypto . Secure Hash Ċ // import Ġnet . cord a . core . flows . Collect Signatures Flow Ċ // import Ġnet . cord a . core . flows . Final ity Flow Ċ // import Ġnet . cord a . core . flows . Flow Exception Ċ // import Ġnet . cord a . core . flows . Flow Logic Ċ // import Ġnet . cord a . core . flows . Flow Session Ċ // import Ġnet . cord a . core . flows . Initi ated By Ċ // import Ġnet . cord a . core . flows . Initi ating Flow Ċ // import Ġnet . cord a . core . flows . Receive Final ity Flow Ċ // import Ġnet . cord a . core . flows . Sign Transaction Flow Ċ // import Ġnet . cord a . core . flows . Start able By RPC Ċ // import Ġnet . cord a . core . identity . Abstract Party Ċ // import Ġnet . cord a . core . identity . Party Ċ // import Ġnet . cord a . core . node . services . Vault Ċ // import Ġnet . cord a . core . node . services . vault . Field Info Ċ // import Ġnet . cord a . core . node . services . vault . Query Criteria Ċ // import Ġnet . cord a . core . node . services . vault . Criteria Expression . Column Predicate Expression Ċ // import Ġnet . cord a . core . node . services . vault . Query Criteria . Vault Custom Query Criteria Ċ // import Ġnet . cord a . core . node . services . vault . Query Criteria . Vault Query Criteria Ċ // import Ġnet . cord a . core . transactions . Signed Transaction Ċ // import Ġnet . cord a . core . transactions . Transaction Builder Ċ // import Ġnet . cord a . core . utilities . Progress Tracker Ċ // Ċ // /** Ċ // Ġ* ĠThis Ġflow Ġallows Ġtwo Ġparties Ġ( the Ġ[ Init iator ] Ġand Ġthe Ġ[ Accept or ]) Ġto Ġcome Ġto Ċ // Ġ* Ġan Ġagreement Ġabout Ġthe ĠIO U Ġencaps ulated Ġwithin Ġan Ġ[ IO U State ]. Ċ // Ġ* Ċ // Ġ* ĠIn Ġour Ġsimple Ġexample , Ġthe Ġ[ Accept or ] Ġalways Ġaccepts Ġa Ġvalid ĠIO U . Ċ // Ġ* Ċ // Ġ* ĠThese Ġflows Ġhave Ġdeli ber ately Ġbeen Ġimplemented Ġby Ġusing Ġonly Ġthe Ġcall () Ċ // Ġ* Ġmethod Ġfor Ġease Ġof Ġunderstanding . ĠIn Ġpractice Ġwe Ġwould Ġrecommend Ġsplitting Ġup Ċ // Ġ* Ġthe Ġvarious Ġstages Ġof Ġthe Ġflow Ġinto Ġsub - rout ines . Ċ // Ġ* Ċ // Ġ* ĠAll Ġmethods Ġcalled Ġwithin Ġthe Ġ[ Flow Logic ] Ġsub - class Ġneed Ġto Ġbe Ġannotated Ġwith Ċ // Ġ* Ġthe Ġ@ Suspend able Ġannotation . Ċ // Ġ*/ Ċ // class ĠTransfer Flow Ġ{ Ċ // Ċ // ĠĠĠ Ġ@ Initi ating Flow Ċ // ĠĠĠ Ġ@ Start able By RPC Ċ // ĠĠĠ Ġclass ĠInit iator ( private Ġval Ġparticipants : ĠArray < Party >, Ġprivate Ġval Ġasset Number : ĠString , Ġprivate Ġval Ġfrom Address : ĠString , Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġprivate Ġval Ġto Address : ĠString , Ġprivate Ġval Ġamount : ĠString ) Ġ: ĠFlow Logic < Signed Transaction >() Ġ{ Ċ // Ċ // Ċ // ĠĠĠĠĠĠĠ Ġ// ĠThe Ġprogress Ġtracker Ġcheck points Ġeach Ġstage Ġof Ġthe Ġflow Ġand Ġoutputs Ġthe Ċ // ĠĠĠĠĠĠĠ Ġ// Ġspecified Ġmessages Ġwhen Ġeach Ċ // ĠĠĠĠĠĠĠ Ġ// Ġcheckpoint Ġis Ġreached Ġin Ġthe Ġcode . ĠSee Ġthe Ġ' progress Tracker . current Step ' Ċ // ĠĠĠĠĠĠĠ Ġ// Ġexpressions Ġwithin Ġthe Ġcall () Ċ // ĠĠĠĠĠĠĠ Ġ// Ġfunction . Ċ // ĠĠĠĠĠĠĠ Ġoverride Ġval Ġprogress Tracker : ĠProgress Tracker ? Ġ= ĠProgress Tracker () Ċ // Ċ // ĠĠĠĠĠĠĠ Ġ/** Ċ // ĠĠĠĠĠĠĠĠ Ġ* ĠThe Ġflow Ġlogic Ġis Ġencaps ulated Ġwithin Ġthe Ġcall () Ġmethod . Ċ // ĠĠĠĠĠĠĠĠ Ġ*/ Ċ // ĠĠĠĠĠĠĠ Ġ@ Suspend able Ċ // ĠĠĠĠĠĠĠ Ġ@ Throws ( Flow Exception :: class ) Ċ // ĠĠĠĠĠĠĠ Ġoverride Ġfun Ġcall (): ĠSigned Transaction Ġ{ Ċ // Ċ // ĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠObtain Ġa Ġreference Ġto Ġthe Ġnot ary Ġwe Ġwant Ġto Ġuse . Ċ // ĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġnot ary Ġ= Ġservice Hub . network Map Cache . not ary Id entities [ 0 ] Ċ // Ċ // ĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠGenerate Ġan Ġunsigned Ġtransaction . Ċ // ĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġme Ġ= Ġour Identity Ċ // ĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġparticipant List Ġ= ĠArrayList < Abstract Party >() Ċ // ĠĠĠĠĠĠĠĠĠĠĠ Ġparticipant List . add ( me ) Ċ // ĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ( a Party Ġin Ġparticipants ) Ġ{ Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġparticipant List . add ( a Party ) Ċ // ĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ċ // Ċ // ĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġfrom Ġï¿½ Ü ° ï¿½ Ġ ï¿½ï¿½ È ¸ Ċ // ĠĠĠĠĠĠĠĠĠĠĠ Ġ// get Ġhouse Ġstates Ġon Ġledger Ġwith Ġuuid Ġas Ġinput Ġtoken Id Ċ // ĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġasset Number Field : ĠField Info ? Ġ= Ċ // Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnull Ċ // ĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġasset Number Field Ġ= Ġget Field (" asset Number ", ĠAsset Token Schema V 1 . Persistent AT :: class . java ) Ċ // ĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠNoSuch Field Exception ) Ġ{ Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġe . printStackTrace () Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠFlow Exception ( e . message ) Ċ // ĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ċ // Ċ // ĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġowner Field : ĠField Info ? Ġ= Ġnull Ċ // ĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġowner Field Ġ= Ġget Field (" owner ", ĠAsset Token Schema V 1 . Persistent AT :: class . java ) Ċ // ĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠNoSuch Field Exception ) Ġ{ Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġe . printStackTrace () Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠFlow Exception ( e . message ) Ċ // ĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ċ // Ċ // ĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġun consumed Ġ= ĠVault Query Criteria ( Vault . State Status . UN CON SU MED ) Ċ // ĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġequal Asset Express Ġ= Ġnet . cord a . core . node . services . vault . Builder . equal < String >( asset Number Field !! , Ġasset Number ) Ċ // ĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġequal Asset Ġ= ĠVault Custom Query Criteria ( equal Asset Express ) Ċ // Ċ // ĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġequal Address Express Ġ= Ġnet . cord a . core . node . services . vault . Builder . equal < String >( owner Field !! , Ġfrom Address ) Ċ // ĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġequal Address Ġ= ĠVault Custom Query Criteria ( equal Address Express ) Ċ // Ċ // ĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġquery Ġ= Ġun consumed . and ( equal Asset ). and ( equal Address ) Ċ // Ċ // ĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġpages Ġ= Ġservice Hub . vault Service . query By ( Asset Token State :: class . java , Ġquery ). states Ċ // Ċ // ĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( pages . size Ġ< Ġ 1 ) Ġ{ Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠFlow Exception (" cannot Ġfind Ġfrom Ġasset ") Ċ // ĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ċ // ĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġfrom State Ġ= Ġpages [ 0 ]. state . data Ċ // Ċ // ĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġfrom Amount Ġ= Ġfrom State . amount Ċ // ĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġto Amount Ġ= ĠBigInteger . ZERO Ċ // Ċ // ĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġequal Address Express Ġ= Ġnet . cord a . core . node . services . vault . Builder . equal ( owner Field , Ġto Address ) Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġequal Address Ġ= ĠVault Custom Query Criteria ( equal Address Express ) Ċ // Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġquery Ġ= Ġun consumed . and ( equal Asset ). and ( equal Address ) Ċ // Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( pages . size Ġ> Ġ 0 ) Ġ{ Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġto Amount Ġ= Ġpages [ 0 ]. state . data . amount Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ċ // Ċ // ĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠException ) Ġ{ Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġe . printStackTrace () Ċ // ĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ċ // Ċ // ĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġmove Amount Ġ= ĠBigInteger ( amount ) Ċ // ĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġafter From Amount Ġ= Ġfrom Amount . subtract ( move Amount ) Ċ // ĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġafter To Amount Ġ= Ġto Amount . add ( move Amount ) Ċ // Ċ // ĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( after From Amount . compareTo ( BigInteger . ZERO ) Ġ< Ġ 0 ) Ġ{ Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠFlow Exception (" not Ġenough Ġtoken Ġamount ") Ċ // ĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ċ // Ċ // ĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġfrom Asset Ġ= ĠAsset Token State ( participant List , Ġasset Number , Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfrom Address , Ġafter From Amount . to Long (), Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠUnique Identifier ()) Ċ // Ċ // ĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġto Asset Ġ= ĠAsset Token State ( participant List , Ġasset Number , Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġto Address , Ġafter To Amount . to Long (), Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠUnique Identifier ()) Ċ // Ċ // ĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġbuilder Ġ= ĠImmutableList . builder < PublicKey >() Ċ // Ċ // ĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ( a Party Ġin Ġparticipant List ) Ġ{ Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbuilder . add ( a Party . own ing Key ) Ċ // ĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ċ // Ċ // ĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġtx Command Ġ= ĠCommand < Digital Asset Contract . Commands . Transfer >( Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠDigital Asset Contract . Commands . Transfer (), Ġbuilder . build ()) Ċ // Ċ // ĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġtx Builder Ġ= ĠTransaction Builder ( not ary ) Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. add Output State ( from Asset ) Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. add Output State ( to Asset ). add Command ( tx Command ) Ċ // Ċ // ĠĠĠĠĠĠĠĠĠĠĠ Ġtx Builder . verify ( service Hub ) Ċ // Ċ // ĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠSign Ġthe Ġtransaction . Ċ // ĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġpart Signed Tx Ġ= Ġservice Hub . sign Initial Transaction ( tx Builder ) Ċ // Ċ // ĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġset builder Ġ= ĠImmutable Set . builder < Flow Session >() Ċ // Ċ // ĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ( a Party Ġin Ġparticipants ) Ġ{ Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġother Party Session Ġ= Ġinitiate Flow ( a Party ) Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġset builder . add ( other Party Session ) Ċ // ĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ċ // Ċ // ĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġim utable set Ġ= Ġset builder . build () Ċ // ĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġfully Signed Tx Ġ= Ġsub Flow ( Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠCollect Signatures Flow ( part Signed Tx , Ġim utable set , ĠCollect Signatures Flow . tracker ())) Ċ // Ċ // ĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġsub Flow ( Final ity Flow ( fully Signed Tx , Ġim utable set )) Ċ // ĠĠĠĠĠĠĠ Ġ} Ċ // ĠĠĠ Ġ} Ċ // Ċ // ĠĠĠ Ġ@ Initi ated By ( Init iator :: class ) Ċ // ĠĠĠ Ġclass ĠAc ceptor ( private Ġval Ġother Party Session : ĠFlow Session ) Ġ: ĠFlow Logic < Signed Transaction >() Ġ{ Ċ // Ċ // ĠĠĠĠĠĠĠ Ġ@ Suspend able Ċ // ĠĠĠĠĠĠĠ Ġ@ Throws ( Flow Exception :: class ) Ċ // ĠĠĠĠĠĠĠ Ġoverride Ġfun Ġcall (): ĠSigned Transaction Ġ{ Ċ // ĠĠĠĠĠĠĠĠĠĠĠ Ġclass ĠSign Tx Flow Ġprivate Ġconstructor ( other Party Flow : ĠFlow Session , Ġprogress Tracker : ĠProgress Tracker ) Ġ: ĠSign Transaction Flow ( other Party Flow , Ġprogress Tracker ) Ġ{ Ċ // Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġcheck Transaction ( st x : ĠSigned Transaction ) Ġ{ Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġrequire That < Any > Ġ{ Ġrequire Ġ-> Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġstate 1 Ġ= Ġst x . tx . outputs [ 0 ]. data Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġrequire . using (" This Ġmust Ġbe Ġan ĠDigital Asset State Ġtransaction .", Ġstate 1 Ġis ĠAsset Token State ) Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġfrom Token Ġ= Ġstate 1 Ġas ĠAsset Token State Ċ // Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġrequire . using (" From Address ĠAmount Ġmust Ġbe Ġbigger Ġthan Ġzero .", Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠBigInteger . ZERO . compareTo ( from Token . amount ) Ġ< Ġ 0 ) Ċ // Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġstate 2 Ġ= Ġst x . tx . outputs [ 1 ]. data Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġrequire . using (" This Ġmust Ġbe Ġan ĠDigital Asset State Ġtransaction .", Ġstate 2 Ġis ĠAsset Token State ) Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġto Token Ġ= Ġstate 2 Ġas ĠAsset Token State Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġrequire . using (" To Address ĠAmount Ġmust Ġbe Ġbigger Ġthan Ġzero .", Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠBigInteger . ZERO . compareTo ( to Token . amount ) Ġ< Ġ 0 ) Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnull Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ċ // ĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ċ // Ċ // ĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġsign Tx Flow Ġ= ĠSign Tx Flow ( other Party Session , ĠSign Transaction Flow . tracker ()) Ċ // ĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġtx Id Ġ= Ġsub Flow ( sign Tx Flow ). id Ċ // Ċ // ĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġsub Flow ( Receive Final ity Flow ( other Party Session , Ġtx Id )) Ċ // ĠĠĠĠĠĠĠ Ġ} Ċ // ĠĠĠ Ġ} Ċ //} Ċ