import { Function, FunctionInput, FunctionOutput } from 'solc'; import * as coder from 'ethereumjs-abi'; import * as convert from '../common/convert'; import * as utils from '../common/utils'; import * as SHA3 from '../common/sha3'; type FunctionIO = FunctionInput & FunctionOutput; type DecodedResult = { raw?: any[] values?: Record } const types = (args: Array) => args.map(arg => arg.type); function fnSignature(abi: Function) { const name = utils.transformToFullName(abi) return SHA3.str(name).slice(0, 8) } const getFunAbiByName=function(abi:Array,funName:string){ let funs= (abi.filter(json => { return (json.type === 'function' || json.type === 'constructor')&& json.name==funName; }) as Function[]) if(funs&& funs.length==1){ return funs[0] } } export const encodeF = function (abi: Array, funName:string,funArgs: Array, bytecode?: string): string { let abiInputs: string[]; let funAbi=getFunAbiByName(abi,funName) if (abi) { abiInputs = types(funAbi.inputs) funArgs = convert.burrowToAbi(abiInputs, funArgs) // If abi is passed, convert values accordingly } // If bytecode provided then this is a creation call, bytecode goes first if (bytecode) { let data = bytecode if (abi) data += convert.bytesTB(coder.rawEncode(abiInputs, funArgs)) return data } else { return fnSignature(funAbi) + convert.bytesTB(coder.rawEncode(abiInputs, funArgs)) } } export const decodeF = function (abi: Function, output: Uint8Array): DecodedResult { if (!output) return let outputs = abi.outputs; let outputTypes = types(outputs); // Decode raw bytes to arguments let raw = convert.abiToBurrow(outputTypes, coder.rawDecode(outputTypes, Buffer.from(output))); let result: DecodedResult = {raw: raw.slice()} result.values = outputs.reduce(function (acc, current) { let value = raw.shift(); if (current.name) { acc[current.name] = value; } return acc; }, {}); return result; }