\begin{equation} y \ =\ X\mu \ +\ \epsilon \ =\ X \ (C^{-1}C)\ \ \mu \ +\ \epsilon = \ (X C^{-1}) \ (C \mu) \ + \epsilon \end{equation}\begin{equation} y \ =\ X\mu \ +\ \epsilon \ =\ XI\mu \ +\ \epsilon \ =\ X \ (C^{-1}C)\ \ \mu \ +\ \epsilon = \ (X C^{-1}) \ (C \mu) \ + \epsilon \end{equation}
Therefore we can use the first term in parentheses to evaluate the second term (our comparisons), using the least squares method, just as we did for the original equation above. This is why we use the inverse of the contrast matrix C (it is invertible, and it needs to be square and full rank in this case).
We can define any type of contrast in this way, either using the built-in functions contr.treatment(), contr.sum() etc or by specifying which comparisons we want. For its contrasts arguments, lm() expects the inverse of C without the intercept column, solve(C)[,-1], and it adds the intercept column to generate $C^{-1}$, and uses it for the modified design matrix. There are many refinements on this scheme (orthogonal contrasts, more complex contrasts, not full rank design matrix etc), but this is the gist of it (cf also here for reference: https://cran.r-project.org/web/packages/codingMatrices/vignettes/codingMatrices.pdf).