I just installed pallet-contracts on my Frontier node.
From the Polkadot js app interface, I can send transactions with tokens without problems, but if I try to deploy a new smart contract (inside developer/contracts GUI), I get this:
✅ InstantateWithCode
❌ system.ExtrinsicFailed NoProvider
What does “NoProvider” means and why i get it? how can i resolve it?
thi is my contracts_config.rs:
use crate::{
Balance, Balances, BalancesCall, Perbill, RandomnessCollectiveFlip, Runtime, RuntimeCall,
RuntimeEvent, RuntimeHoldReason, Timestamp,
};
use frame_support::{
parameter_types,
traits::{ConstBool, ConstU32},
};
use frame_system::EnsureSigned;
pub enum AllowBalancesCall {}
impl frame_support::traits::Contains<RuntimeCall> for AllowBalancesCall {
fn contains(call: &RuntimeCall) -> bool {
matches!(call, RuntimeCall::Balances(BalancesCall::transfer_allow_death { .. }))
}
}
// Unit = the base number of indivisible units for balances
const UNIT: Balance = 1_000_000_000_000;
const MILLIUNIT: Balance = 1_000_000_000;
const fn deposit(items: u32, bytes: u32) -> Balance {
(items as Balance * UNIT + (bytes as Balance) * (5 * MILLIUNIT / 100)) / 10
}
fn schedule<T: pallet_contracts::Config>() -> pallet_contracts::Schedule<T> {
pallet_contracts::Schedule {
limits: pallet_contracts::Limits {
runtime_memory: 1024 * 1024 * 1024,
..Default::default()
},
..Default::default()
}
}
parameter_types! {
pub const DepositPerItem: Balance = deposit(1, 0);
pub const DepositPerByte: Balance = deposit(0, 1);
pub Schedule: pallet_contracts::Schedule<Runtime> = schedule::<Runtime>();
pub const DefaultDepositLimit: Balance = deposit(1024, 1024 * 1024);
pub const CodeHashLockupDepositPercent: Perbill = Perbill::from_percent(0);
pub const MaxDelegateDependencies: u32 = 32;
}
impl pallet_contracts::Config for Runtime {
type Time = Timestamp;
type Randomness = RandomnessCollectiveFlip;
type Currency = Balances;
type RuntimeEvent = RuntimeEvent;
type RuntimeCall = RuntimeCall;
type CallFilter = AllowBalancesCall;
type DepositPerItem = DepositPerItem;
type DepositPerByte = DepositPerByte;
type CallStack = [pallet_contracts::Frame<Self>; 23];
type WeightPrice = pallet_transaction_payment::Pallet<Self>;
type WeightInfo = pallet_contracts::weights::SubstrateWeight<Self>;
type ChainExtension = ();
type Schedule = Schedule;
type AddressGenerator = pallet_contracts::DefaultAddressGenerator;
type MaxCodeLen = ConstU32<{ 128 * 1024 }>;
type DefaultDepositLimit = DefaultDepositLimit;
type MaxStorageKeyLen = ConstU32<128>;
type MaxDebugBufferLen = ConstU32<{ 2 * 1024 * 1024 }>;
type UnsafeUnstableInterface = ConstBool<false>;
type CodeHashLockupDepositPercent = CodeHashLockupDepositPercent;
type MaxDelegateDependencies = MaxDelegateDependencies;
type RuntimeHoldReason = RuntimeHoldReason;
type Environment = ();
type Debug = ();
type ApiVersion = ();
type Migrations = ();
#[cfg(not(feature = "parachain"))]
type Xcm = ();
type UploadOrigin = EnsureSigned<Self::AccountId>;
type InstantiateOrigin = EnsureSigned<Self::AccountId>;
}
And my runtime lib:
mod contracts_config;
..code...
pub type Executive = frame_executive::Executive<
Runtime,
Block,
frame_system::ChainContext<Runtime>,
Runtime,
AllPalletsWithSystem,
pallet_contracts::Migration<Runtime>,
>;
..code..
const NORMAL_DISPATCH_RATIO: Perbill = Perbill::from_percent(75);
// Prints debug output of the `contracts` pallet to stdout if the node is
// started with `-lruntime::contracts=debug`.
const CONTRACTS_DEBUG_OUTPUT: pallet_contracts::DebugInfo =
pallet_contracts::DebugInfo::UnsafeDebug;
const CONTRACTS_EVENTS: pallet_contracts::CollectEvents =
pallet_contracts::CollectEvents::UnsafeCollect;
/// We allow for 2000ms of compute with a 6 second average block time.
pub const WEIGHT_MILLISECS_PER_BLOCK: u64 = 2000;
pub const MAXIMUM_BLOCK_WEIGHT: Weight = Weight::from_parts(
WEIGHT_MILLISECS_PER_BLOCK * WEIGHT_REF_TIME_PER_MILLIS,
u64::MAX,
);
pub const MAXIMUM_BLOCK_LENGTH: u32 = 5 * 1024 * 1024;
impl pallet_insecure_randomness_collective_flip::Config for Runtime {}
...code...
// Create the runtime by composing the FRAME pallets that were previously configured.
#[frame_support::runtime]
mod runtime {
#[runtime::runtime]
#[runtime::derive(
RuntimeEvent,
RuntimeCall,
RuntimeError,
RuntimeOrigin,
RuntimeFreezeReason,
RuntimeHoldReason,
RuntimeSlashReason,
RuntimeLockId,
RuntimeTask
)]
pub struct Runtime;
#[runtime::pallet_index(0)]
pub type System = frame_system;
#[runtime::pallet_index(1)]
pub type Timestamp = pallet_timestamp;
#[runtime::pallet_index(2)]
pub type Aura = pallet_aura;
#[runtime::pallet_index(3)]
pub type Grandpa = pallet_grandpa;
#[runtime::pallet_index(4)]
pub type Balances = pallet_balances;
#[runtime::pallet_index(5)]
pub type TransactionPayment = pallet_transaction_payment;
#[runtime::pallet_index(6)]
pub type Sudo = pallet_sudo;
#[runtime::pallet_index(7)]
pub type Ethereum = pallet_ethereum;
#[runtime::pallet_index(8)]
pub type EVM = pallet_evm;
#[runtime::pallet_index(9)]
pub type EVMChainId = pallet_evm_chain_id;
#[runtime::pallet_index(10)]
pub type BaseFee = pallet_base_fee;
#[runtime::pallet_index(11)]
pub type ManualSeal = pallet_manual_seal;
#[runtime::pallet_index(12)]
pub type PalletCustom = pallet_custom;
#[runtime::pallet_index(13)]
pub type Contracts = pallet_contracts;
#[runtime::pallet_index(14)]
pub type RandomnessCollectiveFlip = pallet_insecure_randomness_collective_flip;
#[runtime::pallet_index(15)]
pub type Assets = pallet_assets;
}
..code...
impl_runtime_apis! {
impl pallet_contracts::ContractsApi<Block, AccountId, Balance, BlockNumber, Hash, EventRecord>
for Runtime
{
fn call(
origin: AccountId,
dest: AccountId,
value: Balance,
gas_limit: Option<Weight>,
storage_deposit_limit: Option<Balance>,
input_data: Vec<u8>,
) -> pallet_contracts::ContractExecResult<Balance, EventRecord> {
let gas_limit = gas_limit.unwrap_or(BlockWeights::get().max_block);
Contracts::bare_call(
origin,
dest,
value,
gas_limit,
storage_deposit_limit,
input_data,
CONTRACTS_DEBUG_OUTPUT,
CONTRACTS_EVENTS,
pallet_contracts::Determinism::Enforced,
)
}
fn instantiate(
origin: AccountId,
value: Balance,
gas_limit: Option<Weight>,
storage_deposit_limit: Option<Balance>,
code: pallet_contracts::Code<Hash>,
data: Vec<u8>,
salt: Vec<u8>,
) -> pallet_contracts::ContractInstantiateResult<AccountId, Balance, EventRecord>
{
let gas_limit = gas_limit.unwrap_or(BlockWeights::get().max_block);
Contracts::bare_instantiate(
origin,
value,
gas_limit,
storage_deposit_limit,
code,
data,
salt,
CONTRACTS_DEBUG_OUTPUT,
CONTRACTS_EVENTS,
)
}
fn upload_code(
origin: AccountId,
code: Vec<u8>,
storage_deposit_limit: Option<Balance>,
determinism: pallet_contracts::Determinism,
) -> pallet_contracts::CodeUploadResult<Hash, Balance>
{
Contracts::bare_upload_code(origin, code, storage_deposit_limit, determinism)
}
fn get_storage(
address: AccountId,
key: Vec<u8>,
) -> pallet_contracts::GetStorageResult {
Contracts::get_storage(address, key)
}
}
..code..
}
..code..