Follow these steps to deploy your first smart contract on Metis L2 using Hardhat.
-
Create a Project Directory:
- Command:
mkdir new_project
- Purpose: This command creates a new folder named
new_project
for your project files.
- Command:
-
Initialize a Node.js Project:
- Command:
npm init
- Purpose: Initializes a new Node.js project. This command creates a
package.json
file in your project directory, which holds various metadata relevant to the project. This file is used to manage the project’s dependencies, scripts, and versioning.
- Command:
-
Install Hardhat:
- Command:
npm install --save-dev hardhat
- Purpose: Installs Hardhat as a development dependency in your project. Hardhat is a task runner and testing framework designed for Ethereum development.
- Command:
-
Create a Hardhat Project:
- Command:
npx hardhat
- Purpose: Initializes a new Hardhat project. This command will prompt you to create a basic project structure and install necessary dependencies.
- Command:
-
Select Default Options:
- When asked to install the sample project's dependencies, choose
yes
. This action installs the@nomicfoundation/hardhat-toolbox
, a set of tools and plugins recommended for most Hardhat projects.
- When asked to install the sample project's dependencies, choose
-
Modify the Hardhat Configuration:
- File:
hardhat.config.js
- Purpose: To deploy contracts on the Metis network, you need to specify the Metis network configuration in the Hardhat config file. This involves setting up the network name, RPC URL, accounts (private keys), and any additional network-specific settings.
- File:
-
Network Configuration Sample:
module.exports = { solidity: "0.8.24", networks: { hardhat: {}, metisAndromeda: { url: "https://andromeda.metis.io/?owner=1088", accounts: [PRIVATE_KEY], }, }, };
- Explanation: This configuration sets the Solidity compiler version and defines a custom network (
metisAndromeda
). Theurl
is the RPC endpoint for the Metis Andromeda network, andaccounts
should include the private key(s) for the account(s) you will use to deploy the contract.
- Explanation: This configuration sets the Solidity compiler version and defines a custom network (
-
Setting the Private Key:
- Best Practice: Instead of hardcoding the private key in the config file, use an environment variable to enhance security. You can use
dotenv
package for managing environment variables. - Change:
accounts: [process.env.WALLET_PRIVATE_KEY]
to use an environment variable. - Adding Private Key to Config:
require('dotenv').config(); const PRIVATE_KEY = process.env.WALLET_PRIVATE_KEY;
- Purpose: Safely loads your private key from an environment variable, reducing the risk of exposing sensitive information.
- Best Practice: Instead of hardcoding the private key in the config file, use an environment variable to enhance security. You can use
-
Deploy Your Contract:
- Command:
npx hardhat run .\scripts\deploy.js --network metisAndromeda
- Purpose: This command compiles your smart contracts and deploys them to the specified network (in this case,
metisAndromeda
). The scriptdeploy.js
contains your deployment logic.
- Command:
-
Verification and Interaction:
- After deployment, you will receive a transaction hash. You can use this hash to verify your contract's deployment on the Metis blockchain explorer.
- Interacting with your deployed contract can be done through Hardhat scripts or directly via a web3 provider interface like Metamask.
- Purpose: The
Lock
contract is designed to lock Ether (or Metis in our case) until a specified future time. Once the time lock expires, the locked funds can be withdrawn by the contract's owner.
-
State Variables:
unlockTime
: Apublic
uint variable that stores the timestamp (in seconds since the Unix epoch) until which the funds are locked.owner
: Apublic
andpayable
address variable that stores the contract owner's address, who is allowed to withdraw the funds after the unlock time.
-
Event:
Withdrawal
: An event that logs the withdrawal action, including the amount of ETH withdrawn and the timestamp of the withdrawal.
-
Constructor:
- The constructor takes a single parameter
_unlockTime
(the future timestamp until which the funds should be locked) and sets the contract'sunlockTime
andowner
state variables. It requires that the_unlockTime
is in the future compared to the currentblock.timestamp
. - The constructor also allows the deployment transaction to include ETH, making the contract's address payable and enabling it to hold and lock the transferred ETH.
- The constructor takes a single parameter
-
Functions:
withdraw()
: This function allows the contract owner to withdraw all the locked funds after theunlockTime
has passed. It includes tworequire
statements to ensure that:- The current block timestamp is equal to or later than the
unlockTime
, ensuring the funds are locked until the specified time. - The caller of the function (
msg.sender
) is the owner of the contract, preventing unauthorized access to the funds.
- The current block timestamp is equal to or later than the
- Upon successful validation, the
Withdrawal
event is emitted, and the contract transfers its entire balance to the owner.
- Locking Mechanism: Upon deployment, the contract locks any ETH sent with the constructor transaction until the specified
unlockTime
. - Security: The contract ensures that only the owner can withdraw the funds and only after the specified unlock time.
- Transparency: The
unlockTime
andowner
are publicly visible, making the contract's state and intentions transparent. - Event Logging: The
Withdrawal
event provides an auditable log of withdrawals, useful for tracking when and how funds are withdrawn.
You can interact with the Lock.sol
contract once it's deployed on the Metis network. Interacting with a smart contract typically involves two types of operations: read operations, which don't change the state of the blockchain and therefore don't require a transaction fee, and write operations, which do change the state and require gas fees. For the Lock.sol
contract, you'll mainly be concerned with a write operation (withdraw
) and reading state variables (unlockTime
and owner
).
-
Documentation for devs https://docs.metis.io/dev/
-
Hardhat and Typescript tutorial https://github.com/harshnambiar/namaste_metis
-
Subgraphs https://docs.ormi.xyz/metis-subgraphs/
-
The public Metis endpoint on Nodies: https://lb.nodies.app/v1/f5c5ecde09414b3384842a8740a8c998
Note: In case when you need higher limits of the public RPC endpoint, there are two options:
- Setting up a private RPC endpoint using a provider such as Nodies or BlastAPI
- Setting up a replica node.
Run Replica Node here: https://github.com/MetisProtocol/metis-replica-node