Notice: Polkadot is undergoing AssetHub migration scheduled for November 4, around 8 AM UTC (block number 28,490,502).Learn more
Patract Hub’s treasury proposal for Ask! v0.2 (ink! in AS)

Patract Hub had finished the development for Ask! v0.1 (funded by Treasury #66) and written a report #494. Ask!'s goal is to provide a set of contract framework and compilation tools using AssemblyScript (aka AS) as the programming language. Contracts written through Ask! can run in the FRAME Contracts Pallet, and eventually can call each other with contracts written by ink!.
v0.2 main functions
This proposal will add the following new features on the basis of v0.1.
1. Add spread and packed data storage methods
In the v0.1, we have implemented the basic data types i8/u8, i16/u16, i32/u32, i64/u64, string, The save and load function of bool, in the v0.2, we will support the save and load of map, array, object and other composite data types. In order to provide flexibility in data storage, but also for storage efficiency on certain scenarios, we will provide two storage methods: spread and packed.
@storageis specified as a persistent storage class, and it is stored in the way ofspreadby default, that is: the preprocessor will generate a key for each member in the storage class, and then use the hash of this key as the index , save the value of the member variable to the chain, and the saved data value is the original value of the member variable, without compression and other operations;- The 
packedmethod is used to store a member (especially compound members, such as object, map, array) in a packed manner. If a member is designated as a packed member, its sub-members will not continue to expand, but to save and load as a whole. And it will be compressed when saving, and decompressed when loading. The members stored inpackedmethod need to be explicitly specified by the developer using the@packedannotation. 
For the part of the composite type, the types commonly used in std are basically implemented in ink!. As far as Ask! is concerned, this version provides a **complete infrastructure for composite types **, and implements the most commonly used composite types. Therefore, like ink!, the corresponding realization of multiple composite types needs to be gradually supplemented in future versions.
2. Add new annotations and extend the supported annotation functions
The basic functions of the four annotations @contract, @storage, @constructor, and @message have been implemented in the v0.1. In this proposal, their functions will be improved and @event annotations will be introduced to support event functions.
- Introduce 
@ignoreand@packedfor@storageclass.- The 
@ignoreannotation is used to indicate that a particular member variable does not need to be persistently stored. It only saves the set value during one call, and after the call is completed, it is destroyed from memory. - The 
@packedannotation is used to indicate that a member variable is stored in a packed and compressed manner. 
 - The 
 - Introduce parameters 
payable,mutates,selectorfor@messageannotation.- The 
payableparameter is used to indicate whether the message can accept value. The default value isfalse. - The 
mutatesparameter is used to indicate whether the message changes the value of the stored data. The default value istrue. - The 
selectorparameter is to specify the selector of the message, that is, if the name of the message is changed, its selector will also use the specified value. 
 - The 
 - Added 
@eventand@topicannotations to support event functions.@eventacts on the class, and the preprocessor will generate theemitlogic code for this class.@topicacts on the member variables of the event class. The marked member variables will be written into the topic field.
 
3. Add contract inheritance function
This function is mainly for the preprocessor to process the inheritance relationship between two classes annotated with @contract. AS language itself supports class inheritance, so the main job of the preprocessor is to process @message, @constructor , @storage , these three annotations related to the contract function. Due to class inheritance, the message and constructor methods will be overridden. At this time, the preprocessor determines the call of the call entry function based on the actual contract writing assign logic, and generate the content of the corresponding field in metadata.json.
The function will follow the following principles:
- The 
@constructormethod is mainly based on subclasses. If it is not provided in the subclass, it is ignored. Because the parent class cannot know the member variables in the subclass, it cannot initialize the contract completely. - The 
@messagemethod uses the union of all messages in the parent class and the subclass. If an override occurs, the message in the subclass is the main one. @storageis not encapsulated, the inheritance relationship is determined by the developer.
ink! currently does not have the ability to inherit/reuse contracts, so Ask! has no reference samples, see issue: [https://github.com/paritytech/ink/issues/625](https://github.com /paritytech/ink/issues/625). In this version, Ask! will implement the corresponding grammatical features of AssemblyScript to simulate the effect of contract inheritance in Solidity.
Because there is no reference sample in this part, the time-consuming implementation may be biased, the completeness of the implementation cannot be clearly guaranteed, and there may be some edge problems that cannot be handled. In short, this part will be designed with reference to the implementation of Solidity. If this part can be implemented successfully, the Ask! contract has features that the ink! contract does not have, and this feature is of great significance to the prosperity of the contract ecosystem .
4. Add the function of cross-contract call by specifying @dynamic class
In the v0.1 version, we have supported the function of using Abi.ts for cross-contract calls, that is, using the following methods:
  let data = Abi.encode("addFunc", [new UInt32(1), new UInt32(2)]);
  let val = this.another.call(data);
However, this method is not conducive to code reuse and maintenance, so the @dynamic annotation is introduced to indicate that a class can be called across contracts.
The @dynamic function is the cornerstone of the definition of contract standards, and is an indispensable function in the contract. Based on this function, the interface can be designed for the contract and the agreement can be made similar to ERC20.
@dynamic acts on the class, the class marked as dynamic, the preprocessor will generate remote call logic for each of its methods, developers do not need to write implementation logic for the methods of the dynamic class. The use of dynamic will be as follows The code shows:
// define a class as dynamic
@dynamic
class IERC20 {
    transfer(from: AccountId, to: AccountId, value: u128): void {}
}
// use dynamic class.
let ksm = new IERC20(new AccountId('0x12345678...'));
ksm.transfer(msg.sender, this.address, msg.value);
Here we don't use the interface keyword, because the interface in AS cannot be a new instance, and the syntax cannot support such an operation.
The definition of @dynamic is similar to the function of interface in Solidity. ink! tries to use #[ink::trait_definition] to implement this. The current design of this part is very imperfect, and a new design has been proposed recently. For details, please refer to the issue: [https://github.com/paritytech/ink/issues/631](https://github.com/ paritytech/ink/issues/631). On the other hand, we believe that the current implementation of ink! contains many problems, see issue:[https://github.com/paritytech/ink/issues/683](https://github.com/paritytech/ink/ issues/683).
Through the above discussion, it can be seen that this feature needs to be carefully designed and there are also various problems in the current ink! design. Therefore, this function may encounter unexpected problems in practice, so this part may also exceed the expected time in practice. Due to language features, we expect that the implementation of this part should be easier than the implementation of ink!.
On the other hand, we hope that the contracts written by Ask! and ink! can call each other. Therefore, in this version we will use this function to design simple cases, for example, manually write the corresponding @dynamic annotated class for the content of the ink! contract, and test the mutual call. But if the ink! contract needs to be more smoothly combined with the Ask! contract, for example, to provide the function of parsing ink!’s metadata to automatically generate the corresponding @dynamic modified class, you need to pay a lot of extra work to design according tools.  For example, combine this function with ask-cli. These extra workloads are not included in the implementation of this version and will be arranged in subsequent versions.
Expanded issues in v0.1
In v0.1, we discussed with Parity team about the type generation part in the contract metadata. The type information of metadata is very useful for third-party applications. Currently, the scale-info library is used in ink! as a library for generating contract type information. This library comes from:
- Draft: https://hackmd.io/0wWm0ueBSF26m2pBG5NaeQ?view
 - Original repo: https://github.com/type-metadata/type-metadata
 - The latest repo: https://github.com/paritytech/scale-info
 
@Robin from the parity team informed that the current scale-info is not mature enough to cover many possible situations, so it cannot be used in the Runtime of Substrate to help the Runtime generate type information in the Runtime (so the polkadot.js api needs developer to provide Extending types). And scale-info is more closely bound to the rust syntax, and in many cases it cannot be applied to the type of AS.
Therefore, for the type information part of the contract metadata, we plan to redesign a tool library for AS types and similar in function to scale-info. Since this library is for AS, its corresponding third-party parsing part also needs to be implemented. Therefore, corresponding to this library, we need to add corresponding implementations in the SDKs of different languages:
- JS/TS: @polkadot{.js}
 - Go: Himalia PatractGo: https://github.com/patractlabs/go-patract
 - Python: Himalia PatractPy: https://github.com/patractlabs/py-patract
 - Java: Himalia PatractJ: https://github.com/patractlabs/patractj
 - C#: Himalia PatractN: https://github.com/patractlabs/csharp-patract
 
Except for polkadot.js, the SDKs of other languages are controlled by Patract, so theoretically, we can finally achieve the type information analysis corresponding to Ask!.
However, the workload of implementing this library and the SDK of the corresponding language is huge and cumbersome. On the other hand, the export of type information does not affect the execution of the contract itself.
At the same time, scale-info itself is not mature. ** Therefore, this part will not be planned to be implemented in this version (v0.2), but is planned to be in a later version. **
Detailed timeline of v0.2 (10 weeks)
- 
Week 1~3 (3 developers):
- Design 
spreadandpackedstorage solutions. - Implement map, array and object support spread and packed layout storage methods.
 - Implement the compression and decompression logic in packed mode.
 
 - Design 
 - 
Week 4~5 (3 developers):
- Implement the 
@eventannotation, including the @event sub-annotation@topic. Implement the event function in the contract. - Add sub-notes of 
@storageannotation. 
@ignore: Ignored data members, marked data members will not be persisted.@packed: Persistence in packed mode for array&map and other types. By default, persistence in spread mode is performed.
- Add sub-annotation of 
@messageannotation:Supports annotations like@message(payable, mutates = false, selector='0x2345678'). 
payable: Indicates that the message accepts the transfer value, the default is not to accept.mutates: Indicates whether the message changes the state variable. The default value istrue.selector: Specify the selector of the message, no matter what the name of the message is, the specified selector is used.
 - Implement the 
 - 
Week 6~7 (3 developers): Implement
@dynamicannotation function.- Define the code generation logic of the 
dynamicannotation. - Generate parameter analysis of 
dynamicclass method, function body implementation and return value processing logic. 
 - Define the code generation logic of the 
 - 
Week 8~10 (3 developers): Implement contract inheritance function.
- Implement a single contract entry, hide the parent class as the contract entry.
 - Get the union of all messages on the inheritance link, and generate the 
callmethod and metadata.json information. - Get the 
@constructormethod information on the inheritance link and hide the constructor methods in all parent classes. - Generate a compilable contract expansion file and compile it into the correct wasm bytecode.
 
 
Cost of v0.2 (30 developers * weeks)
- Operating activities: $6000 ( Rent and Devices: $200 per developer * week )
 - Employee payments: $87000 ($2900 per developer * week)
 - Total Cost: $93000 and monthly average: $211 / KSM
 - Treasury Proposal: 440 KSM
 
Verification of v0.2: GitHub source code & sample contracts
The sample contracts will contain the following:
- Realize the full functions of ERC20 and ERC721 contracts.
 - Through inheritance, reuse contracts that have been written and verified.
 - Use dynamic methods for cross-contract calls.
 - Design a simple case to show how the Ask! and ink! contracts call each other.
 
Comments (0)