From d42a725b4681f1847bd7fb35d77c93371bf88e27 Mon Sep 17 00:00:00 2001 From: Ardis Lu Date: Wed, 27 Mar 2024 20:10:33 -0700 Subject: [PATCH] Upgrade parsing logic to match 4-byte-gen Handles edge cases for tuples and "... returns ()" --- index.html | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/index.html b/index.html index 1cbd3eb..e78ee63 100644 --- a/index.html +++ b/index.html @@ -201,22 +201,33 @@ continue; } + // Drop parameter names and extraneous whitespace, if there are any. Preserves tuple parentheses. + // E.g. "(uint abc, uint256, bool test)[]" --> ['(uint', 'uint256', 'bool)[]'] + const parametersArray = parameters.split(',').map(param => { + const trimmed = param.trim(); + const trailingParens = trimmed.match(/\)*[\[\]]*$/)[0] ?? ''; + const split = trimmed.split(' '); + return `${split[0]}${split.length > 1 ? trailingParens : ''}`; + }); + // Convert types from Solidity to ABI (e.g., 'uint' --> 'uint256') // Reference: https://docs.soliditylang.org/en/latest/abi-spec.html#types - const parametersArray = parameters.split(',').map(param => param.trim().split(' ')[0]); for (const [index, param] of parametersArray.entries()) { - switch (param) { - case 'int': parametersArray[index] = 'int256'; break; - case 'uint': parametersArray[index] = 'uint256'; break; - case 'fixed': parametersArray[index] = 'fixed128x18'; break; - case 'ufixed': parametersArray[index] = 'ufixed128x18'; break; - case 'contract': parametersArray[index] = 'address'; break; - case 'enum': parametersArray[index] = 'uint8'; break; - case 'struct': parametersArray[index] = 'tuple'; break; + if (/int[1-9]/.test(param) || /uint[1-9]/.test(param)) { + continue; } + parametersArray[index] = param + .replace('int', 'int256') // Includes uint --> uint256 + .replace('contract', 'address') + .replace('enum', 'uint8'); } const parametersTypes = parametersArray.join(','); + // Drop extra trailing parenthesis, if there is one. This happens when "... returns ()" is included in the input. + if ((parametersTypes.match(/\(/g)?.length ?? 0) < (parametersTypes.match(/\)/g)?.length ?? 0)) { + parametersTypes = parametersTypes.slice(0, -1); + } + // The final normalized function name to hash const normalizedName = `${name}(${parametersTypes})`; const byteArray = keccak256(new TextEncoder().encode(normalizedName)).slice(0, 4); -- 2.47.3