From 52083324381154bdc3af009023e2a5d00825c6a2 Mon Sep 17 00:00:00 2001 From: JukLee0ira Date: Fri, 30 Aug 2024 12:50:01 +0800 Subject: [PATCH] Validate query data --- src/opCodeFinder.js | 111 +++++++++++++++++++++++++++++++++----------- 1 file changed, 83 insertions(+), 28 deletions(-) diff --git a/src/opCodeFinder.js b/src/opCodeFinder.js index 5dc0da6..b9bb8c2 100644 --- a/src/opCodeFinder.js +++ b/src/opCodeFinder.js @@ -1,25 +1,84 @@ import Web3 from "web3"; import fs from "fs"; -const rpcUrl = "https://rpc.ankr.com/xdc"; -const web3 = new Web3(new Web3.providers.HttpProvider(rpcUrl)); +let web3; +let opCode; +let matchContractCount = 0; + +async function validateInputs(args) { + let startBlock, endBlock, opcode, rpcUrl; + let validArgs = []; + // Check if all parameters are provided + if (args.length !== 4) { + console.log( + "Please provide exactly four arguments: startBlock, endBlock, opcode, and rpc url." + ); + process.exit(1); + } + + rpcUrl = args[3]; + let latestBlock; + try { + web3 = new Web3(new Web3.providers.HttpProvider(rpcUrl)); + latestBlock = await web3.eth.getBlockNumber(); + } catch (e) { + console.log("rpc url must be a valid URL."); + process.exit(1); + } + + // Get the parameter values + startBlock = parseInt(args[0], 10); + if (args[1] === "latest") { + endBlock = Number(latestBlock); + console.log("latest Block Number is " + endBlock); + } else { + endBlock = parseInt(args[1], 10); + } + opcode = parseInt(args[2], 16); + + // Validate that the block number is a valid positive integer + if ( + isNaN(startBlock) || + isNaN(endBlock) || + startBlock < 0 || + endBlock < 0 || + startBlock > endBlock || + startBlock > latestBlock || + endBlock > latestBlock + ) { + console.log("Invalid block number!"); + process.exit(1); + } + + // Validate that the opcode is a valid hexadecimal string (optionally starting with "0x") + if (!/^0x[a-fA-F0-9]+$/i.test(opcode) && !/^[a-fA-F0-9]+$/i.test(opcode)) { + console.log( + "Opcode must be a valid hexadecimal string, optionally starting with '0x'." + ); + process.exit(1); + } + + // If all validations pass + validArgs.push(startBlock, endBlock, opcode, rpcUrl); + return validArgs; +} async function findContracts(startBlockNumber, endBlockNumber) { - let contractAddress = []; let contractCount = 0; for (let i = startBlockNumber; i <= endBlockNumber; i++) { process.stdout.write( - `\rSearching for block ${i} ,total ${contractCount} contracts found` + `\rSearching for block ${i} ,total found ${contractCount} contracts, ${matchContractCount} of which meet the criteria` ); let block = await web3.eth.getBlock(i); if (block != null) { if (block.transactions != null && block.transactions.length != 0) { let blockFinishedCount = block.transactions.length; + //srarch for contract address in each transaction for (let txHash of block.transactions) { let receipt = await web3.eth.getTransactionReceipt(txHash); if (receipt && receipt.contractAddress) { - contractAddress.push(receipt.contractAddress); + getContractBytecode(receipt.contractAddress); contractCount++; } blockFinishedCount--; @@ -35,36 +94,30 @@ async function findContracts(startBlockNumber, endBlockNumber) { } async function getContractBytecode(contractArr) { - for (let contractAddress of contractArr) { - try { - const bytecode = await web3.eth.getCode(contractAddress); - if (bytecode === "0x") { - console.log("No contract found at the specified address."); - } else { - let isContainsPrevrandao = findOpcode(stringToHexArray(bytecode)); - if (isContainsPrevrandao) { - saveTheContract(contractAddress); //saveTheContract in a txt file - } - } - } catch (error) { - console.error("Error fetching contract bytecode:", error); + try { + let bytecode = await web3.eth.getCode(contractArr); + let isContainsTheOpCode = findOpcode(stringToHexArray(bytecode)); + if (isContainsTheOpCode) { + saveTheContract(contractArr); //saveTheContract in a txt file } + } catch (error) { + console.error("Error fetching contract bytecode:", error); } } function saveTheContract(contractAddress) { fs.appendFile( - "prevrandao-contract-addresses.txt", - contractAddress, + "match-contract-addresses.txt", + contractAddress + "\n", { encoding: "utf8" }, (err) => { if (err) { console.error("Error occurred while appending content."); return; } - console.log("Content has been successfully appended to the file"); } ); + matchContractCount++; } function stringToHexArray(hexString) { @@ -90,7 +143,7 @@ function findOpcode(bytecode) { if (isPushOpcode(op)) { // increment i, skipping PUSH argument i += skipPush(op, i); - } else if (op == opcode) { + } else if (op == opCode) { return true; } i++; @@ -103,16 +156,18 @@ function isPushOpcode(op) { return op >= 0x5f && op <= 0x7f; // PUSH1 (0x5f) to PUSH32 (0x7f) } // Example skipPush function -function skipPush(op, index) { +function skipPush(op) { + // The PUSH opcodes are consecutive, so we can use the opcode to determine how many bytes to skip // For example, PUSH1 (0x5f) skips 1 byte, PUSH32 (0x7f) skips 32 bytes return op - 0x60 + 1; } async function main() { - let latestBlockNumber = Number(await web3.eth.getBlockNumber()); - //72290000 is the block before the application of the PREVRANDAO opcode. - let contracts = await findContracts(72290000, latestBlockNumber); - getContractBytecode(contracts); + const args = process.argv.slice(2); + const validArgs = await validateInputs(args); + const startBlock = validArgs[0]; + const endBlock = validArgs[1]; + opCode = validArgs[2]; + await findContracts(startBlock, endBlock); } -const opcode = 0x44; // PREVRANDAO = 0x44 main();