import { AuthenticationErrorBCH , AuthenticationProgramCommon , AuthenticationProgramStateCommon , AuthenticationVirtualMachine , OpcodesBCH , } from '../vm/vm' ; import { Output , Transaction } from './transaction-types' ; param spentOutputs param transaction param vm export const verifyTransaction = < VirtualMachine extends AuthenticationVirtualMachine < AuthenticationProgram , ProgramState > , AuthenticationProgram extends AuthenticationProgramCommon , ProgramState extends AuthenticationProgramStateCommon < Opcodes , Errors > , Opcodes = OpcodesBCH , Errors = AuthenticationErrorBCH > ( { spentOutputs , transaction , vm , } ) => { if ( transaction . inputs . length !== spentOutputs . length ) { return [ 'Unable to verify transaction: a spent output must be provided for each transaction input.' , ] ; } const errors = transaction . inputs . reduce < string [ ] > ( ( all , _ , index ) => { const program = { inputIndex : index , sourceOutput : spentOutputs [ index ] , spendingTransaction : transaction , } as AuthenticationProgram ; const state = vm . evaluate ( program ) ; const verify = vm . verify ( state ) ; if ( verify === true ) { return all ; } return [ ... all , `Error in evaluating input index "${ index }": ${ verify }` ] ; } , [ ] ) ; return errors . length === 0 ? true : errors ; } ;