#! Python3 """ File name: minters.py Author: Jonathan Snow Date created: 09/07/2022 Python Version: 3.9.x File Details: Purpose: A series of functions to generate a list of all addresses that minted an NFT from a provided contract address. """ # Imports from time import sleep, time from modules import eth, config, data from termcolor import colored import sys DEBUG = False # Load latest block and create contract object with generic ABI BLOCK = eth.get_latest_block() ABI = config.load("modules/abi/origin_721.json") ################################################## def main(address): """ Function to pull all Transfer events from a contract and process these events to determine which addresses minted an NFT. """ print("\nStarting Contract Minter Analysis.") # Grab deployment block from Etherscan to simplify processing start_block = eth.get_contract_deploy_date(address, True) # Create contract object using Origin ERC721 ABI contract = eth.get_contract(address, ABI) # Get all transfer logs for the provided contract with a 50k block interval transfers = eth.get_transfer_logs(contract, start_block, BLOCK, 1000) # Find all unique user addresses that received an NFT from burn address users = process_events(transfers) # Save list as a CSV output_path = "files/output" output_name = address + "_" + str(BLOCK) + ".csv" data.save(users, output_path, output_name, ["Address"]) ################################################## def process_events(logs): """ Function to take a list of raw events and process into a list of addresses for further processing. """ print("Preparing to process " + str(len(logs)) + " events.") s_time = time() # Iterate over logs and organize into a list of users output = [] for log in logs: from_address = log.args["from"] # If sender is burn address, Transfer is a mint if from_address == "0x0000000000000000000000000000000000000000": output.append(log.args["to"]) e_time = time() print(colored("Processed events in " + str(round(e_time-s_time,2)) + "s",'green')) output = list(set(output)) print("Found " + str(len(output)) + " users.") return output ################################################## # Runtime Entry Point if __name__ == "__main__": args = sys.argv if len(args) == 2: address = args[1] main(address) else: print("Collection address not entered. Please try again.")