Summary or problem description
Currently, we use System.Contract.Call to invoke a contract. But sometimes, we need to put some restrictions on the call. For example, we require that the called contract cannot call other contracts (no sub-calls); or we require that the called contract cannot modify the state (read-only mode).
Do you have any solution you want to propose?
I introduce a new SYSCALL: System.Contract.CallEx. It is very similar to System.Contract.Call. But it accepts an additional parameter to pass those restrictions on the call.
c#
object CallEx(UInt160 hash, string method, object[] args, CallFlags flags);
Neo Version
Where in the software does this update applies to?
Very interesting proposal @erikzhang ... reminds me of https://github.com/neo-project/neo/issues/446 which was after converted to Scoped Witnesses, as it focus on user perspective rather contract-defined. Yet, this can also be used in benefit of users, as Entry may specific a certain call that disables "features", such as dyn invoke, perhaps storage... etc.
In this sense, what features should we allow disabling on flags? I think at least:
It's a very good idea
Who want to implement this?
I can do it after https://github.com/neo-project/neo/pull/1362
I wonder whether we should restrict the callee's use of storage, subcall, notify. Or do we have an example that really needs this.
public enum CallFlags : byte
{
None = 0,
AllowModifyStates = 0b00000001,
AllowCall = 0b00000010,
AllowNotify = 0b00000100,
All = AllowModifyStates | AllowCall | AllowNotify
}
If it is for the security, I think it would be more reasonable to move the constraint to the manifest. If not, there is no need for the caller to concern about the callee's implementation.
It is for contracts. It is hard for a contract to read manifest before calling another contract.
There are different protections. Manifest level, and contract level.
Most helpful comment
I can do it after https://github.com/neo-project/neo/pull/1362