Originally discussed in https://kusama.polkassembly.io/post/398
Ask! is a smart contract language designed based on AssemblyScript and running on Substrate FRAME Contracts. Ask! uses the similar way to ink! of designing the procedural macro in the form of eDSL, to write contracts by providing annotation type in AssemblyScript (aka AS). This way can hide the implementation details of the contract, and reduces the difficulty of writing contract. Ask! will be similar to ink!’s existing implementation, and the final product will maintain maximum compatibility with ink!’s existing standards. The WASM and metadata files compiled by Ask! can be deployed on the Substrate chain and run normally.
For example:
ink! describe the contract's external call interface through #[ink(constructor)]
, #[ink(message)]
.
In Ask!, it will describe the interface through @constructor
, @action
or other similar annotation.
AS uses the asc compiler
to compile TypeScript (TS) files into WebAssembly bytecode. However, asc is a general-purpose compilation tool, which cannot directly compile TS files into WASM bytecode and metadata information with smart contract structure. Although AS is only a subset of TS, there are a wide range of developers who use TS as a development language, so the cost of learning AS for these developers is very low. Therefore, we think the Ask! project has a very good application development prospect. Compared with Rust-based ink!, we believe that AS-based Ask! can effectively lower the threshold for contract developers and enrich the contract development ecosystem.
In addition to relying on the asc compiler, Ask! does not rely on other open source libraries or projects. In the existing projects that use AS as the smart contract development language, there are no mature projects that can be used, and the basic libraries that can be used are not perfect. The current existing approximate implementations are:
- ParityTech's AS-Substrate. The most recent commit of this project is 5 months ago, and it has not kept up with the current changes in FRAME Contracts and ink!. And in the implementation of
AS-Substrate
, it is not compatible with the existing standard described by ink!. On the other hand, AS-Substrate
has not designed syntactic sugar, annotations or other tools like ink!'s eDSL, and it cannot generate metadata or similar files.
- Slickup's SubScript. This project received a W3F Grant, but since the Grant was approved, it has not been implemented much, and the degree of completion is much lower than that of
AS-Substrate
. Its connection to FRAME Contracts host_api is still for the interface before refactoring.
Patract Hub develops local open source toolkits and one-stop cloud smart IDE, committed to provide free development toolkits and infrastructure services for the entire WASM smart contract ecosystem. We have launched 7 projects in Polkadot/Kusama Treasury, and Ask! will be our 8th project. The Github repo is https://github.com/patractlabs/ask.
FYI: the detailed tech design blow had been provided to the core team from Parity ink! and updated based on their suggestions
Design
Ask! will provide Contract Framework
(referred to as Framework
in the following description) and Contract PreProcessor
(referred to as PreProcessor
in the following description) two compontents. Besides, we will also provide a supporting tool named as ask-cli (similar to the cargo-contracts
of ink!), for helping setting up and managing WASM smart contracts written in Ask!.
their functions are defined as follows:
Framework
's main function is to provide high-level packaging for the on-chain API, and then provide the specification for writing contracts through annotation types. It needs to complete the following tasks:
- Define annotation-based contract writing specifications
- Define the description specification of the contract interface in metadata
- Encapsulate the details of the data interaction between the contract and the chain, such as the definition of the key generation rule in the contract storage and the reading and writing of the storage
- Encapsulate functional components on the chain, such as
Balance
, AccountId
, Block
, Crypto
, etc.
- Compile the AS contract into WASM code based on the semantics of the contract, and contains the link symbol for the interaction interface with FRAME Contracts.
PreProcessor
's main function is to parse the annotations defined in the Framework
, and generate corresponding logic codes for these annotations; according to the contract interface specifications in the Framework, generate metadata files. PreProcessor
needs to complete the following tasks:
- Parse the annotations in the contract and generate the corresponding logic code
- Parse contract interfaces and parameters, and generate metadata files
- Parse the custom contract grammar (syntactic sugar), and generate the corresponding logic code
- Automatic storage and loading of data
ask-cli
's main function is to manage the Ask! project in cli mode, which includes the following functions:
- Create Ask! contract template.
- Simplify the Ask! project compilation process, hide the details of the preprocessing and compilation process.
- Manage the version dependencies of Framework, PreProcessor and Compiler.
- Check the legality of the generated WASM code.
In addition, in order to facilitate developers to develop contracts through AS, Patract Hub will continue the following works:
- Add Ask! support in the our Metis smart contract library, such as SafeMath.
- Provide common contract examples consistent with ink!'s example directory, such as ERC20, ERC721 contracts, etc.
The future development plans of Ask!
v0.1(10 weeks)Define specifications of contract writing and contract method description; encapsulate on-chain interactive API and functional components
Framework
- Define contract writing specifications, define contract annotations and the logical functions corresponding to each annotation.
- Encapsulate the interface defined in the
define_env!
macro in the contract module.
- Design and implement the storage layout of metadata, which can read and write metadata.
- Implement map/array type storage layout design, which can read and write map/array types.
- Encapsulate
AccountId
, Balance
, Block
, Crypto
functional components and other env types.
PreProcessor
- Design program structures, annotation parsing method and workflow.
- Parse and generate logic codes for main annotations (@contract, @storage, @message).
- Generate metadata automatic loading and automatic storage logic code.
- Generate metadata files with complete structure.
What the product needs to achieve
- Contracts written in Ask! can be deployed and executed on Substrate
v0.2 (10 weeks) Finish all the functions of Framework and PreProcessor; provide toolset and sample code.
Framework
- Provide fully packaged functional components
- Joint testing and optimization.
- Provide assistance tools.
- Provide examples of commonly used contracts, improve the usage documents, and provide release versions.
PreProcessor
- Support parsing all annotations and syntactic sugar to generate corresponding logic codes.
- Support the generation of logic codes for automatic storage and loading of composite data types.
- Optimize the compilation process to improve compilation efficiency.
- Improve the accuracy and readability of error messages
- Continue to follow up on Substrate changes
What the product needs to achieve
We will try our best to make full compatibility of the generation rules for storage key and message (selector), as well as all structure encoding, with the existing designs of ink!, so that we can make Ask! and ink! contracts calling each other.
v0.3 (TBD) Finish ask-cli and provide further improvement
ask-cli
- Finish the functions of ask-cli to create, compile, and check code legality for contracts
Ask!
- Sorting out and refactoring the codebase
- Add corresponding functions according to the progress of ink!
- Improve Ask! to become a mature technology that can be used normally at the production level
Detailed timeline of v0.1 (10 weeks,14 Dec ~ 22 Feb)
The 1st and 2nd weeks (3 developers)
- Define the contract structure of the contract files, the definition of the contract method, and the type of contract method parameters.
- Define the data structure of storage: Determine the serialization and deserialization methods of each data item in the storage class.
- Define the
PreProcessor
functions: According to the definitions in 1, 2, determine the annotations required by the contract, the logical function of each annotation, and the generation method of the contract method in the metadata file.
The 3rd and 4th weeks (3 developers)
- Review and confirm the above design structures.
- Encapsulate runtime API: export the TS definition of the API, determine the parameter types and read and write methods.
- Start to implement the annotation functions of @contract, @constructor, @storage and @message.
The 5th and 6th weeks (3 developers)
- Implement metadata reading and writing; Implement array/map data reading and writing.
- Implement the annotation function of @contract, @constructor, @storage, @message.
- Test the runtime API and data read and write functions, and store and load data correctly through the API.
The 7th and 8th weeks (3 developers)
- Complete the development of the parsing annotation functions of @contract, @constructor, @storage, @message.
- Complete the encapsulation of AccountId and Balance functional components.
- Debug @contract, @constructor, @storage, @message annotations, and generate logic code that meets the design requirements.
- PreProcessor can generate basic metadata file content.
- Complete the encapsulation of Block, Crypto and other assistant functional components.
The 9th and 10th weeks (3 developers)
- PreProcessor can generate the contents of header section, storage section and message section in metadata file.
- Complete a manually written contract without relying on PreProcessor can be deployed on the chain.
- PreProcessor can generate complete metadata files.
- Complete all functional component tests.
- Complete joint test and deployment of contract functional components, annotations and metadata generation functions, and the contract can be executed online.
Cost of v0.1 (30 developers * weeks)
- Operating activities: $6000 ( Rent and Devices: $200 per developer * week )
- Employee payments: $87000 ($2900 per developer * week)
- —————————— +
- Total Cost: $93000
- Monthly average: $56 / KSM
- Treasury Proposal: 1661 KSM
Verification of v0.1: Test case on Jupiter and Europa & Written Report & Github source
The goal of this version is to provide an Ask! contract framework that can be used normally (not compatible with ink! yet), including compilation, uploading, deploying, instantiating, and executing in the FRAME Contracts.
- Can compile the ERC20, ERC721 and other example contracts provided in the project to generate WASM code and corresponding metadata.
- Can provide a test script to execute the following operations on the Jupiter testnet or Europa sandbox (both have modules compatible with FRAME Contracts):
- Upload the contract code and pass the WASM code inspection of the FRAME Contracts and compile it into a
Module
.
- Instantiate the uploaded code and correctly call the constructor in the contract to do the initialization.
- Call the instantiated contract to execute the corresponding operation, and the execution result meets expectations.