Thank you @Skyge! I read it. I got the basics things. But I don't understand this: Let's say we upgraded our contract. Then what happens to the balances in v1? Do I need a Proxy contract and my state (in this case, balances) in that Proxy contract or something else? I can't get it
UUPS, just like all upgradeable proxy pattern rely on two things:
A proxy
An implementation
The code you shared corresponds to the code for an implementation with UUPS support. This means that you'll need a UUPS proxy pointing to that implementation.
The proxy is what users will interact with, and where all the state is stored. The implementation is just here to tell the proxy how to behave.
If you ever do an upgrade, you'll need to create a new implementation (that codes for a new behavior) and tell the proxy to use that instead. There is no new proxy. You keep the same proxy, at the same address, with the same data in storage. You just "upgrade" its implementation.