From: Ardis Lu Date: Wed, 3 Jan 2024 04:49:22 +0000 (-0800) Subject: Add check for smart contract language X-Git-Url: https://git.ardis.lu/?a=commitdiff_plain;h=0764e0cc02bb8f42a51ddf27e31be760167e5e6e;p=solc-metadata Add check for smart contract language --- diff --git a/index.d.ts b/index.d.ts index 6a84825..8d1257c 100644 --- a/index.d.ts +++ b/index.d.ts @@ -6,6 +6,13 @@ * @throws {TypeError} Will throw an error if the RPC responds with an HTTP error. */ export function fetchBytecode(address: string, rpc: string): Promise; +/** + * Determine the smart contract language used to produce a smart contract by inspecting the initial bytes + * of the runtime bytecode. + * @param {string} bytecode Runtime bytecode of a smart contract. + * @returns {'solidity'|'vyper'|'unknown'} The smart contract language used to generate this smart contract. + */ +export function detectLanguage(bytecode: string): 'solidity' | 'vyper' | 'unknown'; /** * Parse arbitrary EVM bytecode to extract the bytecode metadata from it. * @param {string} bytecode Raw EVM bytecode in hex (including `0x` prefix). diff --git a/index.html b/index.html index e9c56d9..bcbec42 100644 --- a/index.html +++ b/index.html @@ -215,6 +215,13 @@ } logOutput(result, '✅ Successfully fetched runtime bytecode.', bytecode); + // Validate smart contract language used + const lang = detectLanguage(bytecode); + if (lang !== 'solidity') { + logOutput(result, '❌ Unsupported smart contract language.', `Language detected: ${lang}`); + return; + } + // Parse runtime bytecode const cbor = extractCBOR(bytecode); if (cbor.includes(NaN)) { diff --git a/index.js b/index.js index d8e1fa2..03ecd5b 100644 --- a/index.js +++ b/index.js @@ -24,6 +24,27 @@ async function fetchBytecode(address, rpc) { .then(obj => obj.result); } +/** + * Determine the smart contract language used to produce a smart contract by inspecting the initial bytes + * of the runtime bytecode. + * @param {string} bytecode Runtime bytecode of a smart contract. + * @returns {'solidity'|'vyper'|'unknown'} The smart contract language used to generate this smart contract. + */ +function detectLanguage(bytecode) { + const prefix = bytecode.replace('0x', '').substring(0, 10); + + // https://github.com/banteg/erigon-kv/blob/5584ada83c75b244e611641d100ccc647a7f6791/examples/compilers.py#L17 + if (prefix === '6060604052' || prefix === '6080604052') { + return 'solidity'; + } + else if (prefix === '6004361015' || prefix === '341561000a') { + return 'vyper'; + } + else { + return 'unknown'; + } +} + /** * Parse arbitrary EVM bytecode to extract the bytecode metadata from it. * @param {string} bytecode Raw EVM bytecode in hex (including `0x` prefix). @@ -211,4 +232,4 @@ function fetchCID(cid, ipfs) { return response; } -export { fetchBytecode, extractCBOR, decodeCBOR, calculateCID, fetchCID }; +export { fetchBytecode, detectLanguage, extractCBOR, decodeCBOR, calculateCID, fetchCID };