We've covered several Layer 2 sidechains before:


But Moonbeam is unique since it's a parachain of the Polkadot ecosystem. It only just launched which means you are now able to deploy smart contracts to the chain. Being able to deploy EVM contracts to the Polkadot world comes with unique features.

Moon

What is Moonbeam?

Moonbeam is a Polkadot parachain. Rather than regular sidechains, a parachain in Polkadot has unique security benefits. It can take advantage of the Polkadot chain's security. This shared security mechanism can greatly decrease the risk for 51% attacks like happened for Ethereum Classic attack on January 10. Parachains can also make use of Cross-Consensus Message Format (XCM) which allows to send messages from one parachain to another one. And yes you can use tokens transferred via XCM in your smart contracts!


And you can send regular Ethereum transactions to Moonbeam. Moonbeam has implemented a fully functioning EVM as part of a Polkadot parachain. The EVM is fully functioning with most precompiles and all opcodes available. Consensus-related behavior can differ from Ethereum. Do not infer that block hashes are meaningless or constant merely because the chain uses proof of stake; check the maintained Ethereum-compatibility and consensus documentation for the network version you target.

The available precompiles and additionally deployed helper contracts can be found here. In particular Moonbeam specific features include:

  • Parachain Staking: You can interact with the parachain staking directly by (un-)-delegating and retrieving rewards.
  • Crowdloan Rewards: You can retrieve crowdloan information as well as claim rewards.
  • Wrapped GLMR as ERC-20: 0xAcc15dC74880C9944775448304B263D191c6077F

All code for Moonbeam can be found here. And block explorers either with Moonbeam Blockscout or Moonscan.

Why choose Moonbeam?

Moonbeam is a Polkadot parachain and participates in its relay-chain security and finality model. That is a meaningful architectural property, but market-cap rank does not establish that an application has “much higher security” or no security tradeoffs. Application code, governance, bridges, runtime versions and deployment choices still matter.

See the consensus and finality documentation. And you can make use of new features!

Parachain Staking

Historical context: These staking/precompile signatures are from the original 2022 example. Use the current precompile registry and versioned interfaces when building a new integration; do not assume a historical snake_case wrapper is interchangeable with a current interface.

You can directly access staking features using the ParachainStaking interface contract at address 0x0000000000000000000000000000000000000800.

This will allow you to delegate funds directly to the Moonbeam parachain staking from Proof of Stake within your smart contract.

  • You can use the delegate function to start a delegation to parachain node (called collator).
  • You can use schedule_leave_delegators to stop a delegation.


There are a few other functions in the interface which you can see here, but the ones on the right will be the most important ones.

soliditySolidity >=0.8.0
// SPDX-License-Identifier: GPL-3.0-only
pragma solidity >=0.8.0;

interface ParachainStaking {
    function is_delegator(
        address delegator
    ) external view returns (bool);

    function is_candidate(
        address candidate
    ) external view returns (bool);

    function delegate(
        address candidate,
        uint256 amount,
        uint256 candidateDelegationCount,
        uint256 delegatorDelegationCount
    ) external;

    function schedule_leave_delegators() external;
}

Crowdloan Rewards

And you can also access crowdloan rewards to get info or to claim rewards for any crowdloan participant. The interface is available at address 0x0000000000000000000000000000000000000801.

If you're wondering what the heck is a crowdloan? The short answer is there is a limited amount of parachain slots available since every parachain increases the computational complexity of nodes in the Polkadot chain. That's why there are auctions for the slots as 2-year leasings. Whoever bids the most DOT will receive the slot for two years, while having their DOT locked during this time. A crowdloan then is a mechanism that most projects are using to collectively use DOT together and participants will receive the project's token as reward.

In the case of Moonbeam crowdloan participants received 30% initially and the rest is vested of a two year time with rewards being able to be claimed continuously.

You can see past, current and future auctions here. As you can see Moonbeam actually won the second auction right after Acala.

solidity
interface CrowdloanRewards {
    function is_contributor(
        address contributor
    ) external view returns (bool);

    function reward_info(
        address contributor
    ) external view returns (uint256, uint256);

    function claim() external;
    
    function update_reward_address(
        address new_address
    ) external;
}

XCM Tokens

Moonbeam exposes cross-chain functionality through XCM precompiles, so a Solidity contract can access supported XCM operations through an EVM-facing interface. The original claim that contracts cannot send XCM messages is outdated.

The current XCM precompile guide explains supported operations, destinations and interface versions. XCM still runs through Substrate under the EVM-facing layer, and the destination chain must support the intended message. Cross-chain assets and transfers are not automatically interchangeable simply because a token has an ERC-20 interface.

