import { BaseScriptBuilder } from './BaseScriptBuilder' ; import { common , UInt160 } from './common' ; import { CallFlags } from './models' ; import { getSysCallHash , SysCallName } from './models/vm' ; import { scriptBuilderParamTo } from './paramUtils' ; import { ScriptBuilderParam , ScriptBuilderParamToCallbacks } from './types' ; export class ScriptBuilder extends BaseScriptBuilder { private readonly pushParamCallbacks : ScriptBuilderParamToCallbacks < this > ; public constructor ( ) { super ( ) ; this . pushParamCallbacks = { undefined : ( ) => this . emitPush ( Buffer . alloc ( 0 , 0 ) ) , array : ( param ) => this . emitPushArray ( param ) , map : ( param ) => this . emitPushMap ( param ) , uInt160 : ( param ) => this . emitPushUInt160 ( common . asUInt160 ( param ) ) , uInt256 : ( param ) => this . emitPushUInt256 ( common . asUInt256 ( param ) ) , ecPoint : ( param ) => this . emitPushECPoint ( common . asECPoint ( param ) ) , number : ( param ) => this . emitPushInt ( param ) , bn : ( param ) => this . emitPushInt ( param ) , string : ( param ) => this . emitPushString ( param ) , boolean : ( param ) => this . emitPushBoolean ( param ) , buffer : ( param ) => this . emitPush ( param ) , object : ( param ) => this . emitPushObject ( param ) } ; } public emitPushParam ( param ) { return scriptBuilderParamTo ( param , this . pushParamCallbacks ) ; } public emitPushParams ( ... params ) { for ( let i = params . length - 1 ; i >= 0 ; i -= 1 ) { this . emitPushParam ( params [ i ] ) ; } return this ; } public emitSysCall ( sysCall , ... params ) { this . emitPushParams ( ... params ) ; const hash = getSysCallHash ( sysCall ) ; return this . emitSysCallInternal ( hash ) ; } public emitPushArray ( params ) { if ( params . length === 0 ) { return this . emitOp ( 'NEWARRAY0' ) ; } this . emitPushParams ( ... params ) ; this . emitPushParam ( params . length ) ; return this . emitOp ( 'PACK' ) ; } public emitAppCallInvocation ( operation , flags , ... params ) { this . emitPushArray ( params ) ; this . emitPushInt ( flags ) ; return this . emitPushParam ( operation ) ; } public emitAppCallVerification ( scriptHash ) { this . emitPushParam ( common . uInt160ToBuffer ( scriptHash ) ) ; return this . emitSysCall ( 'System.Contract.Call' ) ; } public emitDynamicAppCall ( scriptHash , operation , flags , ... params ) { this . emitAppCallInvocation ( operation , flags , ... params ) ; return this . emitAppCallVerification ( scriptHash ) ; } public emitPushMap ( params ) { this . emitOp ( 'NEWMAP' ) ; params . forEach ( ( value , key ) => { this . emitOp ( 'DUP' ) ; this . emitPushParam ( key ) ; this . emitPushParam ( value ) ; this . emitOp ( 'SETITEM' ) ; } ) ; return this ; } public emitPushObject ( params ) { this . emitOp ( 'NEWMAP' ) ; Object . entries ( params ) . forEach ( ( [ key , value ] ) => { this . emitOp ( 'DUP' ) ; this . emitPushParam ( key ) ; this . emitPushParam ( value ) ; this . emitOp ( 'SETITEM' ) ; } ) ; return this ; } public emitSysCallName ( sysCall ) { this . emitPush ( getSysCallHash ( sysCall ) ) ; return this ; } }