def main():
    global contract_dict
    parser = argparse.ArgumentParser(description='Optional app description')
    parser.add_argument('-c', '--contract', type=str, help='the hash of the contract to scan')
    parser.add_argument('-net', '--network', type=str, help='the network, such as mainnet, carthagenet, dalphanet, delphinet or a RPC node uri', default='mainnet')
    parser.add_argument('-org', '--origin', help='find the level when the contract was deployed', action='store_true')
    parser.add_argument('-fst', '--first', help="find the contract's first update", action='store_true')
    parser.add_argument('-lst', '--last', help="find the contract's last update", action='store_true')
    parser.add_argument('-stt', '--start', type=int, help='index from where to start the scan', default=(- 1))
    parser.add_argument('-hash', '--hash', type=int, help='block hash from where to scan')
    parser.add_argument('-end', '--end', type=int, help='index until which to start the scan (from which for last update)', default=(- 1))
    args = parser.parse_args()
    contract_hash = args.contract
    if (args.contract is None):
        print('Error: Specify contract hash', '\n')
        return
    network = args.network
    p = pytezos.using(shell='mainnet')
    head_level = (- 1)
    try:
        p = pytezos.using(shell=network)
        head_level = p.shell.head.header()['level']
    except Exception as e:
        print('Error: Network error', e, '\n')
        return
    start = args.start
    if (args.hash is not None):
        try:
            block = p.shell.chains.main.blocks[args.hash]
            start = block.header()['level']
        except Exception as e:
            print('Error: block not found', e, '\n')
            return
    end = args.end
    ci = None
    storage = None
    try:
        ci = p.contract(contract_hash)
        storage = ci.storage(head_level)
    except Exception as e:
        print('Error: contract not found', e, '\n')
        return
    if (args.first == True):
        Thread(target=contract_first_update_search, args=(p, contract_hash), kwargs={'start': start}).start()
    if (args.last == True):
        thread = Thread(target=contract_last_update_search, args=(p, contract_hash), kwargs={'end': end}).start()
    if (args.origin == True):
        thread = Thread(target=contract_origin_search, args=(p, contract_hash), kwargs={'verbose': 1}).start()
    if ((args.first == False) and (args.last == False) and (args.origin == False)):
        if (contract_hash not in contract_dict.keys()):
            end2 = head_level
            if (end <= head_level):
                end2 = head_level
            Thread(target=contract_all_update_search, args=(p, contract_hash), kwargs={'start': start, 'end': end2}).start()
            if ((end == (- 1)) or (end > head_level)):
                contract_dict[contract_hash] = {'last_data': storage}
                Thread(target=read_from_head, args=(p,)).start()
        else:
            print('Error: contract already being scanned.', '\n')
    while (len(contract_dict) != 0):
        try:
            inputs = input('\n\nFunctions:\n  add <hash> --start <start> --end <end>\n  remove <hash>\n  origin <hash> \n  first <hash> --start <start>\n  last <hash> --end <end>\n  list\n\n').strip()
            inputs = inputs.split(' ')
            if (inputs[0].lower() in ['add', 'remove', 'origin', 'first', 'last', 'list']):
                if (inputs[0].lower() == 'list'):
                    for key in contract_dict.keys():
                        print(key)
                    print('\n')
                else:
                    try:
                        contract_hash = inputs[1]
                        storage = p.contract(contract_hash).storage()
                        (originated_level, originated_data) = contract_origin_search(p, contract_hash)
                        head_level = p.shell.head.header()['level']
                        start = (- 1)
                        if ('--start' in inputs):
                            stt = int(inputs[(inputs.index('--start') + 1)])
                            start = stt
                            if (stt < originated_level):
                                start = originated_level
                        end = (- 1)
                        if ('--end' in inputs):
                            end = int(inputs[(inputs.index('--end') + 1)])
                        if (inputs[0] == 'first'):
                            Thread(target=contract_first_update_search, args=(p, contract_hash), kwargs={'start': start}).start()
                        if (inputs[0] == 'last'):
                            Thread(target=contract_last_update_search, args=(p, contract_hash), kwargs={'end': end}).start()
                        if (inputs[0] == 'origin'):
                            Thread(target=contract_origin_search, args=(p, contract_hash), kwargs={'verbose': 1}).start()
                        if (inputs[0] == 'add'):
                            end2 = head_level
                            if (end <= head_level):
                                end2 = end
                            Thread(target=contract_all_update_search, args=(p, contract_hash), kwargs={'start': start, 'end': end2}).start()
                            if (((end == (- 1)) or (end > head_level)) and (contract_hash not in contract_dict.keys())):
                                contract_dict[contract_hash] = {'last_data': storage}
                        if (inputs[0] == 'remove'):
                            if (contract_hash in contract_dict.keys()):
                                del contract_dict[contract_hash]
                                print((('Contract ' + str(contract_hash)) + ' removed.\n'))
                    except Exception as e:
                        print('Error: contract not found', e, '\n')
            else:
                print('Error command not recognized', inputs, '\n')
        except Exception as e:
            print(e)
    print('No more contract to scan, closing program.\n')
