package Ġcom . r 3 . ref app . util Ċ Ċ import Ġnet . cord a . core . contracts . Command Data Ċ import Ġnet . cord a . core . contracts . Contract State Ċ import Ġnet . cord a . core . contracts . require That Ċ import Ġnet . cord a . core . transactions . Ledger Transaction Ċ import Ġjava . security . PublicKey Ċ Ċ /** Ċ Ġ* ĠUtility Ġdata Ġclass Ġused Ġto Ġmap Ġexpected Ġcount Ġof Ġverification Ġelements Ġto Ġtype Ġof Ġverification Ġelement . ĠCan Ġbe Ġused Ċ Ġ* Ġto Ġcreate Ġverification Ġelements Ġfor Ġcommands , Ġinputs , Ġoutputs Ġ. etc . Ċ Ġ*/ Ċ data Ġclass ĠVerification Element < T >( val Ġcount : ĠInt , Ġval Ġclazz : ĠClass < T >) Ċ Ċ /** Ċ Ġ* ĠCreates Ġ[ Verification Element ]. ĠUtility Ġextension Ġin fix Ġfunction Ġused Ġto Ġmap Ġelement Ġcount Ġand Ġelement Ġtype . Ċ Ġ* Ġ@ param Ġclazz Ġ[ Class ] Ġof Ġverification Ġelement Ċ Ġ* Ġ@ return Ġreturns Ġ[ Verification Element ] Ċ Ġ*/ Ċ infix Ġfun Ġ< T > ĠInt . of Type ( clazz : ĠClass < T >) Ġ= ĠVerification Element ( this , Ġclazz ) Ċ Ċ /** Ċ Ġ* ĠCreates Ġ[ Pair ] Ġof Ġaccount Ġkey Ġname Ġand Ġkey Ġextractor Ġfunction . ĠUtility Ġextension Ġin fix Ġfunction Ġused Ġto Ġmap Ġsigner Ġkey Ċ Ġ* Ġname Ġand Ġextractor Ġfunction . Ċ Ġ* Ġ@ param Ġkey Extractor Ġfunction Ġused Ġto Ġextract Ġsigner 's Ġkey Ċ Ġ* Ġ@ return Ġreturns Ġ[ Pair ] Ġof Ġkey Ġname Ġand Ġextractor Ġfunction Ċ Ġ*/ Ċ infix Ġfun ĠString . key ( key Extractor : Ġ() Ġ-> ĠPublicKey ) Ġ= ĠPair ( this , Ġkey Extractor ) Ċ Ċ /** Ċ Ġ* ĠGeneric Ġbasic Ġcontract Ġverification Ġfunction . Ċ Ġ* ĠRequire Ġthat : Ċ Ġ* ĠĠ ĠThere Ġis Ġtotal Ġnumber Ġof Ġcommands Ġequal Ġto Ġsum Ġof Ġ[ command Verification Element ] Ċ Ġ* ĠĠ ĠThere Ġis Ġtotal Ġnumber Ġof Ġinputs Ġequal Ġto Ġsum Ġof Ġ[ input Verification Element ] Ċ Ġ* ĠĠ ĠThere Ġis Ġtotal Ġnumber Ġof Ġoutputs Ġequal Ġto Ġsum Ġof Ġ[ output Verification Element ] Ċ Ġ* ĠĠ ĠThere Ġis Ġtotal Ġnumber Ġof Ġreferenced Ġstates Ġequal Ġto Ġsum Ġof Ġ[ referenced States ] Ċ Ġ* ĠĠ ĠFor Ġeach Ġgiven Ġcommand Ġin Ġ[ command Verification Element ] Ġverifies Ġthat Ġnumber Ġof Ġcommands Ġof Ġgiven Ġtype Ġis Ġequal Ċ Ġ* ĠĠ Ġto Ġgiven Ġcount Ċ Ġ* ĠĠ ĠFor Ġeach Ġgiven Ġinput Ġin Ġ[ input Verification Element ] Ġverifies Ġthat Ġnumber Ġof Ġinputs Ġof Ġgiven Ġtype Ġis Ġequal Ċ Ġ* ĠĠ Ġto Ġgiven Ġcount Ċ Ġ* ĠĠ ĠFor Ġeach Ġgiven Ġoutput Ġin Ġ[ output Verification Element ] Ġverifies Ġthat Ġnumber Ġof Ġoutputs Ġof Ġgiven Ġtype Ġis Ġequal Ċ Ġ* ĠĠ Ġto Ġgiven Ġcount Ċ Ġ* ĠĠ ĠFor Ġeach Ġgiven Ġreferenced Ġstate Ġin Ġ[ referenced States ] Ġverifies Ġthat Ġnumber Ġof Ġreferenced Ġstates Ġof Ġgiven Ġtype Ġis Ġequal Ċ Ġ* ĠĠ Ġto Ġgiven Ġcount Ċ Ġ* ĠĠ ĠFor Ġeach Ġgiven Ġsigner Ġverifies Ġthat Ġsigner Ġis Ġlisted Ġin Ġcommand 's Ġsigner Ġlist Ċ Ġ* Ċ Ġ* Ġ@ param Ġtx Ġthe Ġ[ Ledger Transaction ] Ċ Ġ* Ġ@ param Ġcommands Ġlist Ġof Ġcommand Ġverification Ġelements Ċ Ġ* Ġ@ param Ġinputs Ġlist Ġof Ġinput Ġverification Ġelements Ċ Ġ* Ġ@ param Ġoutputs Ġlist Ġof Ġoutput Ġverification Ġelements Ċ Ġ* Ġ@ param Ġsigner Keys Ġlist Ġof Ġsigner Ġkey Ġnames Ġand Ġextractor Ġfunctions Ċ Ġ* Ġ@ param Ġreferenced States Ġlist Ġof Ġreferenced Ġstate Ġverification Ġelements Ċ Ġ* Ġ@ throws ĠIllegalArgumentException Ġif Ġany Ġof Ġthe Ġver ifications Ġfails Ċ Ġ*/ Ċ fun Ġexecute Basic Contract Verification ( ĊĠĠĠĠĠĠĠ Ġtx : ĠLed ger Transaction , ĊĠĠĠĠĠĠĠ Ġcommands : ĠList < Verification Element < out ĠCommand Data >>, ĊĠĠĠĠĠĠĠ Ġinputs : ĠList < Verification Element < out ĠContract State >>, ĊĠĠĠĠĠĠĠ Ġoutputs : ĠList < Verification Element < out ĠContract State >>, ĊĠĠĠĠĠĠĠ Ġsigner Keys : ĠList < Pair < String , Ġ() Ġ-> ĠPublicKey >>, ĊĠĠĠĠĠĠĠ Ġreferenced States : ĠList < Verification Element < out ĠContract State >> Ġ= Ġempty List ()) Ġ{ ĊĊĠĠĠ Ġval Ġtotal NumberOf Commands Ġ= Ġcommands . sum By Ġ{ Ġit . count Ġ} ĊĠĠĠ Ġval Ġall Sign ers Ġ= Ġtx . commands . flatMap Ġ{ Ġit . sign ers Ġ}. toSet () ĊĠĠĠ Ġval Ġcommand Name Ġ= Ġcommands . join ToString Ġ{ Ġit . clazz . simple Name Ġ} ĊĠĠĠ Ġval Ġtotal NumberOf Inputs Ġ= Ġinputs . sum By Ġ{ Ġit . count Ġ} ĊĠĠĠ Ġval Ġtotal NumberOf Outputs Ġ= Ġoutputs . sum By Ġ{ Ġit . count Ġ} ĊĠĠĠ Ġval Ġtotal NumberOf Referenced States Ġ= Ġreferenced States . sum By Ġ{ Ġit . count Ġ} ĊĠĠĠ Ġrequire That Ġ{ ĊĊĠĠĠĠĠĠĠ Ġ" Number Ġof Ġcommands Ġshould Ġbe Ġequal Ġto Ġ$ total NumberOf Commands Ġfor Ġ$ command Name " Ġusing ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ( total NumberOf Commands Ġ== Ġtx . commands . count ()) ĊĠĠĠĠĠĠĠ Ġ" Number Ġof Ġinputs Ġshould Ġbe Ġequal Ġto Ġ$ total NumberOf Inputs Ġfor Ġ$ command Name " Ġusing ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ( total NumberOf Inputs Ġ== Ġtx . inputs . count ()) ĊĠĠĠĠĠĠĠ Ġ" Number Ġof Ġoutputs Ġshould Ġbe Ġequal Ġto Ġ$ total NumberOf Outputs Ġfor Ġ$ command Name " Ġusing ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ( total NumberOf Outputs Ġ== Ġtx . outputs . count ()) ĊĠĠĠĠĠĠĠ Ġ" Number Ġof Ġreferenced Ġstates Ġshould Ġbe Ġequal Ġto Ġ$ total NumberOf Referenced States Ġfor Ġ$ command Name " Ġusing ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ( total NumberOf Referenced States Ġ== Ġtx . reference States . count ()) ĊĊĠĠĠĠĠĠĠ Ġcommands . forEach Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" Number Ġof Ġcommands Ġof Ġtype Ġ${ it . clazz . simple Name } Ġshould Ġbe Ġequal Ġto Ġ${ it . count }" Ġusing ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ( it . count Ġ== Ġtx . commands OfType ( it . clazz ). count ()) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġinputs . forEach Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" Number Ġof Ġinputs Ġof Ġtype Ġ${ it . clazz . simple Name } Ġshould Ġbe Ġequal Ġto Ġ${ it . count } Ġfor Ġ$ command Name " Ġusing ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ( it . count Ġ== Ġtx . inputs OfType ( it . clazz ). count ()) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġoutputs . forEach Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" Number Ġof Ġoutputs Ġof Ġtype Ġ${ it . clazz . simple Name } Ġshould Ġbe Ġequal Ġto Ġ${ it . count } Ġfor Ġ$ command Name " Ġusing ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ( it . count Ġ== Ġtx . outputs OfType ( it . clazz ). count ()) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreferenced States . forEach Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" Number Ġof Ġreferenced Ġstates Ġof Ġtype Ġ${ it . clazz . simple Name } Ġshould Ġbe Ġequal Ġto Ġ${ it . count } Ġfor Ġ$ command Name " Ġusing ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ( it . count Ġ== Ġtx . reference Input Refs OfType ( it . clazz ). count ()) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġsigner Keys . forEach Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ"${ it . first } Ġkey Ġmust Ġbe Ġ${ if Ġ( signer Keys . count () Ġ== Ġ 1 ) Ġ" only Ġsigner " Ġelse Ġ" in Ġsign ers Ġlist "} Ġfor Ġ$ command Name " Ġusing ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ( all Sign ers . contains ( it . second ())) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ" All Ġsign ers Ġfrom Ġcommands Ġmust Ġbe Ġpresent Ġin Ġsigner Keys " Ġusing Ġ( all Sign ers Ġ== Ġsigner Keys . map Ġ{ Ġit . second () Ġ}. toSet ()) ĊĠĠĠ Ġ} Ċ }