xclud / web3dart

Ethereum library, written in Dart.
https://pub.dev/packages/web3dart
MIT License
170 stars 94 forks source link

Find the function name and parameter from input data #74

Closed KrisnaArynasta closed 1 year ago

KrisnaArynasta commented 1 year ago

I have input data like this, 0x095ea7b3000000000000000000000000765313fc9003fdbb60be7f968ca3302a7939a30f000000000000000000000000000000000000000000000000000000000000c92c

If I try decode with my ABI in https://lab.miguelmota.com/ethereum-input-data-decoder/example/ it show the function name and parameters.

My question is, can I decode the input in flutter using web3dart?

sylvestrevgenhiveon commented 1 year ago

@KrisnaArynasta Hello. How you decode input by contract?

KrisnaArynasta commented 1 year ago

Hello, In my case, I solve by this code: this code will give you function name, parameter name of the function, and the parameter value from the input data

String data = '0x095ea7b3000000000000000000000000765313fc9003fdbb60be7f968ca3302a7939a30f000000000000000000000000000000000000000000000000000000000000c92c';

String funcName = '';
List<String> abiTypeList = ["uint256", "address", "address[]" , "uint256[]", "bool", "uint8"]; //you can add every type you want
var funcParam  = [];
var funcParamValue  = [];

abiPath = "assets/smartContractABI/erc20.json";
abiStringFile = await rootBundle.loadString(abiPath);
Final contract = DeployedContract(ContractAbi.fromJson(abiStringFile, 'TokenName'), 'SC Address');

for(int indexFunc = 0; indexFunc < contract.functions.length; indexFunc++){
      final tupleFunctionName = contractList[indexContract].function(contractList[indexContract].functions[indexFunc].name).selector;

      if(hex.encode(tupleFunctionName) == data.substring(2,10)){
        funcName = contractList[indexContract].functions[indexFunc].name;

        List<FunctionParameter> parameters =contract .function(funcName).parameters;
        final tuple = TupleType(parameters.map((p) => p.type).toList());
        final buffer = hexToBytes(data.replaceAll('0x', '')).buffer;
        final parsedData = tuple.decode(buffer, 4);

        var paramData = parsedData.data;
        var paramName = [];
        var paramValue = [];

for(int indexParam = 0; indexParam < paramData.length; indexParam++){
          paramName.add(contract .function(funcName).parameters[indexParam].name);
          String type = abiTypeList.where((x) => x == contractList[indexContract].function(result["funcName"].toString()).parameters[indexParam].type.name).first;

          String stringValue = paramData[indexParam].toString();
          if(type == "uint256"){
            BigInt valueConverted = BigInt.from(int.parse(stringValue));
            paramValue.add(valueConverted);
          }
          else if(type == "address"){
            EthereumAddress valueConverted = EthereumAddress.fromHex(stringValue);
            paramValue.add(valueConverted);
          }

        }

        funcParam = paramName;
        funcParamValue = paramValue;
        break;
      }
}

note: this code only handle 2 type, uint256 and address