def main():
    global contract_dict
    parser = argparse.ArgumentParser(description='Optional app description')
    parser.add_argument('-c', '--contract', type=str, help='the hash of the contract to scan')
    parser.add_argument('-net', '--network', type=str, help='the network, such as mainnet, carthagenet, dalphanet, delphinet or a RPC node uri', default='mainnet')
    parser.add_argument('-org', '--origin', help='find the level when the contract was deployed', action='store_true')
    parser.add_argument('-fst', '--first', help="find the contract's first update", action='store_true')
    parser.add_argument('-lst', '--last', help="find the contract's last update", action='store_true')
    parser.add_argument('-stt', '--start', type=int, help='index from where to start the scan', default=(- 1))
    parser.add_argument('-hash', '--hash', type=int, help='block hash from where to scan')
    parser.add_argument('-end', '--end', type=int, help='index until which to start the scan (from which for last update)', default=(- 1))
    args = parser.parse_args()
    contract_hash = args.contract
    if (args.contract is None):
        print('Error: Specify contract hash', '\n')
        return
    network = args.network
    p = pytezos.using(shell='mainnet')
    head_level = (- 1)
    try:
        p = pytezos.using(shell=network)
        head_level = p.shell.head.header()['level']
    except Exception as e:
        print('Error: Network error', e, '\n')
        return
    start = args.start
    if (args.hash is not None):
        try:
            block = p.shell.chains.main.blocks[args.hash]
            start = block.header()['level']
        except Exception as e:
            print('Error: block not found', e, '\n')
            return
    end = args.end
    ci = None
    storage = None
    try:
        ci = p.contract(contract_hash)
        storage = ci.storage(head_level)
    except Exception as e:
        print('Error: contract not found', e, '\n')
        return
    if (args.first == True):
        Thread(target=contract_first_update_search, args=(p, contract_hash), kwargs={'start': start}).start()
    if (args.last == True):
        thread = Thread(target=contract_last_update_search, args=(p, contract_hash), kwargs={'end': end}).start()
    if (args.origin == True):
        thread = Thread(target=contract_origin_search, args=(p, contract_hash), kwargs={'verbose': 1}).start()
    if ((args.first == False) and (args.last == False) and (args.origin == False)):
        if (contract_hash not in contract_dict.keys()):
            end2 = head_level
            if (end <= head_level):
                end2 = head_level
            Thread(target=contract_all_update_search, args=(p, contract_hash), kwargs={'start': start, 'end': end2}).start()
            if ((end == (- 1)) or (end > head_level)):
                contract_dict[contract_hash] = {'last_data': storage}
                Thread(target=read_from_head, args=(p,)).start()
        else:
            print('Error: contract already being scanned.', '\n')
    while (len(contract_dict) != 0):
        try:
            inputs = input('\n\nFunctions:\n  add <hash> --start <start> --end <end>\n  remove <hash>\n  origin <hash> \n  first <hash> --start <start>\n  last <hash> --end <end>\n  list\n\n').strip()
            inputs = inputs.split(' ')
            if (inputs[0].lower() in ['add', 'remove', 'origin', 'first', 'last', 'list']):
                if (inputs[0].lower() == 'list'):
                    for key in contract_dict.keys():
                        print(key)
                    print('\n')
                else:
                    try:
                        contract_hash = inputs[1]
                        storage = p.contract(contract_hash).storage()
                        (originated_level, originated_data) = contract_origin_search(p, contract_hash)
                        head_level = p.shell.head.header()['level']
                        start = (- 1)
                        if ('--start' in inputs):
                            stt = int(inputs[(inputs.index('--start') + 1)])
                            start = stt
                            if (stt < originated_level):
                                start = originated_level
                        end = (- 1)
                        if ('--end' in inputs):
                            end = int(inputs[(inputs.index('--end') + 1)])
                        if (inputs[0] == 'first'):
                            Thread(target=contract_first_update_search, args=(p, contract_hash), kwargs={'start': start}).start()
                        if (inputs[0] == 'last'):
                            Thread(target=contract_last_update_search, args=(p, contract_hash), kwargs={'end': end}).start()
                        if (inputs[0] == 'origin'):
                            Thread(target=contract_origin_search, args=(p, contract_hash), kwargs={'verbose': 1}).start()
                        if (inputs[0] == 'add'):
                            end2 = head_level
                            if (end <= head_level):
                                end2 = end
                            Thread(target=contract_all_update_search, args=(p, contract_hash), kwargs={'start': start, 'end': end2}).start()
                            if (((end == (- 1)) or (end > head_level)) and (contract_hash not in contract_dict.keys())):
                                contract_dict[contract_hash] = {'last_data': storage}
                        if (inputs[0] == 'remove'):
                            if (contract_hash in contract_dict.keys()):
                                del contract_dict[contract_hash]
                                print((('Contract ' + str(contract_hash)) + ' removed.\n'))
                    except Exception as e:
                        print('Error: contract not found', e, '\n')
            else:
                print('Error command not recognized', inputs, '\n')
        except Exception as e:
            print(e)
    print('No more contract to scan, closing program.\n')