Open lexfrl opened 4 years ago
How does destruction work?
The contract itself must define a self-destruction logic.
Interesting side-effect on testing experience: seems like this might be a significant improvement for unit-testing also, since it's unlocking testability of a contract initialization.
Updated the text a bit.
The contract itself must define a self-destruction logic.
There needs to be something in the runtime that allows this. Otherwise you can only destroy data associated with the contract but not the contract itself.
Right. It must be allowed to call Deploy action if action was created by the contract code.
In short, we just restrict any "sender = receiver" calls if account.code
is not empty. DeployAction can contain empty Vec<u8>
.
But you're right, the problem is that it seems like we don't have action type witch just erases the contract state. AccountDelete does that (but it also deletes an account, which is unfortunate).
Actually I don't think the self-destruction logic is necessary. We can just delete everything stored under ContractData
prefix.
Actually I don't think the self-destruction logic is necessary.
It could be (maybe) useful if a contract has some (if any) obligations towards to other contracts/accounts.
as a follow-up to the protocol research group discussion 30.06.2020
At the moment Near runtime doesn't have a notion for a contract lifetime. Lack of a contract lifetime logic negatively affects the following areas:
From a DevX perspective, developer has to keep in mind to not forget to define the deployment procedure outside to the contract source code - there is no other choice but to define and maintain the deployment script separately. It's also not prefect for a bunch of reasons:
The list is not exhaustive.
The proposal
I suggest to upgrade runtime by introducing the explicit notion of a contract lifetime. This shouldn't require a lot of changes to the code, thought impact on the runtime semantics and DeX experience are significant.
Implementation steps
1) Reserve a function export symbol
_init
; 2) Extend the Deploy action to carry arguments (Vec<u8>
); 3) Extend Runtime to call the_init
function export with provided arguments as part of the Deploy action processing and update the contract state. 4) Restrict the direct (full) access to the account on the initial code deployment. Relax it back whenaccount.code
empty.As a new default, we should take out the arbitrary ability of altering code from an external actor which is made with no respect to the logic of the deployed contract. From the moment of deployment till destruction, account is fully managed by the contract code- that should be an axiom. Not having this default is not safe since it opens a window for leaks to the contact invariants. I suggest the following: Deploy action should check if there is a code deployed and should restrict a FullAccess into the account, since otherwise that opens a direct external access to the internal account state which consistency is ought to be maintained by the contract. Having this rule may improve trustability of contracts due to a better semantic expressiveness of operation (and because the argument is valid and its premises are true, the argument is sound).
Note: fees are not covered in this proposal (CC @olonho)
CC @amgando @evgenykuzyakov @nearmax @willemneal @SkidanovAlex @ilblackdragon @frol @bowenwang1996