package Ġio . horizontal systems . bitcoin core . transactions . extract ors Ċ Ċ import Ġio . horizontal systems . bitcoin core . core . I Storage Ċ import Ġio . horizontal systems . bitcoin core . models .* Ċ import Ġio . horizontal systems . bitcoin core . storage . Full Transaction Ċ import Ġkotlin . math . absolute Value Ċ Ċ class ĠTransaction Metadata Extractor ( ĊĠĠĠ Ġprivate Ġval Ġmy Outputs Cache : ĠMy Outputs Cache , ĊĠĠĠ Ġprivate Ġval Ġoutput Provider : ĠI Transaction Output Provider Ċ ) Ġ{ ĊĊĠĠĠ Ġfun Ġextract ( transaction : ĠFull Transaction ) Ġ{ ĊĊĠĠĠĠĠĠĠ Ġvar Ġmy Inputs Total Value Ġ= Ġ 0 L ĊĠĠĠĠĠĠĠ Ġvar Ġmy Outputs Total Value Ġ= Ġ 0 L ĊĠĠĠĠĠĠĠ Ġvar Ġmy Change Outputs Total Value Ġ= Ġ 0 L ĊĠĠĠĠĠĠĠ Ġvar Ġoutputs Total Value Ġ= Ġ 0 L ĊĠĠĠĠĠĠĠ Ġvar Ġall Inputs Mine Ġ= Ġtrue ĊĊĠĠĠĠĠĠĠ Ġfor Ġ( input Ġin Ġtransaction . inputs ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġvalue Ġ= Ġmy Outputs Cache . value Sp ent By ( input ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( value Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmy Inputs Total Value Ġ+= Ġvalue ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġall Inputs Mine Ġ= Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġfor Ġ( output Ġin Ġtransaction . outputs ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( output . value Ġ<= Ġ 0 ) Ġcontinue ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġoutputs Total Value Ġ+= Ġoutput . value ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( output . publicKey Path Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmy Outputs Total Value Ġ+= Ġoutput . value ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( output . change Output ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmy Change Outputs Total Value Ġ+= Ġoutput . value ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġif Ġ( my Inputs Total Value Ġ== Ġ 0 L Ġ&& Ġmy Outputs Total Value Ġ== Ġ 0 L ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġtransaction . header . is Mine Ġ= Ġtrue ĊĠĠĠĠĠĠĠ Ġif Ġ( my Inputs Total Value Ġ> Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtransaction . header . is Outgoing Ġ= Ġtrue ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġvar Ġamount Ġ= Ġmy Outputs Total Value Ġ- Ġmy Inputs Total Value ĊĠĠĠĠĠĠĠ Ġvar Ġfee : ĠLong ? Ġ= Ġnull ĊĊĠĠĠĠĠĠĠ Ġif Ġ( all Inputs Mine ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfee Ġ= Ġmy Inputs Total Value Ġ- Ġoutputs Total Value ĊĠĠĠĠĠĠĠĠĠĠĠ Ġamount Ġ+= Ġfee ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġinputs Total Value Ġ= Ġ 0 L ĊĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġall Inputs Have Value Ġ= Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ( input Ġin Ġtransaction . inputs ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġprevious Output Ġ= Ġoutput Provider . get ( input . previous Output Tx Hash , Ġinput . previous Output Index . toInt ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( previous Output Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġinputs Total Value Ġ+= Ġprevious Output . value ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġall Inputs Have Value Ġ= Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbreak ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġfee Ġ= Ġif Ġ( all Inputs Have Value ) Ġinputs Total Value Ġ- Ġoutputs Total Value Ġelse Ġnull ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġif Ġ( amount Ġ> Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtransaction . metadata . amount Ġ= Ġamount ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtransaction . metadata . type Ġ= ĠTransaction Type . Incoming ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġif Ġ( amount Ġ< Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtransaction . metadata . amount Ġ= Ġamount . absolute Value ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtransaction . metadata . type Ġ= ĠTransaction Type . Outgoing ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtransaction . metadata . amount Ġ= Ġ( my Outputs Total Value Ġ- Ġmy Change Outputs Total Value ). absolute Value ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtransaction . metadata . type Ġ= ĠTransaction Type . Sent To Self ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġtransaction . metadata . fee Ġ= Ġfee ĊĊĠĠĠĠĠĠĠ Ġif Ġ( my Outputs Total Value Ġ> Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġmy Outputs Cache . add ( transaction . outputs ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ } Ċ Ċ interface ĠI Transaction Output Provider Ġ{ ĊĠĠĠ Ġfun Ġget ( transaction Hash : ĠByteArray , Ġindex : ĠInt ): ĠTransaction Output ? Ċ } Ċ Ċ class ĠTransaction Output Provider ( private Ġval Ġstorage : ĠI Storage ): ĠI Transaction Output Provider Ġ{ ĊĠĠĠ Ġoverride Ġfun Ġget ( transaction Hash : ĠByteArray , Ġindex : ĠInt ): ĠTransaction Output ? Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġstorage . getOutput ( transaction Hash , Ġindex ) ĊĠĠĠ Ġ} Ċ } Ċ