Moonbeam vs. Moonriver: Which one to choose?

Historical context: The auction timing and relative rollout speeds below describe January 2022. Treat the deployment comparison as an operational choice, not a security ranking guaranteed by either network.

One unique feature of the Polkadot ecosystem is that they have a so-called canary chain: Kusama. It's the same chain as Polkadot except that they are more experimental (hence the name canary) by doing everything faster. For example governance time is shorter, unstaking period is shorter and the parachain auctions for Kusama started already half a year ago. And that's why some projects have two parachains, one on Kusama and one on Polkadot. In the case of Moonbeam, there is also the Moonriver parachain with the connection to Kusama. So which one should you use?

Moonriver will be the faster upgrading, more experimental chain with less security. For your own Dapp on Moonbeam you have three options:

  1. Deploy only to Moonbeam: higher security, more stable, longer time for upgrades
  2. Deploy only to Moonriver: lower security, less stable, faster time for upgrades
  3. Deploy to Moonbeam and Moonriver: a canary deployment can help you observe upgrades and application behavior earlier, but two deployments also mean more maintenance and separate network risks; this does not automatically provide the highest security


Which option you choose is up to you. If you're unsure, you're probably best to deploy only to Moonbeam since it gives you high security without extra work.

Moonriver vs. Moonbeam Meme

Moonbeam Ecosystem

There is a large ecosystem evolving around Moonbeam. You can find many tools and projects currently working towards integrating Moonbeam. Many are at the time of writing still work in progress for Moonbeam. For example the Band and Chainlink oracles are not yet available, although Chainlink is available for Moonriver.

You can already use The Graph on Moonbeam. Check out my tutorial how to use it here. It's the best tool for querying blockchain data in your Dapp's frontend.

And if you're looking to integrate a DEX in your contracts like Uniswap, Solarflare is exactly that. If you want to integrate it, my previous Uniswap 2 tutorial should work just fine.

Solarflare

How to deploy to Moonbeam

Deploying to Moonbeam is very simple. If you're using Truffle or Hardhat, simply add the network configuration like this:

javascript
// Legacy Truffle configuration. HDWalletProvider and mnemonic are defined by the surrounding project.
module.exports = {
  networks: {
    moonbeam: {
      provider: () => new HDWalletProvider(mnemonic, "https://rpc.api.moonbeam.network"),
      network_id: 1284,
    },
    moonriver: {
      provider: () => new HDWalletProvider(mnemonic, "https://rpc.api.moonriver.moonbeam.network"),
      network_id: 1285,
    },
    moonbase_alpha: {
      provider: () => new HDWalletProvider(mnemonic, "https://rpc.api.moonbase.moonbeam.network"),
      network_id: 1287,
    },
  },
};

You'll also need funds in the chain of course. For the testnet you can use the faucet via the faucet channel at the Moonbeam Discord. For Moonbeam and Moonriver funds, you'll need to purchase those on an exchange.

How to onboard users to your Moonbeam Dapp

1. Choice of wallet

These days you have much more than just MetaMask as possible wallets to support available. Take a look at Yearn Finance for example. They are supporting 11 different wallets alone at the time of this writing.

Wallet Options
Moonriver MetaMask

2. MetaMask example live in action

We'll focus on MetaMask as the biggest wallet with the most features. With MetaMask you can nowadays actually request to connect directly to a custom network.

If you want to see this live, just go to the Moonbeam docs. Unless you already have Moonbeam Network added, it will request to add this network.

3. How to add Moonbeam automatically for users

The wallet code requests Moonbeam’s addition and then requests switching. Success from wallet_addEthereumChain alone does not guarantee an active-network change, and either request may be rejected. Use the wallet’s actual selected chain in your dapp.

javascript
// Moonbeam: chain ID 1284 (decimal).
// Moonriver: 1285 (0x505), MOVR; Moonbase Alpha: 1287 (0x507), DEV. Choose each network’s matching RPC and explorer.
const params = [
  {
    "chainId": "0x504",
    "chainName": "Moonbeam",
    "rpcUrls": [
      "https://rpc.api.moonbeam.network"
    ],
    "nativeCurrency": {
      "name": "GLMR",
      "symbol": "GLMR",
      "decimals": 18
    },
    "blockExplorerUrls": [
      "https://moonscan.io"
    ]
  }
];

try {
  await ethereum.request({ method: "wallet_addEthereumChain", params });
  // Adding a network does not guarantee that it is selected.
  await ethereum.request({
    method: "wallet_switchEthereumChain",
    params: [{ chainId: params[0].chainId }],
  });
} catch (error) {
  // The wallet may reject either request; keep the UI on its actual chain.
  console.error("Network request was not completed", error);
}