We are making a design decision now and we need your voice.
Since we are introducing contract factories we need to agree on the new syntax on the Sophia side of the new features. The time is up as the opcodes are already in the testing phase.
Just to remind: we are introducing 3 new primitives:
BYTECODE_HASH– takes a contract and returns the hash of its bytecode. Fairly simple.
CREATE– takes a contract bytecode (new thing), deploys it and returns contract as a callable value.
CLONE– just like create but takes an existing contract and clones it. It shall have a separate state and balance that are set up from scratch (no state cloning). It is more efficient than
CREATEsince we can share code references and therefore the gas price is significantly lower.
Here the situation seems to be obvious. There will be a new function
Chain.bytecode_hash : contract => option(hash) that takes a contract and returns hash of it. Will fallback to
None on failure.
One of the ideas brought by @cytadela8 is if we should charge gas for the introspected bytecode size as one could deploy a big contract and spam this operation (making the execution costly). On the other hand the VM could just cache the results of it.
CLONE my idea is to add a new function
Chain.clone with a named argument
clonee (to be discussed), optional protection annotation and all the arguments that its
init is going to take. It returns a thing of the same type as the cloned contract. Example:
contract Clonee = type state = int entrypoint init : int => state contract Main = entrypoint duplicate(c : Clonee) : Clonee = Chain.clone(contract = c, protected = false, 2137)
I was thinking about the OOP syntax
c.clone(21237), but this would collide with a potential
clone entrypoint of
c. Another possibility is to introduce
new keyword for this:
new c(2137), but not sure how intuitive would it be.
Question to you: the current remote calls support limitation of gas for the execution. Do you want to have this option for cloning as well? Case is that hypothetically
init can take a lot of resources. This is an important thing to agree on if we want to have this, because this affects the behavior of the VM and the arities of FATE opcodes.
Arbitrary contract creation
This will have the biggest impact on the syntax and interface. At the current state Sophia allows only one contract definition and multiple contract declarations (for the purpose of remote calls). Moreover there is an assumption that the latest toplevel entity is the main contract. While it was quite obvious back then which contract was the “main” one, as it had to be also the only one that contains entrypoints’ definitions not only type declarations, now there would be some ambiguity if we do it in the most naive way:
contract FungusToken = entrypoint init() = ... contract FungibleToken = entrypoint init() = ... contract FunnyToken = entrypoint init() = ...
…which one of these three is the main one and which are the deployable side contracts? The answer is known to devs with some insight – the last one as stated – but this is very misleading and I believe could be used to tricky frauds.
My proposal is to get rid of that “last contract” assertion and change the syntax to the following:
// Main contract contract Main = ... // Contract declaration for remote calls and cloning contract type RemoteContract = ... // Contract definition for deployment, // but also remote calls and cloning contract schema DeployableContract = ...
Note that the position of the main contract is now arbitrary and there are syntactic changes:
schemakeyword that is used to indicate a independent contract definition that is used only as a type declaration and a base for the new “create” feature
- requirement to add
contractkeyword and contract’s name in contract type declaration
While I am pretty convinced to the
type keyword, I have doubts about
schema. How would you describe it? I decided not to change the main contract definition as it would break a lot of existing contracts. Now only those using remote calls are affected to a little extent.
Next thing is the syntax for contract deploy. Some ideas for that:
let c = Chain.create(SomeContract, arg1, arg2)
let c = SomeContract.create(arg1, arg2)
let c = SomeContract(arg1, arg2)
let c = new SomeContract(arg1, arg2)
let c : SomeContract = Chain.create(arg1, arg2)// thanks Ulf!
create word is also a matter of discussion – what would you say for
Personally I like the
new keyword, despite Java PTSD.
Proposed gas prices:
CREATE have optional
value named argument just like remote calls.
I need your opinions on the following dillemas:
- Do we want optional gas limitation on
- How do you see the syntax for contract cloning?
- How do you see the syntax for contract creation?
- What do you think about the proposed syntax for contract declarations? Asking especially about the
- Do we want to have some special gas treatment for
Stay safe and well typed!