This article was originally posted by me on November 19, 2021, at thiscoindaily
In this article, I’ll be introducing you to ink!, a rust-based embedded domain-specific language (eDSL) created by parity tech for writing smart contracts that run on substrate-based chains.
Writing smart contracts parachains
the polkadot and Kusama relay chains don’t permit smart contracts to be written on them. This is a deliberate step to help keep the relay chain as light-weight and specific as possible. However, parachains (and parathreads) connected to the relay chain can run smart contracts if smart contract functionality is implemented on them.
Currently, there are two main ways in which prospective parachains/parathreads can implement smart contract functionalities in the runtime:
- By utilizing the EVM pallet, which allows you to port (and run) ethereum smart contracts on substrate-based chains. This is made possible, thanks to substrate’s ethereum compatibility layer (frontier).
- By utilizing substrate’s built-in contracts pallet, which allows smart contracts written in ink! to be run on top of it. It’s worthy to note that ink! is not the only language that can be supported by this pallet. any language that can compile to web assembly can be supported as well.
For the purpose of this article, we would be looking at the ink programming language, its features and syntax, and how to write ink! smart contracts.
Note: if you’re just getting started with substrate, you might want to check out this article on how to explore substrate.
Are you ready? let’s get to it!
Introducing ink!
As I mentioned earlier, ink! is an eDSL. It uses rust as its host language and therefore inherits the generic constructs of rust. this means that if you already know rust, then developing with ink won’t be a problem.
Because ink! uses the rust programming language as its host, it automatically ships with all the amazing benefits of building with rust. It’s still at an early (but stable) stage right now, but considering all the short-coming of solidity, ink! is set to become an amazing option, when it comes to building secure and scalable smart contracts with systems-grade speed, security, and efficiency while maintaining quite a high level of abstraction.
Also, ink! compiles to web assembly. which means it automatically inherits all the amazing features of web assembly too.
Ink! syntax
As stated before, ink! uses rust as its host language. but ink uses macros to help give more flexibility to our code. For example, ink! makes heavy use of the attribute-like macros, which allows ink! to attach items to custom attributes, hence allowing manipulation of those items.
ink! uses these macros to create a form of abstraction, in which a lot of procedures are carried out behind the curtains. that way, you get to focus on writing your contract, without having to border about the lower-level nitty-gritty.
for example, take a look at the code below (the structure of the code may not appear normally on mobile)
use ink_lang as ink;
#[ink::contract]
mod CertNft {
#[ink(storage)]
pub Struct CertificateNft {
issuer: AccountId,
certificate_number: u16,
/* -- snip -- */
}
impl CertificateNft {
#[ink(constructor)]
pub fn new(init_value: u16) -> Self {
Self {
certificate_number: init_value,
}
/* --snip-- */
}
/* --snip-- */
}
- The contract macro above helps to analyze the code and make sure that it conforms to a specified set of rules (e.g, you can only have one
#[ink(storage)]
struct per contract) before compiling it to wasm. - the storage macro helps to create storage items for structs.
- the constructor macro helps to flag methods that are callable once the contract has been instantiated
If you’ve tried creating and implementing modules on the substrate’s runtime before, you’ll quickly realize how ink! uses macros to abstract out a lot of hassles you’d have had to go through while building the runtime (at the expense of flexibility, of course)
Note: if you haven’t heard of macros, don’t worry. ink! ships with relevant macros and doesn’t expect you to create custom macros from scratch. You can read more about macros here.
Be sure to check out a list of ink! macros/attributes, the rules you have to follow while using them, and situations in which they are used here
Developing a smart contract with ink!
In order to develop (and deploy) a smart contract, you need to,
1) set up your working enviroment
- to create and compile an ink! contract, you need to have rust/cargo installed.
- Once you’ve installed rust/cargo,you’ll also need to install the binaryen package as a pre-requisite for installing INK! cli
- once the pre-requisites above have been fulfilled, you’re now ready to install ink! cli, which will help stream-line the management of your projects. to install ink! cli, run the code below
cargo install cargo-contract --vers ^0.15 --force --locked
2) create a new project and write your contract
To create a new project, run the code below
cargo contract new project_name
note: replace project_name with the name of your project. this will create a new folder for your project. all your contracts will go into the lib.rs file.
If you specified any tests in your contract, you can run the following to test the functionality of your code.
cargo +nightly test
3) compile your contract
Once you’ve built your contract and all tests have been passed, you can compile your contract by running the following code:
cargo +nightly contract build
4) deploy your contract
After compiling your contract, it’s time to deploy it. To do this, you’ll need a node that accepts wasm smart contracts.
You could follow this tutorial to set up a node and add the contract pallet to it (in order to enable wasm smart contract functionality).
If you don’t want to go through the hassle and want a node with smart contract functionality set up as soon as possible, you could set up one and start up a development chain by running the codes below
cargo install contracts-node --git https://github.com/paritytech/substrate-contracts-node.git --tag v0.1.0 --force --locked
substrate-contracts-node --dev --tmp
Once your node is up and running, you can now use Canvas UI to deploy and call your contract.
Note, if you don’t know about the Canvas Test network, you can learn more about it here
Conclusion
This article was created to help give you an overview of ink!. To start developing with ink!, I’d suggest you check out ink! docs and start with the basics. Also, consider doing this tutorial to help understand the intricacies of setting up (and deploying) smart contracts on a wasm contract-supported blockchain,
Ciao!!