Обычно такая работа назначается как проверка навыков или техническая задача, а не как часть продукта.
Это приложение сканирует все блоки сети Ethereum, начиная с одного введенного номера блока. И найдите все транзакции, которые создали смарт-контракт ERC721 для каждого блока.
Далее идет рабочий процесс приложения.
- Подтвердите диапазон блока, который будет сканироваться
- Получить блок для каждого номера блока и извлечь все его транзакции
Эта работа будет выполняться функцией с именем «getBlockWithTransactions» в Ethers.Js. - Проверьте, создала ли транзакция какой-либо смарт-контракт
Если объект транзакции не имеет свойства создает или имеет значение null, , эта транзакция не создала никакого смарт-контракта. - Проверьте, соответствует ли созданный смарт-контракт стандарту ERC721
Стандарт ERC721 компании Openzeppelin реализовал ERC165, чтобы указать тип интерфейса смарт-контракта. Если метод «supportsInterface» в смарт-контракте возвращает «true», когда он вызывается с идентификатором интерфейса «0x80ac58cd», мы можем определить, что этот смарт-контракт соответствует стандарту ERC721. - Распечатать список развернутых адресов смарт-контрактов NFT (ERC721)
Теперь следуйте за мной, чтобы писать код шаг за шагом с помощью этого рабочего процесса.
Импорт библиотек и определение констант
'use strict' const ethers = require('ethers'); const readline = require('readline').createInterface({ input: process.stdin, output: process.stdout, }); // receive user's input parameter on console const { RPC_URL_HTTP_ENDPOINT } = require('./config'); // network provider RPC url const ERC721 = require('./abi/ERC721.json'); // ERC721 standard abi
Определить поставщика и элемент данных
//define & initizlize ethers project const provider = new ethers.providers.JsonRpcProvider(RPC_URL_HTTP_ENDPOINT); //define data items var collectedAddresses = [], startBlock, lastBlock;
Подтвердите диапазон блоков и начните сканирование
/** * @description input the number of start block */ const initApp = async () => { //read blocknumber from console readline readline.question("Please input block number: ", async (blockNumber) => { startBlock = blockNumber; lastBlock = await provider.getBlockNumber(); await mainProcess(startBlock, lastBlock); }) }
Основной процесс
/** * * @param {String} startBlock * @param {String} lastBlock * @description get blocks between two block numbers from parameter and * get ERC721 creation transactions for each block */ const mainProcess = async (startBlock, lastBlock) => { console.log("\nSearching..."); let block; for (let i = startBlock; i <= lastBlock; i++) { //get block and transactions from blocknumber try { block = await provider.getBlockWithTransactions(Number(i)); console.log(`Block ${i}_>`); } catch (err) { continue; } //scan each transaction in block for await (const transaction of block.transactions) { //check if any smart contract created with this transaction if (transaction?.creates !== null) { //check if created smart contract is ERC721 or not try { const contract = new ethers.Contract(transaction?.creates, ERC721.abi, provider); const isERC721 = await contract.supportsInterface('0x80ac58cd'); if(isERC721) { collectedAddresses.push(transaction?.creates); } else { continue; } } catch (_) { continue; } } } //print result on console if (collectedAddresses.length > 0) { console.log(`For block ${i}: `, collectedAddresses); collectedAddresses = []; console.log("\nSearching..."); } } //close console readline readline.close(); }
Запустить приложение
initApp(); //start app
Надеюсь, вы попытаетесь создать более экономичный и продвинутый продукт на основе этого руководства.