298 lines
8.6 KiB
Python
298 lines
8.6 KiB
Python
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,
|
||
'blindBox': {
|
||
'user_hold': 0,
|
||
'open': 0,
|
||
'total': 0,
|
||
'merchant_hold': 0
|
||
},
|
||
'nft_rank': [
|
||
],
|
||
'nft_hero_box_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['blindBox']['total'] += 1
|
||
boxUser[tokenId] = toAddress
|
||
if toAddress == EMPTY_ADDRESS:
|
||
stat['blindBox']['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['blindBox']['total'] - stat['blindBox']['open'])
|
||
stat['blindBox']['merchant_hold'] = len(merchant_box)
|
||
stat['blindBox']['user_hold'] = stat['blindBox']['total'] - stat['blindBox']['open'] - stat['blindBox']['merchant_hold']
|
||
for key, value in boxUser.copy().items():
|
||
if value == MERCHANT_ADDRESS:
|
||
del boxUser[key]
|
||
assert(len(boxUser) == stat['blindBox']['user_hold'])
|
||
userHoldNums = {}
|
||
userHoldHeroBoxNums = {}
|
||
for key, value in boxUser.items():
|
||
userHoldNums[value] = 1
|
||
for row in nftTable:
|
||
ownerAddress = row['owner_address'].lower()
|
||
if ownerAddress != EMPTY_ADDRESS and ownerAddress != '':
|
||
if row['token_type'] != '4':
|
||
stat['nft_total'] += 1
|
||
stat['nft_mint'] += 1
|
||
if ownerAddress not in userHoldNums:
|
||
userHoldNums[ownerAddress] = 1
|
||
else:
|
||
userHoldNums[ownerAddress] += 1
|
||
if row['token_type'] == '1':
|
||
if ownerAddress not in userHoldHeroBoxNums:
|
||
userHoldHeroBoxNums[ownerAddress] = {
|
||
'hero': 1,
|
||
'box': 0,
|
||
'nftNum': 1
|
||
}
|
||
else:
|
||
userHoldHeroBoxNums[ownerAddress]['hero'] += 1
|
||
userHoldHeroBoxNums[ownerAddress]['nftNum'] += 1
|
||
if row['token_type'] == '4':
|
||
if ownerAddress not in userHoldHeroBoxNums:
|
||
userHoldHeroBoxNums[ownerAddress] = {
|
||
'hero': 0,
|
||
'box': 1,
|
||
'nftNum': 1
|
||
}
|
||
else:
|
||
userHoldHeroBoxNums[ownerAddress]['box'] += 1
|
||
userHoldHeroBoxNums[ownerAddress]['nftNum'] += 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['blindBox']['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)
|
||
|
||
#
|
||
userHoldHeroBoxList = []
|
||
for key, value in userHoldHeroBoxNums.items():
|
||
if value['nftNum'] > 1:
|
||
userHoldHeroBoxList.append(
|
||
{
|
||
'address': key,
|
||
'hero': value['hero'],
|
||
'box': value['box'],
|
||
'nftNum': value['nftNum']
|
||
}
|
||
)
|
||
#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_hero_box_rank'] = sorted(userHoldHeroBoxList, key=functools.cmp_to_key(cmpFunc))
|
||
for i in range(len(stat['nft_hero_box_rank'])):
|
||
stat['nft_hero_box_rank'][i]['rank'] = i + 1
|
||
rankList = [
|
||
(
|
||
'address',
|
||
'hero',
|
||
'box',
|
||
'nftNum',
|
||
'rank'
|
||
)
|
||
]
|
||
for item in stat['nft_hero_box_rank']:
|
||
rankList.append(
|
||
(
|
||
item['address'],
|
||
item['hero'],
|
||
item['box'],
|
||
item['nftNum'],
|
||
item['rank']
|
||
)
|
||
)
|
||
with open('nft_hero_box_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()
|