craft-nft

A standalone NFT implementation for real-world arts and crafts assets
Info | Log | Files | Refs | README

dump.py (4598B)


      1 """Output information about all minted tokens
      2 
      3 .. moduleauthor:: Louis Holbrook <dev@holbrook.no>
      4 .. pgp:: 0826EDA1702D1E87C6E2875121D2E7BB88C2A746 
      5 
      6 """
      7 
      8 # SPDX-License-Identifier: GPL-3.0-or-later
      9 
     10 # standard imports
     11 import sys
     12 import os
     13 import json
     14 import argparse
     15 import logging
     16 import time
     17 from enum import Enum
     18 
     19 # external imports
     20 import chainlib.eth.cli
     21 from chainlib.chain import ChainSpec
     22 from chainlib.eth.constant import ZERO_ADDRESS
     23 from chainlib.settings import ChainSettings
     24 from chainlib.eth.settings import process_settings
     25 from chainlib.eth.cli.arg import Arg
     26 from chainlib.eth.cli.arg import ArgFlag
     27 from chainlib.eth.cli.arg import process_args
     28 from chainlib.eth.cli.log import process_log
     29 from chainlib.eth.cli.config import Config
     30 from chainlib.eth.cli.config import process_config
     31 from hexathon import strip_0x
     32 from hexathon import add_0x
     33 
     34 # local imports
     35 from craft_nft import CraftNFT
     36 from craft_nft.nft import to_batch_key
     37 
     38 logg = logging.getLogger()
     39 
     40 def process_config_local(config, arg, args, flags):
     41     contract = None
     42     try:
     43         contract = config.get('_EXEC_ADDRESS')
     44     except KeyError:
     45         pass
     46 
     47     if contract == None:
     48         address = config.get('_POSARG')
     49         if address:
     50             contract = add_0x(address)
     51         else:
     52             contract = stdin_arg()
     53 
     54     config.add(contract, '_CONTRACT', False)
     55 
     56     config.add(100000, '_FEE_LIMIT', True)
     57 
     58     token_id = None
     59     if args.token_id != None:
     60         token_id = strip_0x(args.token_id)
     61         bytes.fromhex(token_id)
     62     config.add(token_id, '_TOKEN_ID', False)
     63 
     64     return config
     65 
     66 
     67 arg_flags = ArgFlag()
     68 arg = Arg(arg_flags)
     69 
     70 flags = arg_flags.STD_READ | arg_flags.EXEC | arg_flags.TAB
     71 
     72 argparser = chainlib.eth.cli.ArgumentParser()
     73 argparser = process_args(argparser, arg, flags)
     74 argparser.add_argument('--token-id', dest='token_id', type=str, help='List mints for this token id only')
     75 argparser.add_argument('contract_address', type=str, help='Token contract address (may also be specified by -e)')
     76 args = argparser.parse_args()
     77 
     78 logg = process_log(args, logg)
     79 
     80 config = Config()
     81 config = process_config(config, arg, args, flags, positional_name='contract_address')
     82 config = process_config_local(config, arg, args, flags)
     83 logg.debug('config loaded:\n{}'.format(config))
     84 
     85 settings = ChainSettings()
     86 settings = process_settings(settings, config)
     87 logg.debug('settings loaded:\n{}'.format(settings))
     88 
     89 
     90 def render_token_batches(c, conn, token_address, token_id, w=sys.stdout):
     91     i = 0
     92     while True:
     93         o = c.get_token_spec(token_address, token_id, i)
     94         r = None
     95         try:
     96             r = conn.do(o)
     97         except:
     98             break
     99         spec = c.parse_token_spec(r)
    100 
    101         if spec.sparse:
    102             logg.info('sparse token issuance detected. Will iterate through {} tokens, may take a while'.format(spec.count))
    103             for j in range(spec.count):
    104                 token_id_indexed = to_batch_key(token_id, i, j)
    105                 try:
    106                     render_token_mint(c, conn, token_address, token_id_indexed, w=w)
    107                 except:
    108                     pass
    109         else:
    110             for j in range(spec.cursor):
    111                 token_id_indexed = to_batch_key(token_id, i, j)
    112                 render_token_mint(c, conn, token_address, token_id_indexed, w=w)
    113 
    114         i += 1
    115 
    116 
    117 def render_token_mint(c, conn, token_address, token_id, w=sys.stdout):
    118     o = c.get_token(token_address, token_id)
    119     r = conn.do(o)
    120     token = c.parse_token(r, token_id)
    121     if token.minted:
    122         w.write('token {}\n'.format(token))
    123 
    124 
    125 def render_token(c, conn, token_address, token_id, w=sys.stdout):
    126     token_id = strip_0x(token_id)
    127     o = c.get_token_spec(token_address, token_id, 0)
    128     r = conn.do(o)
    129     spec = c.parse_token_spec(r)
    130     if spec.count > 0:
    131         return render_token_batches(c, conn, token_address, token_id, w=sys.stdout)
    132 
    133     return render_token_mint(c, conn, token_address, token_id, w=w)
    134 
    135 
    136 def main():
    137     token_address = config.get('_CONTRACT')
    138     conn = settings.get('CONN')
    139     c = CraftNFT(
    140             chain_spec=settings.get('CHAIN_SPEC'),
    141             gas_oracle=settings.get('GAS_ORACLE'),
    142             )
    143 
    144     outkeys = config.get('_OUTARG')
    145 
    146     i = 0
    147 
    148     if config.get('_TOKEN_ID') != None:
    149         render_token(c, conn, token_address, config.get('_TOKEN_ID'))
    150         return
    151 
    152     while True:
    153         o = c.token_at(token_address, i)
    154         r = None
    155         try:
    156             r = conn.do(o)
    157         except:
    158             break
    159         render_token(c, conn, token_address, r)
    160         i += 1
    161 
    162 
    163 if __name__ == '__main__':
    164     main()