Use the Contracts pallet
Create the basis for building Wasm smart contracts using FRAME.
#
GoalAdd the Contracts pallet to your runtime to be able to use Wasm smart contracts in your blockchain.
#
Use cases- Smart Contract develoment
- On-chain execution of Wasm binaries
#
OverviewThis guide will show you how you can add the Contracts pallet to your runtime in order to allow your blockchain to support Wasm smart contracts. You can follow similar patterns to add additional FRAME pallets to your runtime, however you should note that each pallet is a little different in terms of the specific configuration settings needed to use it correctly.
note
You should already have the latest version of the Substrate Node Template compiled on your computer to follow this guide. If you haven't already done so, refer to this tutorial.
#
Steps#
1. Import the dependenciesRefer to this guide to properly include Contracts in your runtime.
This includes updating runtime/Cargo.toml
and runtime/Cargo.toml` with: - pallet-contracts
- pallet-contracts-primitives
#
2. Add the Contracts pallet to your runtimeNow you'll have to implement the Contract's pallet configuration traits in order for your runtime to use it properly.
pallet_contracts
#
Implement Start by making sure you've included all of the types that pallet_contracts
exposes. You can copy these from FRAME's source code (assuming versioning is equivalent to the imported crate). Here's what you need to add inside runtime/lib.rs
โ only the first 4 types are shown:
#
Parameter typesSome of these types require parameter_types
. Have a look at their implementation in this runtime to make sure you include everything. We'll take DeletionQueueDepth
as one example. Parameter types go right above impl pallet_contracts::Config for Runtime
:
Notice how the above parameter type requires WeightInfo
. This requires you to add the following to the top of runtime/lib.rs
:
Similarly, other parameter types use constants such as DAYS
, MILLICENTS
and AVERAGE_ON_INITIALIZE_RATIO
.
Define these towards the top of your runtime/lib.rs
file where the other constants exists:
pallet_contracts
#
Add an instance in runtime for Ceate an instance of the Contracts pallet in construct_macro!
inside runtime/lib.rs
:
#
3. Add API dependenciesinfo
Some pallets, including the Contracts pallet, expose custom runtime APIs and RPC endpoints. In the case of the Contracts pallet, this enables reading contracts state from off chain.
In this guide, we want to use the Contracts pallet to make calls to our node's storage without making a transaction.
To achieve this, we'll use another pallet called pallet-contracts-rpc-runtime-api
.
#
Import dependenciesJust like in the first step of this guide, update Cargo.toml
to add pallet-contracts-rpc-runtime-api
.
Now we can add the ContractsApi
dependency required to implement the Contracts runtime API.
Add this with the other use
statements.
#
Implement the Contracts runtime APIWe're now ready to implement the contracts runtime API.
This happens in the
impl_runtime_apis!
macro near the end of your
runtime.
Make sure to add the following functions that the ContractsApi
exposes:
call()
: returnspallet_contracts_primitives::ContractExecResult { Contracts::bare_call(origin, dest, value, gas_limit, input_data)}
get_storage()
: returnspallet_contracts_primitives::GetStorageResult {Contracts::get_storage(address, key)}
rent_projection()
: returnspallet_contracts_primitives::RentProjectionResult<BlockNumber> {Contracts::rent_projection(address)}
#
Add RPC API extensionTo be able to call the runtime API, we must add the RPC to the node's service.
In node/Cargo.toml
, add the dendencies for pallet-contracts
and pallet-contracts-rpc
.
Unsure what version to include?
Use the latest version as indicated on crates.io.
This RPC does not contain access to the Contracts pallet by default. To interact with this pallet, we have to extend the existing RPC and add the Contracts pallet along with its API.
In node/src/rpc.rs
, add this line to the where
clause in create_full<C, P>
:
And add the contracts RPC API extension using: