Contracts that are not "usable" anymore

What will happen to contracts that are not “usable” anymore? Is there something like unpublishcontract function? With “unusable” I mean that all functions return with an err.

In that context, I would like to know how to change an existing smart contract, at least in theory?

You can’t change a smart contract after it is deployed. That’s the whole point of the smart contract computing paradigm.

If you want to render your smart contract unusable, you’ll have to add the code to do so yourself. For example, you could add a persistent variable in your contract that acts as a global “off switch” for all of your contract’s public functions.

Insofar as upgrades, the recommended way to upgrade a smart contract is to deploy a new version of the smart contract, and seamlessly read state from the prior version of the contract via the (at-block ...) built-in function. You would need to update any other software that interacts with the smart contract to use the latest version. To make this seamless, you could write a separate smart contract that stores the contract address of the latest version, which your off-chain app inspects in order to determine which version of the smart contract to use. You’d set up this “lookup” contract so that only you, the developer could set the contract address version for the app to use.

What would happen with these contracts? Would they still take space on the nodes? Could nodes decide to remove the code?

They cannot be removed. Otherwise, new nodes would be unable to bootstrap, since they wouldn’t have all of the block state. This is true for all blockchains, and is part of the social contract they encode: that anyone, anywhere can independently audit the chain state and the materialized view it represents.

And what about contracts that are not used anymore and the state is not needed anymore? Like selfdestruct in ethereum?

There isn’t a selfdestruct function in Clarity, but I’m open to adding one. Want to open an issue for it here?