def _find_path(graph, start_addr, end_addr):
    """Determines if there is a path from start_addr to end_addr (note that
    edges in the graph are unidirectional).

    Args:
        graph, dict, a dict that maps a string (the sending address) to a set
            that contains every address that has received BTC from the sending
            address
        start_addr, string, the starting (sending) address for the path
        end_addr, string, the ending (receiving) address for the path

    Returns:
        None, if no path, otherwise a list of addresses representing the path
    """

    if type(graph) is not dict:
        raise TypeError("graph should be a dictionary")

    if start_addr not in graph:
        return None

    # now, we perform a DFS...

    parent_mapping = {} # maps a child addr to its parent
    stack = []
    stack.insert(0, start_addr) # the equivalent of push()

    while len(stack) > 0:
        addr = stack.pop()

        # if the current address being considered is the end address, we need
        # traverse back through the graph to start_addr and keep track of the 
        # path along the way

        if addr == end_addr:
            path = []
            path.append(addr)
            parent = parent_mapping[addr]

            while parent != start_addr:
                path.append(parent)
                parent = parent_mapping[parent]

            path.append(parent)

            return path

        for child_addr in graph[addr]:
            stack.insert(0, child_addr)
            parent_mapping[child_addr] = addr

    return None