When a contract is upgraded, its hash will be changed. This will cause trouble to the upgrade of the contract. Because after each upgrade, all DApps and related contracts must be reconfigured. If we keep the hash unchanged when upgrading the contract, the upgrade process will become very smooth.
Will this introduce unsafe factors? My answer is no. Because even now, by deploying two contracts with exactly the same methods, it is possible to keep the contract hash unchanged. Of these two contracts, one provides entries and forwards the calls to the other contract that provides functions. The entry contract does not need to be upgraded, and upgrading the function contract will not change the hash of the entry contract.
If we continue to retain dynamic calls, then theoretically we cannot prevent the contract from retaining the original hash after the upgrade. That being the case, why don't we provide native support?
For each deployed contract, there is a unique ID assigned. Maybe we should modify Contract.Call to allow the contract to be called directly by ID. For scenarios that must be called by scripthash, such as for Witness, we introduce:
scripthash=hash(SYSCALL(Contract.Call, ID))
In this way, we also solved the problem #1973 solved.
Why don't we just identify deployed contracts by ID?
For me it is dangerous that a contract can be updated without changing the way it is called, the hash. Because if the logic has changed, the dapp or the user will not find out and by going to call the contract, he will be able to execute a different code than the one he previously used. It will open doors to scams.
I guess the assumption is that the contract is controlled (created/updated) by its authors, so if they decide to ruin it --- you can't do anything about it.
Dapps need to know when the logic was changed. If they need to listen the update event always...
Hash has two purposes, identify the contract and versioning, if we remove the versioning, we will introduce a new problem.
That's true, there are no compatibility guarantees on upgrade, but maybe we should try to force it a little? Disallow changing method's signatures on update, for example. It doesn't prevent breaking implementation of a method of course, so contract's author is still responsible for that.
And changing hashes on update has some problems of its own, especially for payable contracts (I mean, not related to #1973, like users sending tokens to the old address).
And changing hashes on update has some problems of its own, especially for payable contracts (I mean, not related to #1973, like users sending tokens to the old address).
This can be solved with https://github.com/neo-project/neo/pull/2012 if we store the old contract, without script, flagged as removed.
The fact is that as long as we provide dynamic calls, the contract can change the logic without changing the hash.
The fact is that as long as we provide dynamic calls, the contract can change the logic without changing the hash.
Yes, you are right. I'm not against keeping the hash unchanged when updating contracts, but I think it's better to compute the hash with the nef file instead of the state. If we bind the script's hash to the states, we can have problems with offline nodes.
but I think it's better to compute the hash with the nef file instead of the state. If we bind the script's hash to the states, we can have problems with offline nodes.
Make sense.
Then, Let's go on. @erikzhang @shargon Preview4 is waiting for https://github.com/neo-project/neo/pull/1973 and https://github.com/neo-project/neo/pull/1973 is waiting for this.
For me, this is precisely the same structure as native contracts, right? We call by id, and scripthash is simply a call to that id. The option to call by id is good to allow upgrading libraries, while call by hash makes more solid assumption regarding the called contract.
In my opinion, don't use ID too much at the same time. Because we can't avoid using scripthash of the contract in many places, such as contract transfer.
In my opinion we can preserve the same hash, but is not good to have a state related hash
In my opinion we can preserve the same hash, but is not good to have a state related hash
The hash of the nef file? We don't need to move ABI to nef now.
The hash of the nef file
Yes, I can make a new PR with this change only
The hash of the nef file
Yes, I can make a new PR with this change only
Let's move on.
Most helpful comment
Why don't we just identify deployed contracts by ID?