Smart-contract Stack
Smart Contract Runtime Environment
Astar & Shiden runtimes are based on Substrate. Both networks incorporate pallet-contracts
to enable Wasm smart-contract capabilities. The pallet-contracts
is a sandbox environment to deploy and execute WebAssembly smart contracts. Any language that compiles to Wasm can be used. But the code should be compatible with pallet-contracts
API.
To avoid unnecessary complexity, and boilerplate code, the best way is to use an eDSL that specifically targets the pallet-contracts
like ink!
(based on Rust) or ask!
(based on AssemblyScript). More supported language and eDSL will come as the ecosystem grows.
The Wasm blob is then deployed and stored on-chain.
Transaction fees
weight
Similar to Substrate, pallet-contracts
uses weight to charge execution.
One gas is equivalent to one weight, defined as one picosecond of execution time on the runtime's reference machine.
Transaction Weight is Substrate documentation
automatic deposit collection
Additionally to the weight, there is also a fee paid for on-chain storage called automatic deposit collection. This additional fee is paid by the caller and is calculated with the price set for each storage item DepositPerItem
and the price charged for each byte of storage DepositPerByte
.
The automatic deposit collection can be simplified as follows:
A caller of a contract pays a deposit to each contract in which new storage was created as a result of the executed call. In a similar way, a caller gets a refund from all the contracts that the call removed storage from.
Loading from storage weight
In order to prevent from theoretical PoV attack, as contract's WASM blob should be loaded from storage to be sent via network for state changes validation (included into PoV), a weight per byte of code is charged when loading a contract from storage.
Execution Engine
Pallet-contracts uses wasmi as a wasm-interpreter to execute the smart-contract Wasm blob. Even though there is a faster JIT interpreter like wasmtime used in the native runtime, smart contracts are an untrusted environment and that’s why the high degree of correctness of wasmi makes it the best option.
Two-step Deployment of Contracts
The contract code (Wasm blob) and the contract address and storage are decoupled from each other. To deploy a non-existing contract on-chain:
- First, upload the Wasm contract on-chain (every contract Wasm code has a
code_hash
as an identifier). - Second, instantiate the contract - it will create an address and storage for that contract.
- Anyone can instantiate a contract based on its
code_hash
.
There are several perks of decoupling contract code and address/storage:
- It will save space on-chain. Since a contract can have several constructors and several instantiations, it will just create a new instance based on the same underlying code. Think about standardized tokens, like PSP22 & PSP34, that will have one
code_hash
&blob
leaving on-chain, and as many instantiations as it is needed rather than having code uploaded at each new instantiation (like in Ethereum). - To instantiate a contract from within contract code (see delegator example), only
code_hash
needs to be provided. - Some standards contracts (PSP22, PSP34) will only be uploaded on-chain once, preventing users from paying the gas fees of uploading new code.
- Update contract code for an address: replace the contract code at the specified address with a new code (see set_code_hash). Storage and balances will be preserved.
Documentation about pallet-contracts
Smart Contracts
To facilitate development it is better to use a language targeting specifically pallet-contracts
.
There are two eDSLs currently available
Client APIs
The only library available to communicate with smart contracts is PolkadotJS API.
This API provides application developers the ability to query a node and interact with the Polkadot or Substrate chains using Javascript.
Parity also developed a web application to interact with contracts called contracts-ui.
Stack comparison to Ethereum
Ethereum | Astar | |
---|---|---|
L1 Architecture | Ethereum clients | Substrate |
Smart Contract Runtime Environment | EVM | pallet-contract, EVM via frontier |
Gas Model | fixed price per instruction | weight + storage fees + loading fees |
Smart Contract DSLs | Solidity and Vyper | ink! (Rust) and ask! (AssemblyScript) |
Standards | EIPs | PSPs |