I deployed and tested a contract (on testnet, but the same question goes for mainnet too), now I'm finished with it, moved on to new contracts. Should I remove the old one? Does it do any harm, assuming that it will never be invoked again? Removing a contract itself is another transaction so the best I can do seems like leaving it there. Is this correct? Thanks,
Should I remove the old one?
If there's no chance of either yourself or anyone else sending funds to it, then yes - it's a nice bit of housekeeping. Sending funds to a payable contract that has been
selfdestruct()ed is basically sending them into a black hole.
Removing a contract itself is another transaction so the best I can do seems like leaving it there.
SELFDESTRUCT opcode is negative gas, meaning you'll get reimbursed a certain amount for calling it as a "reward" for freeing up space in the blockchain's state. (Kinda. See below.) However, this only really deducts an amount from the overall cost of the transaction, so you'll almost certainly still be paying some amount of gas.
Your comment on a previous answer:
I guess this means I'm correct, so calling suicide on a contract does not make the blockchain lighter
Yes and no. (Probably more 'no'.)
selfdestruct() you're removing the reference to the contract's bytecode and storage from the state trie/database. Specifically, you're removing the reference from the current block and all future blocks. So slightly "lighter" and less complex, in that you've removed an entry in a trie.
However, the blockchain effectively keeps a track of its entire history, so blocks before the current block will still have a reference to the removed bytecode. This means that full nodes will still have a copy of the contract code (because they have all the state from all the blocks, ever).
(An analogy would be NULLifying a pointer in C, without actually freeing the memory first. The memory is still allocated, you just can't access it anymore.)
Relevant previous answers: