Both of these chips already has a factory-supplied bootloader that
might be suitable for your needs, avoiding the need to write your own.
Each chip has a separate 'BOOT' flash area (3KB for '035, 2KB for '003 - see datasheet memory map) that contains the bootloader code. The CH32X035 bootloader is accessible via either USB or serial UART; the CH32V003 bootloader supports only serial UART. The factory bootloader is capable of erasing, writing, and verifying the user application flash (but
not reading it out), and reading and writing the configuration option bytes. The communication protocol, while not officially documented by WCH, is fairly simple and has some open-source implementations.
However, there are some caveats:
- For the CH32V003, there is no external means of controlling the bootloader (e.g. BOOTn strapping pins); you can only signal that the bootloader is entered at next reset by writing a couple of special values to a register and commanding a software reset. Thus, it's only really useful for in-app firmware updates. But this seems to be what you want to do, so...
- My experience has been that it seems that you can only enter the bootloader of the CH32X035 from
power-on reset, and not a regular reset. I don't know why, such a restriction seems stupid to me; maybe I'm doing something wrong, but it just would not do so by simply hitting the reset button on the eval board I have.

You can also do the same thing as above to command the bootloader is entered at next reset by software, though.
- Serial UART communication generally runs only at 115,200 baud, so is a bit slow. The CH32X035 bootloader, IIRC, supports an additional 'set baud' command for faster rates, but the CH32V003 does not.
The BOOT flash area is actually writable using WCH-Link debug adapter, so you could write your own bootloader and put it there instead of the factory one if you desire. The BOOT area is inherently non-writable from user application code, so you don't need to worry about write-protection.
As for write-protection of the user flash area: you can set the WRPR0-3 values in the configuration option bytes to specify write protection of certain parts of the user flash. For the CH32X035, each bit represents a 2K sector of the flash; for the CH32V003 each bit is 1K, with WRPR2-3 unused. See reference manual "User Option Bytes" section.