import csv import json import datetime import functools # 1.NFT总量 (宝箱+赠送+open宝箱) # 2.NFT mint数量 (卖出的宝箱+赠送) # 3.NFT宝箱已开和未开数量(总数即可) # 4.NFT持有人数量排序 (已购的宝箱+赠送) mintTable = [] nftTable = [] nftTransferTable = [] contracts = lambda : json.load(open('contract.json', 'r')) stat = { 'nft_total': 0, 'nft_mint': 0, 'bindBox': { 'user_hold': 0, 'open': 0, 'total': 0, 'merchant_hold': 0 }, 'nft_rank': [ ] } EMPTY_ADDRESS = '0x0000000000000000000000000000000000000000'.lower() MERCHANT_ADDRESS = '0x14ea40648fc8c1781d19363f5b9cc9a877ac2469'.lower() merchant_box = {} def exportMintTable(): rows = [] with open('mint.raw.csv', 'w', newline='') as f: writer = csv.writer(f) writer.writerows(rows) def exportNftTable(): rows = [] with open('nft.raw.csv', 'w', newline='') as f: writer = csv.writer(f) writer.writerows(rows) def exportNftTransferTable(): rows = [] with open('nft_transfer.raw.csv', 'w', newline='') as f: writer = csv.writer(f) writer.writerows(rows) def exportNftSumTable(): rows = [] for nft in nftTable: rows.push( ( nft['token_id'], nft['token_type'], nft['creator_address'], nft['owner_address'], nft['tags'], datetime.datetime.fromtimestamp(nft['modifytime']) ) ) with open('nft.sum.csv', 'w', newline='') as f: writer = csv.writer(f) writer.writerows(rows) def statData(): userNftNums = {} boxUser = {} for row in nftTransferTable: rawData = json.loads(row['raw_data']) if rawData['address'].lower() == '0x8444404bD78089A5a6d5Cc57f7Df8924f2DdACB4'.lower() and \ rawData['event'] == 'Transfer': fromAddress = rawData['returnValues']['from'].lower() toAddress = rawData['returnValues']['to'].lower() tokenId = rawData['returnValues']['tokenId'].lower() if fromAddress == EMPTY_ADDRESS: stat['nft_total'] += 1 stat['bindBox']['total'] += 1 boxUser[tokenId] = toAddress if toAddress == EMPTY_ADDRESS: stat['bindBox']['open'] += 1 del boxUser[tokenId] else: boxUser[tokenId] = toAddress if toAddress == MERCHANT_ADDRESS: merchant_box[rawData['returnValues']['tokenId']] = 1 if fromAddress == MERCHANT_ADDRESS: del merchant_box[rawData['returnValues']['tokenId']] #end for assert(len(boxUser) == stat['bindBox']['total'] - stat['bindBox']['open']) stat['bindBox']['merchant_hold'] = len(merchant_box) stat['bindBox']['user_hold'] = stat['bindBox']['total'] - stat['bindBox']['open'] - stat['bindBox']['merchant_hold'] for key, value in boxUser.copy().items(): if value == MERCHANT_ADDRESS: del boxUser[key] assert(len(boxUser) == stat['bindBox']['user_hold']) userHoldNums = {} for key, value in boxUser.items(): userHoldNums[value] = 1 for row in nftTable: ownerAddress = row['owner_address'].lower() if ownerAddress != EMPTY_ADDRESS and ownerAddress != '' and row['token_type'] != '4': stat['nft_total'] += 1 stat['nft_mint'] += 1 if ownerAddress not in userHoldNums: userHoldNums[ownerAddress] = 1 else: userHoldNums[ownerAddress] += 1 #end for userHoldList = [] for key, value in userHoldNums.items(): if value > 1: userHoldList.append( { 'address': key, 'nftNum': value } ) #end for def cmpFunc(a, b): if a['nftNum'] > b['nftNum']: return -1 elif a['nftNum'] < b['nftNum']: return 1 else: return 0 stat['nft_rank'] = sorted(userHoldList, key=functools.cmp_to_key(cmpFunc)) for i in range(len(stat['nft_rank'])): stat['nft_rank'][i]['rank'] = i + 1 stat['nft_mint'] += stat['bindBox']['merchant_hold'] rankList = [ ( 'address', 'nftNum', 'rank' ) ] for item in stat['nft_rank']: rankList.append( ( item['address'], item['nftNum'], item['rank'] ) ) with open('nft_rank.csv', 'w', newline='') as f: writer = csv.writer(f) writer.writerows(rankList) print(json.dumps(stat, indent=4)) def loadData(): def rowToObj(row, fields): #print(row) #print(len(row), len(fields)) assert(len(row) == len(fields)) obj = {} for idx in range(len(fields)): obj[fields[idx]] = row[idx] return obj def loadCsv(data, fileName, fields): print(fileName) with open(fileName, "r", encoding="utf-8") as f: reader = csv.reader(f, delimiter='#') for row in reader: data.append(rowToObj(row, fields)) loadCsv(mintTable, 't_mint.txt', [ 'idx', 'unikey', 'account', 'game_id', 'ignore', 'bc_minted', 'bc_mint_txhash', 'bc_mint_itemid', 'bc_mint_tokenid', 'bc_mint_token_type', 'bc_mint_tags', 'bc_mint_count', 'bc_mint_time', 'bc_mint_prepare_block_number', 'bc_mint_success_block_number', 'bc_mint_confirm_time', 'suspend', 'suspend_reason', 'done', 'createtime', 'modifytime' ]) loadCsv(nftTable, 't_nft.txt', [ 'idx', 'owner_address', 'creator_address', 'token_id', 'token_type', 'token_state', 'game_id', 'item_id', 'deleted', 'opened', 'confirm_count', 'confirm_block_number', 'rand_attr', 'tags', 'createtime', 'modifytime' ]) loadCsv(nftTransferTable, 't_nft_transfer.txt', [ 'idx', 'token_id', 'txhash', 'block_number', 'log_index', '_from', '_to', 'raw_data', 'owner_confirmed', 'createtime', 'modifytime' ]) loadData() statData()