/// <reference types="node" />
/// <reference types="pouchdb-core" />
import { OpCode, SysCallName, UInt160, VMState } from '@neo-one/client-common-browserify';
import { Block, ExecutionAction, ScriptContainer, TriggerType, VMListeners, WriteBlockchain } from '@neo-one/node-core-browserify';
import BN from 'bn.js';
import { StackItem } from './stackItem';
export declare const MAX_SHL_SHR = 65535;
export declare const MIN_SHL_SHR: number;
export declare const MAX_SIZE_BIG_INTEGER = 32;
export declare const MAX_STACK_SIZE: number;
export declare const MAX_ITEM_SIZE: number;
export declare const MAX_INVOCATION_STACK_SIZE = 1024;
export declare const MAX_ARRAY_SIZE = 1024;
export declare const MAX_ARRAY_SIZE_BN: BN;
export declare const BLOCK_HEIGHT_YEAR = 2000000;
export declare const BLOCK_HEIGHT_MAX_SIZE_CHECKS: number;
export declare const FEES: {
    ONE: BN;
    TEN: BN;
    TWENTY: BN;
    ONE_HUNDRED: BN;
    TWO_HUNDRED: BN;
    FOUR_HUNDRED: BN;
    FIVE_HUNDRED: BN;
    ONE_THOUSAND: BN;
};
export declare const FREE_GAS: BN;
export declare type ExecutionStack = readonly StackItem[];
export interface ExecutionInit {
    readonly scriptContainer: ScriptContainer;
    readonly triggerType: TriggerType;
    readonly action: ExecutionAction;
    readonly listeners: VMListeners;
    readonly skipWitnessVerify: boolean;
    readonly persistingBlock?: Block;
}
export interface CreatedContracts {
    readonly [hash: string]: UInt160;
}
export interface Options {
    readonly depth: number;
    readonly stack: ExecutionStack;
    readonly stackAlt: ExecutionStack;
    readonly createdContracts: CreatedContracts;
    readonly scriptHashStack: readonly UInt160[];
    readonly scriptHash: UInt160 | undefined;
    readonly entryScriptHash: UInt160;
    readonly returnValueCount: number;
    readonly stackCount: number;
    readonly pc?: number;
}
export interface ExecutionContext {
    readonly state: VMState;
    readonly errorMessage?: string;
    readonly blockchain: WriteBlockchain;
    readonly init: ExecutionInit;
    readonly engine: {
        readonly run: (input: {
            readonly context: ExecutionContext;
        }) => Promise<ExecutionContext>;
        readonly executeScript: (input: {
            readonly code: Buffer;
            readonly blockchain: WriteBlockchain;
            readonly init: ExecutionInit;
            readonly gasLeft: BN;
            readonly options?: Options;
        }) => Promise<ExecutionContext>;
    };
    readonly code: Buffer;
    readonly scriptHashStack: readonly UInt160[];
    readonly scriptHash: UInt160;
    readonly callingScriptHash: UInt160 | undefined;
    readonly entryScriptHash: UInt160;
    readonly pc: number;
    readonly depth: number;
    readonly stack: ExecutionStack;
    readonly stackAlt: ExecutionStack;
    readonly gasLeft: BN;
    readonly createdContracts: CreatedContracts;
    readonly returnValueCount: number;
    readonly stackCount: number;
}
export interface OpResult {
    readonly context: ExecutionContext;
    readonly results?: readonly StackItem[];
    readonly resultsAlt?: readonly StackItem[];
}
export interface OpInvokeArgs {
    readonly context: ExecutionContext;
    readonly args: readonly StackItem[];
    readonly argsAlt: readonly StackItem[];
}
export declare type OpInvoke = (input: OpInvokeArgs) => Promise<OpResult> | OpResult;
export interface Op {
    readonly name: OpCode;
    readonly in: number;
    readonly inAlt: number;
    readonly out: number;
    readonly outAlt: number;
    readonly invocation: number;
    readonly fee: BN;
    readonly invoke: OpInvoke;
}
export interface SysCall {
    readonly name: SysCallName;
    readonly in: number;
    readonly inAlt: number;
    readonly out: number;
    readonly outAlt: number;
    readonly invocation: number;
    readonly fee: BN;
    readonly invoke: OpInvoke;
    readonly context: ExecutionContext;
}
