<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Gino Osahon</title>
    <description>The latest articles on Forem by Gino Osahon (@ginowine).</description>
    <link>https://forem.com/ginowine</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F898961%2F61bdf7a0-da05-4e15-9fe8-dd7d37066529.jpeg</url>
      <title>Forem: Gino Osahon</title>
      <link>https://forem.com/ginowine</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/ginowine"/>
    <language>en</language>
    <item>
      <title>Getting Started with AWS Containers Part Two</title>
      <dc:creator>Gino Osahon</dc:creator>
      <pubDate>Wed, 12 Jul 2023 12:21:40 +0000</pubDate>
      <link>https://forem.com/ginowine/a-guide-to-getting-started-with-aws-containers-part-two-4jeo</link>
      <guid>https://forem.com/ginowine/a-guide-to-getting-started-with-aws-containers-part-two-4jeo</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--_AvCKpNU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gq8jz3wgwbq7tn62hqny.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--_AvCKpNU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gq8jz3wgwbq7tn62hqny.png" alt="Docker Image" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Overview
&lt;/h2&gt;

&lt;p&gt;Welcome to part 2 of my blog post on getting started with AWS Containers. In part 2, You will learn about the following concepts. Setting up AWS for Containers, Building and Packaging Containerized Applications, Setting Up Docker on AWS, Deploying ECS containers. Not to worry, if these terms are new to you — you'll learn about them here!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;You will learn about the following topics in this second part of the blog post.&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Setting Up AWS for Containers&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Creating an AWS account&lt;/li&gt;
&lt;li&gt;Configuring AWS Identity and Access Management (IAM) roles and policies&lt;/li&gt;
&lt;li&gt;Creating a VPC with Public and Private Subnets for Your Clusters&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Building and Packaging Containerized Applications&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Choosing a containerization technology (Docker, containerd, etc.)&lt;/li&gt;
&lt;li&gt;Introduction to Docker&lt;/li&gt;
&lt;li&gt;Setting Up Docker on AWS&lt;/li&gt;
&lt;li&gt;How to deploy and manage Docker containers on AWS EC2&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;To follow this tutorial, you are strongly advised to read &lt;a href="https://dev.to/ginowine/a-guide-to-getting-started-with-aws-containers-1971"&gt;article one here&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  1. Setting Up AWS for Containers
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Creating an AWS Account
&lt;/h2&gt;

&lt;p&gt;Watch this YouTube video created by Cloud Tech on how to create an AWS account :&lt;br&gt;
&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/SFaSB6vgp8k"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  Configuring AWS Identity and Access Management (IAM) Roles and Policies
&lt;/h2&gt;

&lt;p&gt;Watch this YouTube video created by Inquirinity on how to configure IAM for an AWS account :&lt;br&gt;
&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/LhAyqaZwYKE"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;You can also visit &lt;a href="https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html"&gt;Amazon Webservice documentation&lt;/a&gt; website to learn all about IAM on AWS&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating a VPC with Public and Private Subnets for Your Clusters
&lt;/h2&gt;

&lt;p&gt;Container instances in your clusters need external network access to communicate with the Amazon ECS service endpoint. However, you might have tasks and services that you would like to run in private subnets. Creating a VPC with both public and private subnets provides you the flexibility to launch tasks and services in either a public or private subnet. Tasks and services in the private subnets can access the internet through a NAT gateway. Services in both the public and private subnets can be configured to use a load balancer so that they can still be reached from the public internet.&lt;/p&gt;

&lt;p&gt;This tutorial guides you through creating a VPC with two public subnets and two private subnets, which are provided with internet access through a NAT gateway.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1: Create an Elastic IP Address for Your NAT Gateway
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;A NAT gateway&lt;/strong&gt; requires an Elastic IP address in your public subnet, but the VPC wizard does not create one for you. Create the Elastic IP address before running the VPC wizard.&lt;/p&gt;

&lt;p&gt;To create an Elastic IP address, open the &lt;a href="https://console.aws.amazon.com/vpc/"&gt;Amazon VPC console&lt;/a&gt; or visit this URL &lt;a href="https://console.aws.amazon.com/vpc/"&gt;https://console.aws.amazon.com/vpc/&lt;/a&gt; and sign in. Follow the below steps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;In the left navigation pane, choose Elastic IPs.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Choose Allocate new address, Allocate, Close.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Note the Allocation ID for your newly created Elastic IP address; you enter this later in the VPC wizard.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2: Run the VPC Wizard
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;The VPC wizard automatically creates and configures most of your VPC resources for you.&lt;/li&gt;
&lt;li&gt;To run the VPC wizard, in the left navigation pane, choose VPC Dashboard.&lt;/li&gt;
&lt;li&gt;Choose Launch VPC Wizard, VPC with Public and Private Subnets, Select.&lt;/li&gt;
&lt;li&gt;For VPC name, give your VPC a unique name.&lt;/li&gt;
&lt;li&gt;For Elastic IP Allocation ID, choose the ID of the Elastic IP address that you created earlier.&lt;/li&gt;
&lt;li&gt;Choose Create VPC.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When the wizard is finished, choose OK. Note the Availability Zone in which your VPC subnets were created. Your additional subnets should be created in a different Availability Zone.&lt;/p&gt;

&lt;p&gt;Non-default subnets, such as those created by the VPC wizard, are not auto-assigned public IPv4 addresses. Instances launched in the public subnet must be assigned a public IPv4 address to communicate with the Amazon ECS service endpoint.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;To modify your public subnet's IPv4 addressing behavior&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;In the left navigation pane, choose Subnets.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Select the public subnet for your VPC. By default, the name created by the VPC wizard is Public subnet.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Choose Actions, Modify auto-assign IP settings.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Select the Enable auto-assign public IPv4 address check box, and then choose Save.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Step 3: Create Additional Subnets
&lt;/h2&gt;

&lt;p&gt;The wizard creates a VPC with a single public and a single private subnet in a single Availability Zone. For greater availability, you should create at least one more of each subnet type in a different Availability Zone so that your VPC has both public and private subnets across two Availability Zones.&lt;/p&gt;

&lt;p&gt;To create an additional private subnet&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;In the left navigation pane, choose Subnets.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Choose Create Subnet.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;For Name tag, enter a name for your subnet, such as Private subnet.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;For VPC, choose the VPC that you created earlier.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;For Availability Zone, choose a different Availability Zone than your original subnets in the VPC.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;For IPv4 CIDR block, enter a valid CIDR block. For example, the wizard creates CIDR blocks in 10.0.0.0/24 and 10.0.1.0/24 by default. You could use 10.0.3.0/24 for your second private subnet.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Choose Yes, Create.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To create an additional public subnet&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;In the left navigation pane, choose Subnets and then Create Subnet.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;For Name tag, enter a name for your subnet, such as Public subnet.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;For VPC, choose the VPC that you created earlier.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;For Availability Zone, choose the same Availability Zone as the additional private subnet that you created in the previous procedure.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;For IPv4 CIDR block, enter a valid CIDR block. For example, the wizard creates CIDR blocks in 10.0.0.0/24 and 10.0.1.0/24 by default. You could use 10.0.2.0/24 for your second public subnet.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Choose Yes, Create.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Select the public subnet that you just created and choose Route Table, Edit.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;By default, the main route table is selected. Choose the other available route table so that the 0.0.0.0/0 destination is routed to the internet gateway (igw-xxxxxxxx) and choose Save.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;With your second public subnet still selected, choose Subnet Actions, Modify auto-assign IP settings.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Select Enable auto-assign public IPv4 address and choose Save, Close.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  2. Building and Packaging Containerized Applications
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Choosing a Containerization Technology
&lt;/h2&gt;

&lt;p&gt;Containerization has become a popular approach for packaging and deploying applications. Several containerization technologies are available, including Docker, containerd, and others. In this tutorial, you will focus on Docker as the containerization technology of choice.&lt;/p&gt;

&lt;h2&gt;
  
  
  Introduction to Docker
&lt;/h2&gt;

&lt;p&gt;Docker has revolutionized the way developers package and deploy applications, offering a lightweight and portable solution for containerization. With Docker, developers can create self-contained units called containers that encapsulate their applications and all their dependencies, including libraries, frameworks, and runtime environments. This approach ensures that applications run consistently across different environments, from development to production, regardless of the underlying infrastructure.&lt;/p&gt;

&lt;p&gt;One of the key benefits of Docker is improved application isolation. By leveraging containerization, applications are encapsulated within their own runtime environment, isolated from the host system and other applications. This isolation prevents conflicts between dependencies and ensures that applications operate reliably and predictably.&lt;/p&gt;

&lt;p&gt;Furthermore, Docker brings consistency to application deployment. With Docker containers, developers can create a standardized environment, ensuring that applications behave consistently across different development machines, testing environments, and production servers. This eliminates the "works on my machine" problem and facilitates smoother collaboration between teams.&lt;/p&gt;

&lt;p&gt;Simplified deployment is another advantage provided by Docker. With Docker containers, developers can package their applications and dependencies into a single, self-contained unit that can be easily distributed and deployed on any system supporting Docker. This portability enables seamless deployment across different cloud platforms, on-premises servers, or even developer laptops, reducing deployment complexities and enabling efficient scaling of applications.&lt;/p&gt;

&lt;p&gt;Additionally, Docker promotes scalability and resource efficiency. Its lightweight nature allows for quick provisioning and deployment of containers, enabling rapid scaling of applications based on demand. Containers consume fewer resources compared to traditional virtual machines, making more efficient use of system resources and allowing for higher density of application instances on a single host.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting Up Docker on AWS
&lt;/h2&gt;

&lt;p&gt;Docker is a popular containerization technology that enables developers to package and deploy applications in lightweight and portable containers. Amazon Web Services (AWS) provides a robust infrastructure for running Docker containers. This guide will walk you through the steps to set up Docker on AWS.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1: Create an AWS Account
&lt;/h2&gt;

&lt;p&gt;If you don't have an AWS account already, go to the AWS website (&lt;a href="https://aws.amazon.com/"&gt;https://aws.amazon.com/&lt;/a&gt;) and click on "Create an AWS Account." Follow the instructions to set up your account. You will need to provide billing information and create a new IAM user with appropriate permissions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2: Launch an EC2 Instance
&lt;/h2&gt;

&lt;p&gt;Once you have an AWS account, launch an EC2 instance to host your Docker containers. Follow these steps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Open the AWS Management Console and navigate to the EC2 service.&lt;/li&gt;
&lt;li&gt;Click on "Launch Instance" to start the instance creation process.&lt;/li&gt;
&lt;li&gt;Choose an Amazon Machine Image (AMI) that supports Docker, such as Amazon Linux 2 or Amazon ECS-optimized AMI.&lt;/li&gt;
&lt;li&gt;Select an instance type based on your application's requirements.&lt;/li&gt;
&lt;li&gt;Configure the instance details, such as the number of instances, VPC settings, and security groups.&lt;/li&gt;
&lt;li&gt;Add storage and configure any additional settings as needed.&lt;/li&gt;
&lt;li&gt;Review your configuration and launch the instance.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Step 3: Connect to the EC2 Instance
&lt;/h2&gt;

&lt;p&gt;After the EC2 instance is launched, you need to connect to it using SSH. Follow these steps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Locate the public IP address or DNS name of your EC2 instance in the AWS Management Console.&lt;/li&gt;
&lt;li&gt;Open a terminal on your local machine and run the following command, replacing your-instance-ip with the IP address or DNS name:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;ssh -i your-key-pair.pem ec2-user@your-instance-ip&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Note: You may need to adjust the SSH command based on the operating system and key pair you used during the EC2 instance setup.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 4: Install Docker on the EC2 Instance
&lt;/h2&gt;

&lt;p&gt;Once connected to the EC2 instance, install Docker by executing the following commands:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
Update the package index:
&lt;code&gt;sudo yum update -y&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
Install Docker:
&lt;code&gt;sudo amazon-linux-extras install docker -y&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
Start the Docker service:
&lt;code&gt;sudo service docker start&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
Add the ec2-user to the Docker group to run Docker commands without using sudo:
&lt;code&gt;sudo usermod -a -G docker ec2-user&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Step 5: Verify the Docker Installation
&lt;/h2&gt;

&lt;p&gt;To confirm that Docker is installed and running correctly on the EC2 instance, run the following command:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;docker info&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;If Docker is installed properly, you will see information about the Docker version and configuration.&lt;/p&gt;

&lt;h2&gt;
  
  
  Deploying and Managing Docker Containers on AWS EC2
&lt;/h2&gt;

&lt;p&gt;Once you have Docker set up on your AWS EC2 instance, you can begin deploying and managing Docker containers. This guide will walk you through the steps to deploy and manage Docker containers on your AWS EC2 instance.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1: Prepare your Docker Image
&lt;/h2&gt;

&lt;p&gt;Before deploying a container, ensure you have a Docker image ready for your application. You can either build your own Docker image using a Dockerfile or pull an existing image from a registry like Docker Hub.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2: Pull or Load the Docker Image
&lt;/h2&gt;

&lt;p&gt;If you are using an existing Docker image from a registry, use the docker pull command to fetch the image onto your EC2 instance. For example:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;docker pull your-image:tag&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;If you have a locally-built Docker image or a saved image file, use the docker load command to load the image into Docker on your EC2 instance. For example:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;docker load -i your-image.tar&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 3: Run the Docker Container
&lt;/h2&gt;

&lt;p&gt;To deploy a Docker container based on your image, use the docker run command. Customize the command based on your application's requirements. Here's an example:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;docker run -d --name your-container -p host-port:container-port your-image:tag&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Replace your-container with a desired name for your container, host-port with the port number on your EC2 instance you want to map to the container's port, and container-port with the port your application listens on inside the container.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 4: Manage and Monitor Docker Containers
&lt;/h2&gt;

&lt;p&gt;You can manage and monitor your Docker containers on your EC2 instance using various Docker commands. Here are some commonly used commands:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;docker ps&lt;/code&gt;: Lists the running containers on the EC2 instance.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;docker stop container-id&lt;/code&gt;: Stops a running container. Replace container-id with the actual container ID or name.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;docker start container-id&lt;/code&gt;: Starts a stopped container.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;docker logs container-id&lt;/code&gt;: Displays the logs of a specific container.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;docker exec -it container-id /bin/bash&lt;/code&gt;: Accesses the terminal inside a running container for executing commands or debugging.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Step 5: Clean Up Unused Containers
&lt;/h2&gt;

&lt;p&gt;To keep your EC2 instance clean and efficient, it's essential to remove unused containers. Use the docker rm command followed by the container ID or name to remove a stopped container. For example:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;docker rm container-id&lt;/code&gt;&lt;br&gt;
Be cautious while removing containers as it permanently deletes the container and its associated data.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 6: Automate Container Deployment and Management
&lt;/h2&gt;

&lt;p&gt;To streamline container deployment and management, consider using container orchestration tools like Amazon Elastic Container Service (ECS) or Kubernetes on AWS. These tools provide more advanced features, such as automatic scaling, load balancing, and improved container management capabilities.&lt;/p&gt;

&lt;p&gt;Feel free to visit the official &lt;a href="https://docs.aws.amazon.com/whitepapers/latest/aws-overview/containers.html"&gt;Amazon Container Documentation Website&lt;/a&gt; and explore further resources from Amazon &lt;/p&gt;

</description>
      <category>docker</category>
      <category>aws</category>
      <category>containers</category>
      <category>cloudcomputing</category>
    </item>
    <item>
      <title>Getting Started with AWS Containers Part One</title>
      <dc:creator>Gino Osahon</dc:creator>
      <pubDate>Wed, 12 Jul 2023 09:18:28 +0000</pubDate>
      <link>https://forem.com/ginowine/a-guide-to-getting-started-with-aws-containers-1971</link>
      <guid>https://forem.com/ginowine/a-guide-to-getting-started-with-aws-containers-1971</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--vpFx_75x--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7k0rahgv0ug531o5en41.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vpFx_75x--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7k0rahgv0ug531o5en41.png" alt="Container Image" width="800" height="509"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Welcome to Getting Started with AWS Containers.
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Overview
&lt;/h2&gt;

&lt;p&gt;In this 2 part series blog post, you will go through a step-by-guide to understanding the concepts of Containers, AWS container services, Amazon Elastic Container Service (ECS), Amazon Elastic Kubernetes Service (EKS), Docker, How to setup ECS, Building and Packaging Containerized Applications, AWS IAM, VPC, and Deploying ECS containers. Not to worry, if these terms are new to you — you'll get introduced to them in this article!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The following topics will be covered in this first part of the tutorial.&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Introduction to Containers&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Brief explanation of containers and their benefits&lt;/li&gt;
&lt;li&gt;Introduction to AWS container services&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Understanding Containers on AWS&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt; Introduction to Amazon Elastic Container Service (ECS)&lt;/li&gt;
&lt;li&gt; Key features of ECS&lt;/li&gt;
&lt;li&gt; Differences between Fargate and EC2 launch types&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Introduction to Amazon Elastic Kubernetes Service (EKS)&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Key features of EKS&lt;/li&gt;
&lt;li&gt;Comparison of ECS and EKS for container orchestration&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Prerequisites&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To follow this tutorial, you should have knowledge in:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Cloud Technologies/computing&lt;/li&gt;
&lt;li&gt;Software Development and Deployment &lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  1. Introduction to Containers
&lt;/h1&gt;

&lt;p&gt;A Container is a portable and lightweight computing environment. It houses all the system resources that an application, for example, Microservices needs to run. Some examples of these resources include memory, storage, networking resources, dependencies, binary code, configurations files, and CPU. Containers allow you to package your application together with system resources, providing isolated environments for running your Applications.&lt;/p&gt;

&lt;p&gt;Modern software engineering practices encourages containerising application deployment for a consistent delivery and management of applications for users. find below some of the benefits of containerisation in application deployment. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--O74l46eL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/modxz4cr18a5qkkw30uj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--O74l46eL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/modxz4cr18a5qkkw30uj.png" alt="benefits of containers" width="492" height="542"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Portability&lt;/strong&gt; - Write once, run anywhere. Containers can help developers bundle all their application dependencies, so no need to rebuilding the application when deploying to any other environment.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Efficiency&lt;/strong&gt; - Containers provide one of the most efficient methods of virtualisation for developers. They minimise overhead and utilises all available resources. Isolated containers can perform their operations without interfering with other containers, allowing a single host to perform many functions. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Agility&lt;/strong&gt; - Containerisation makes DevOps workflow seamless and easy. They can rapidly be deployed on any environment, and used to handle application functionalities. If they are not longer needed, you can automatically shut it down until it is needed again, a technique known as orchestration. Technologies like Kubernetes automate the process of coordinating, managing, scaling, and removing containers.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Faster delivery&lt;/strong&gt; -  Developers can use containers to compartmentalize their application. They can divide big application into discrete parts using microservices, and make isolated changes to areas of the application without affecting the whole application.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Improved Security&lt;/strong&gt; - Being able to isolate components of an application provides an additional layer of security. This is because containers are isolated from one another, this way, if security on one container is compromised, other containers on the same host remain secure.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Flexibility&lt;/strong&gt; - Containerized apps using microservices become so flexible that you can host certain elements on bare metal and deploy others to virtual cloud environments&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Easier management&lt;/strong&gt; - Platforms like Kubernetes, Google Kubernetes Engine (GKE), and Amazon Elastic Container Service (ECS/EKS) offers a variety of tools that simplify container management, like application installation, rollbacks and upgrades. There are self-healing features you can use to attempt to recover failed containers, terminate containers that fail health checks, and constantly monitor your containers’ health and status. There is also the flexibility of allocating each container a set amount of CPU and RAM to handle its tasks. Managing containers with tools like Kubernetes is way easier than traditional application management methods.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Containers help the DevOps process by accelerating deployment, streamlining workflows, and minimizing infrastructure conflicts; it also enables developers to use the available resources better. Modern tools like Kubernetes and the Docker engine has made the process of containerising application something that developers can leverage to build scalable applications&lt;/p&gt;

&lt;h2&gt;
  
  
  Introduction to AWS Containers
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--N4X1dnPa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/d7olcyondzp6lxmsdi9w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--N4X1dnPa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/d7olcyondzp6lxmsdi9w.png" alt="AWS containers" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Considering that Cloud Computing is the productive way of deploying and delivering application services to users, the introduction of the AWS container services is at the forefront of this campaign. It opens the gateway to a world of boundless possibilities. Developers and IT enthusiasts immerse themselves in containerisation due to the abovementioned benefits. With its effortless management of containerized applications, Amazon Elastic Container Service (ECS) beckons users to a seamless experience, regardless of scale, where intricate complexities fade into the background, allowing creative minds to focus solely on innovation. &lt;/p&gt;

&lt;p&gt;Amazon container services enable developers to orchestrate containers with the unparalleled powers of Kubernetes, granting DevOps Engineers the ability to control containerized deployments with finesse and precision. It enables DevOps Engineers to explore the capabilities of the Cloud concept of application development, unleashing container-based architecture's full potential.&lt;/p&gt;

&lt;p&gt;Amazon Cloud Services has a diverse and supportive community of contributors and a well-documented resource; this creates a sense of belonging and provides a passionate community about the containerized community. Though the challenges of configuring IAM roles, building container images, and navigating the intricacies of ECS or EKS may present occasional obstacles, As the curtain rises on the Introduction to AWS container services, individuals step into a realm where dreams of scalability, flexibility, and seamless deployments are within reach, evoking a sense of wonder at the infinite possibilities awaiting them in the cloud's embrace.&lt;/p&gt;

&lt;h1&gt;
  
  
  2. Understanding Containers on AWS
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Introduction to Amazon Elastic Container Service (ECS)
&lt;/h2&gt;

&lt;p&gt;Amazon Elastic Container Service (ECS) is a fully managed container orchestration service that enables developers to quickly deploy, manage, and scale containerized applications. It also has AWS configuration and operational best practices built in. ECS is integrated with AWS and third-party tools, such as Amazon Elastic Container Registry and Docker. This integration makes it easier for teams to focus on building the applications, not the environment.&lt;/p&gt;

&lt;h2&gt;
  
  
  There are three layers in Amazon ECS:
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Capacity&lt;/strong&gt; - The infrastructure where your container run&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Controller&lt;/strong&gt; - Deploy and manage your applications that run on the containers&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Provisioning&lt;/strong&gt; - The tools that you can use to interface with the scheduler to deploy and manage your applications and containers.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  The following diagram shows the Amazon ECS layers.
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--sLlobPxe--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vq96ti10dfyqcwa5fcno.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--sLlobPxe--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vq96ti10dfyqcwa5fcno.png" alt="Amazon ECS layers" width="800" height="525"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Amazon ECS capacity Layer
&lt;/h2&gt;

&lt;p&gt;This is the infrastructure layer where your containers run, and it is made up of the following components. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Amazon EC2 instances in the AWS cloud&lt;/strong&gt; - This is where you choose the instance type, number of instances, and where you can also manage the capacity. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Serverless (AWS Fargate) in the AWS cloud&lt;/strong&gt; - Fargate is a serverless pay-as-you-go compute engine. With Fargate you don't need to manage servers, handle capacity planning, or isolate container workloads for security.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;On-premises virtual machines (VM) or servers&lt;/strong&gt; - This component allows you to register an external instance such as an on-premises server or virtual machine, to your Amazon ECS cluster.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Amazon ECS controller layer&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The Amazon ECS scheduler is the software that manages your applications.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Amazon ECS provisioning layer&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;There are multiple options for provisioning Amazon ECS:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;AWS Management Console&lt;/strong&gt; — Provides a web interface that you can use to access your Amazon ECS resources.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AWS Command Line Interface (AWS CLI)&lt;/strong&gt; — Provides commands for a broad set of AWS services, including Amazon ECS.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AWS SDKs&lt;/strong&gt; — Provides language-specific APIs and takes care of many of the connection details. These include calculating signatures, handling request retries, and error handling.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Copilot&lt;/strong&gt; — Provides an open-source tool for developers to build, release, and operate production ready containerized applications on Amazon ECS.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AWS CDK&lt;/strong&gt; — Provides an open-source software development framework that you can use to model and provision your cloud application resources using familiar programming languages.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  key features of Amazon ECS:
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Options to run your applications on Amazon EC2 instances, a serverless environment, or on-premises VMs.&lt;/li&gt;
&lt;li&gt;Integration with AWS Identity and Access Management (IAM). You can assign granular permissions for each of your containers.&lt;/li&gt;
&lt;li&gt;AWS managed container orchestration with operational best practices built-in, and no control plane, nodes, or add-ons for you to manage. &lt;/li&gt;
&lt;li&gt;Continuous integration and continuous deployment (CI/CD). This is a common process for microservice architectures that are based on Docker containers.&lt;/li&gt;
&lt;li&gt;Support for service discovery. This is a key component of most distributed systems and service-oriented architectures. With service discovery, your microservice components are automatically discovered as they're created and terminated on a given infrastructure.&lt;/li&gt;
&lt;li&gt;Monitoring and logging&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Differences between Fargate and EC2 launch types
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--dfT4yi5i--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/weskw3h0cu2b46n4j14f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--dfT4yi5i--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/weskw3h0cu2b46n4j14f.png" alt="EC2 vs Fargate" width="800" height="418"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Amazon Fargate and EC2 launch types are two options available within Amazon Elastic Container Service (ECS) for running containers. Here are four key differences between them:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Serverless vs. Self-managed Infrastructure:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Fargate: Fargate is a serverless compute engine for containers. With Fargate, you don't need to provision or manage any underlying infrastructure. AWS takes care of server provisioning, scaling, and management, allowing you to focus solely on deploying and running your containers.&lt;/li&gt;
&lt;li&gt;EC2: EC2 launch type, on the other hand, requires you to manage and provision EC2 instances to run your containers. You need to choose the instance types, manage capacity, and handle auto-scaling to ensure the availability and performance of your containers.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;

&lt;p&gt;&lt;strong&gt;Granularity of Control:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Fargate: Fargate offers a high level of abstraction, making it easy to deploy and manage containers without worrying about the underlying infrastructure details. However, this also means that you have less granular control over the underlying resources, such as the host operating system or the networking stack.&lt;/li&gt;
&lt;li&gt;EC2: With EC2 launch type, you have more control over the EC2 instances that run your containers. This enables you to fine-tune the instance configuration, use custom AMIs, and apply advanced networking configurations as needed.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;

&lt;p&gt;&lt;strong&gt;Billing Model:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Fargate: Fargate follows a pay-as-you-go pricing model, where you are charged based on the vCPU and memory resources your containers consume, and you don't pay for idle resources. This model can be cost-effective for workloads with variable or unpredictable traffic patterns.&lt;/li&gt;
&lt;li&gt;EC2: EC2 launch type is billed based on the EC2 instances you provision, regardless of whether your containers fully utilize the available resources or not. As a result, the cost may be higher for workloads that experience fluctuations in demand or have inconsistent resource utilization.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;

&lt;p&gt;&lt;strong&gt;Ease of Management:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Fargate: Fargate is designed for simplicity and ease of management. AWS handles all the infrastructure tasks, such as patching, updates, and scaling, allowing you to focus solely on managing your containerized applications.&lt;/li&gt;
&lt;li&gt;EC2: While EC2 launch type provides more control over the underlying instances, it also requires more management effort on your part. You need to monitor the instances, apply updates, manage security, and handle scaling based on demand.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When choosing between Amazon Fargate and EC2 launch types, consider factors such as the level of control required, workload characteristics, and cost considerations. Fargate is well-suited for developers who want to abstract away infrastructure management and focus on application development, while EC2 launch type provides more flexibility and control for users who require custom configurations and fine-tuning of the container environment.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Introduction to Amazon Elastic Kubernetes Service (EKS)
&lt;/h2&gt;

&lt;p&gt;The Introduction to Amazon Elastic Kubernetes Service (EKS) unveils a realm of boundless possibilities for container orchestration. Amazon EKS is a managed Kubernetes service to run Kubernetes in the AWS cloud and on-premises data centers. &lt;/p&gt;

&lt;p&gt;In the cloud, Amazon EKS automatically manages the availability and scalability of the Kubernetes control plane nodes responsible for scheduling containers, managing application availability, storing cluster data, and other key tasks. With Amazon EKS, you can take advantage of all the performance, scale, reliability, and availability of AWS infrastructure and integrations with AWS networking and security services.&lt;/p&gt;

&lt;p&gt;As the managed Kubernetes service provided by AWS, EKS empowers developers to effortlessly deploy, manage effortlessly, and scale containerized applications using the powerful Kubernetes platform. With EKS, the complexities of setting up and maintaining a Kubernetes cluster fade into obscurity as AWS shoulders the burden of infrastructure management and ensures high availability and resilience. &lt;/p&gt;

&lt;p&gt;The journey into Amazon EKS embarks on a voyage of innovation, collaboration, and enhanced agility, inviting newcomers and seasoned Kubernetes enthusiasts to navigate the waters of container orchestration with confidence and unbridled excitement.&lt;/p&gt;

&lt;h2&gt;
  
  
  Key features of the Amazon Elastic Kubernetes Service
&lt;/h2&gt;

&lt;p&gt;The Amazon Elastic Kubernetes Service (EKS) offers an array of features that spark feelings of excitement and confidence in the hearts of developers and IT teams alike:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Seamless Scalability:&lt;/strong&gt; The scalability of EKS invokes a sense of liberation, as it effortlessly adapts to varying workloads. Whether it's a surge in traffic during peak hours or a sudden influx of users, EKS dynamically adjusts resources, alleviating the fear of application slowdowns and ensuring a smooth user experience.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Streamlined Deployment:&lt;/strong&gt; EKS' streamlined deployment process ignites enthusiasm, as it allows developers to swiftly roll out containerized applications without getting entangled in the intricacies of Kubernetes cluster setup. The ease of use empowers teams to focus on innovation, inspiring them to bring their ideas to life with unparalleled efficiency.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;High Availability and Reliability:&lt;/strong&gt; The reliability of EKS evokes a sense of trust and security, knowing that the applications will remain accessible and stable, even during challenging times. With built-in redundancy and automated failover mechanisms, EKS provides a safety net that bolsters confidence in the face of uncertainty.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Intelligent Auto-scaling:&lt;/strong&gt; EKS' intelligent auto-scaling capabilities elicit feelings of awe, as it intuitively monitors application demand and adjusts resources accordingly. The knowledge that the infrastructure can autonomously handle traffic spikes and downturns instills a sense of peace, allowing teams to focus on innovation without fearing performance bottlenecks.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Seamless Integrations:&lt;/strong&gt; The seamless integration of EKS with other AWS services brings a sense of unity and harmony to the cloud ecosystem. It inspires collaboration between applications and services, amplifying the potential for building feature-rich, interconnected solutions that delight users and customers alike.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Enhanced Security:&lt;/strong&gt; The robust security measures of EKS generate feelings of assurance and peace of mind. From role-based access control to automated security updates, EKS creates a shield of protection around the containerized applications, ensuring data integrity and safeguarding against cyber threats.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Community and Support:&lt;/strong&gt; The strong EKS community and AWS support invoke feelings of camaraderie and belonging. Knowing that there is a vast network of experts, resources, and documentation to lean on fosters a sense of empowerment, enabling developers to explore the full potential of Kubernetes with a safety net of knowledge.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Comparison of ECS and EKS for container orchestration
&lt;/h2&gt;

&lt;p&gt;When comparing Amazon Elastic Container Service (ECS) and Amazon Elastic Kubernetes Service (EKS) for container orchestration, it elicits a range of emotions that stem from the unique strengths and characteristics of each service:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Simplicity and Ease of Use (ECS):&lt;/strong&gt; ECS evokes feelings of simplicity and ease of use, offering a straightforward approach to container orchestration. It allows developers to focus on their applications without the added complexity of managing Kubernetes infrastructure. The simplicity of ECS fosters a sense of relief, enabling quick deployments and reducing the learning curve for teams, particularly those new to containerization and orchestration.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Flexibility and Community (EKS):&lt;/strong&gt; EKS sparks feelings of excitement and curiosity due to its inherent flexibility and the vibrant Kubernetes community it embraces. EKS opens doors to a vast ecosystem of tools, plugins, and knowledge, nurturing a sense of empowerment and inspiration. This flexibility fosters a spirit of exploration, enabling teams to leverage the rich Kubernetes feature set, custom configurations, and integration possibilities to build innovative and scalable solutions.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Managed Infrastructure (ECS):&lt;/strong&gt; ECS invokes a sense of relief and peace of mind with its managed infrastructure. Teams appreciate the freedom from infrastructure management responsibilities, allowing them to focus on application development and deployment. This managed approach evokes feelings of security and trust, knowing that AWS handles the underlying infrastructure, patching, and scaling, thus relieving the burden of operational tasks and enabling teams to concentrate on delivering high-quality applications.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Granularity and Control (EKS):&lt;/strong&gt; EKS elicits feelings of control and precision, appealing to developers seeking fine-grained control over their container orchestration environment. The ability to customize Kubernetes configurations, choose specific container runtimes, and access advanced networking options invokes a sense of empowerment and confidence. EKS provides a playground for meticulous fine-tuning, creating an atmosphere of excitement and satisfaction among those who desire a high level of control.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let's end the first part of the 2 part series article here and continue in article two. You will learn about the following topics in &lt;a href="https://dev.to/ginowine/a-guide-to-getting-started-with-aws-containers-part-two-4jeo"&gt;article 2.&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Setting Up AWS for Containers&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Creating an AWS account&lt;/li&gt;
&lt;li&gt;Configuring AWS Identity and Access Management (IAM) roles and policies&lt;/li&gt;
&lt;li&gt;Creating a VPC with Public and Private Subnets for Your Clusters&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Building and Packaging Containerized Applications&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Choosing a containerization technology (Docker, containerd, etc.)&lt;/li&gt;
&lt;li&gt;Introduction to Docker&lt;/li&gt;
&lt;li&gt;Setting Up Docker on AWS&lt;/li&gt;
&lt;li&gt;How to deploy and manage Docker containers on AWS EC2&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Feel free to visit the official &lt;a href="https://docs.aws.amazon.com/whitepapers/latest/aws-overview/containers.html"&gt;Amazon Container Documentation Website&lt;/a&gt; and explore further resources from Amazon &lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/ginowine/a-guide-to-getting-started-with-aws-containers-part-two-4jeo"&gt;Click here to go to article 2&lt;/a&gt;&lt;/p&gt;

</description>
      <category>aws</category>
      <category>cloudcomputing</category>
      <category>containers</category>
      <category>docker</category>
    </item>
    <item>
      <title>How to Convert BTC to RBTC Using The 2-Way Peg App</title>
      <dc:creator>Gino Osahon</dc:creator>
      <pubDate>Wed, 26 Oct 2022 09:13:42 +0000</pubDate>
      <link>https://forem.com/ginowine/how-to-convert-btc-to-rbtc-using-the-2-way-peg-app-p9d</link>
      <guid>https://forem.com/ginowine/how-to-convert-btc-to-rbtc-using-the-2-way-peg-app-p9d</guid>
      <description>&lt;h1&gt;
  
  
  Overview
&lt;/h1&gt;

&lt;p&gt;The &lt;a href="https://2wp-app.rsk.co/"&gt;2 way peg&lt;/a&gt; is a protocol to convert BTC to RBTC and vice versa. It is secured by the powpeg, which is a unique 2-way peg system that secures the locked bitcoins with the same Bitcoin hashrate that establishes consensus. See the history of the &lt;a href="https://dev.to/rsk/architecture/flyover"&gt;Powpeg&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The 2 way peg is a web application that fosters the interaction between the bitcoin blockchain and the RSK network for easier exchange of BTC and RBTC. It provides a way to visualize the status of transactions, communicate with a user wallet (both hardware wallets and software wallets), while also providing the highest possible level of security for transactions.&lt;/p&gt;

&lt;p&gt;In this guide, we are going to learn how to use the 2 way peg app application, its features, benefits, how to use hardware and software wallets to perform peg-ins, and how to view transaction statuses. This guide also provides more advanced operation instructions including how to use different wallets, selecting fees, et cetera.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Note: Current version (v1.1.0) of the 2 way peg app does not support peg-outs.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  How it Works
&lt;/h2&gt;

&lt;p&gt;The 2 way peg app uses a &lt;a href="https://en.wikipedia.org/wiki/Representational_state_transfer"&gt;REST API&lt;/a&gt; and a &lt;a href="https://github.com/rsksmart/2wp-api"&gt;2 way peg api&lt;/a&gt; as the backend, this API uses a &lt;a href="https://en.wikipedia.org/wiki/Daemon_(computing)"&gt;daemon&lt;/a&gt; process, which is responsible for listening on blockchain transactions to update the state of peg-ins and in the future, the state of peg-outs, these state changes (tx hash, date change, last status) are stored in a mongodb database.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Currently, the 2 way peg app is available on both &lt;a href="https://2wp-app.rsk.co/"&gt;RSK Mainnet&lt;/a&gt; and &lt;a href="https://2wp-app.testnet.rsk.co/"&gt;RSK Testnet&lt;/a&gt;. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The source code is available on github, and open source:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="//github.com/rsksmart/2wp-app"&gt;Front end&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="//github.com/rsksmart/2wp-api"&gt;Back end&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Features
&lt;/h2&gt;

&lt;p&gt;The 2 way peg app, has two primary features, they are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Peg-in: A conversion from BTC to RBTC. See &lt;a href="https://dev.to/gNqfE7PjQ4qsdxoCsCCutg#Glossary"&gt;Glossary&lt;/a&gt; section for more explanation. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Note: The peg-in process is final and cannot be reverted&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Peg-out: A conversion from RBTC to BTC. This current version of the 2 way peg app (v1.1.0) does not support the peg-out functionality.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why use the 2 way peg?
&lt;/h2&gt;

&lt;p&gt;The 2 way peg application has lots of benefits, these include:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Simplified transactions&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The peg-in in its nature is a complex process and this app makes it simpler. Using the 2 way peg app enables you to choose where to receive the converted BTC, which is also possible without it, but with an even higher level of complexity than a legacy peg-in.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Visualization of transactions&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Enables the visualization of the status of transactions on the RSK network&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Enables communication with a user wallet (hardware and software)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The 2 way peg app communicates directly with the following services:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Trezor: Directly via usb&lt;/li&gt;
&lt;li&gt;Ledger: Directly via usb and integrated with the manufacturer's application&lt;/li&gt;
&lt;li&gt;Liquality: Directly through the application provided by the company&lt;/li&gt;
&lt;li&gt;Nifty: Through the rLogin application&lt;/li&gt;
&lt;li&gt;Metamask: Through the rLogin application. Learn more about the &lt;a href="https://github.com/rsksmart/rLogin"&gt;rLogin application&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Secure transactions&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;All transactions need to be confirmed via the device used by the customer, whether a hardware or software wallet, all transaction information and the appropriate signatures are generated through integration with the wallets.&lt;/p&gt;

&lt;h2&gt;
  
  
  Next
&lt;/h2&gt;

&lt;p&gt;Be sure to check out our next article &lt;a href="https://developers.rsk.co/guides/two-way-peg-app/getting-started/"&gt;How to get started using the 2 way peg app&lt;/a&gt; on the RSK Developer Portal. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://developers.rsk.co/guides/two-way-peg-app/overview/"&gt;This article was originally posted on the RSK Developer Portal&lt;/a&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Resources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;2 way peg app frontend &lt;a href="https://github.com/rsksmart/2wp-app"&gt;repo&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;2 way peg app backend &lt;a href="https://github.com/rsksmart/2wp-api"&gt;repo&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;How to get &lt;a href="https://developers.rsk.co/guides/get-crypto-on-rsk/powpeg-btc-rbtc/"&gt;RBTC using RSK’s built in Powpeg&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://faucet.rsk.co/"&gt;RSK Testnet Faucet&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developers.rsk.co/guides/get-crypto-on-rsk/rbtc-exchanges/"&gt;Get RBTC using Exchanges&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
    </item>
    <item>
      <title>Overview - The Complete Guide to Decentralized Exchanges (DEX)</title>
      <dc:creator>Gino Osahon</dc:creator>
      <pubDate>Tue, 20 Sep 2022 08:28:48 +0000</pubDate>
      <link>https://forem.com/ginowine/overview-the-complete-guide-to-decentralized-exchanges-dex-94g</link>
      <guid>https://forem.com/ginowine/overview-the-complete-guide-to-decentralized-exchanges-dex-94g</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--1MC568FQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e8qlymifrcitkprx01gf.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--1MC568FQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e8qlymifrcitkprx01gf.jpeg" alt="decentralized exchange" width="800" height="531"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this guide, you will learn about decentralized exchanges (DEX), types of DEXes, features of a DEX - lending, borrowing and yield farming. We will explore the differences between a centralized exchange(CEX) and a DEX, On-chain order books, Off-chain order books, Automated Market Makers (AMM), and the different types of DEXes oN RSK.&lt;/p&gt;

&lt;h2&gt;
  
  
  Overview
&lt;/h2&gt;

&lt;h2&gt;
  
  
  What is a DEX?
&lt;/h2&gt;

&lt;p&gt;A decentralized exchange, also known as DEX, is a peer-to-peer trading platform where cryptocurrency holders and traders make transactions directly without handing over management of their funds to an intermediary or a custodian. DEXes have become a pivotal element in the crypto world by enabling trading with considerable improvements in crypto volume. &lt;/p&gt;

&lt;h2&gt;
  
  
  How DEXes Work
&lt;/h2&gt;

&lt;p&gt;A decentralized exchange (DEX) excludes the need for any centralized authority, supervision, and authorization of transactions on exchanges. DEXes allow for peer-to-peer cryptocurrency trading by linking crypto buyers and sellers together. DEXes are both custodial and non-custodial in nature. A non-custodial exchange platform means users have control and ownership of their private keys. &lt;/p&gt;

&lt;h2&gt;
  
  
  Types of DEXes
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Order Book DEXes
&lt;/h3&gt;

&lt;p&gt;Order books maintain records of all the open orders for purchasing and selling assets for specific pairs of assets. The &lt;em&gt;buy orders&lt;/em&gt; imply a trader’s interest in purchasing or bidding for an asset at a particular price. While, &lt;em&gt;sell orders&lt;/em&gt; show that the trader is prepared to selling by asking for a specific price for the concerned asset. &lt;/p&gt;

&lt;h4&gt;
  
  
  On-chain order books
&lt;/h4&gt;

&lt;p&gt;These DEXes store their open order information on the blockchain, and are referred to as on-chain order book DEXes. On-chain order book DEXes could help traders in leveraging their positions by using funds from lenders on their platform.&lt;/p&gt;

&lt;h4&gt;
  
  
  Off-chain order books
&lt;/h4&gt;

&lt;p&gt;Off-chain order book DEX platforms store the order books outside of the blockchain networks. The off-chain order book DEXes only perform transaction settlement on the blockchain, thereby offering the value of centralized crypto exchanges. &lt;/p&gt;

&lt;p&gt;The notable examples of order book DEXes on RSK include: &lt;/p&gt;

&lt;h2&gt;
  
  
  DEX Aggregators
&lt;/h2&gt;

&lt;p&gt;These are trading protocols that work by sourcing and routing liquidity throughout multiple DEXes according to specified requirements. DEX aggregators don’t have any need for servicing traders exclusively from their own liquidity pools. This enables DEX aggregators to play a crucial role in delivering efficient approaches for crypto trading.&lt;/p&gt;

&lt;h2&gt;
  
  
  Automated Market Makers
&lt;/h2&gt;

&lt;p&gt;The automated Market Maker (AMM) system uses smart contracts efficiently to address the liquidity problem. Rather than matching the buy orders and sell orders, the smart contracts in AMM-based decentralized exchanges could leverage liquidity pools. The liquidity pools are basically pre-funded pools of assets, which serve an important role in the working of AMM-based DEXes.&lt;/p&gt;

&lt;p&gt;AMMs leverage blockchain-based services for obtaining information from exchanges and other platforms for setting the price of traded assets. These price feed services are provided by blockchain oracles like &lt;a href="https://developers.rsk.co/solutions/chainlink/"&gt;Chainlink&lt;/a&gt;, &lt;a href="https://developers.rsk.co/solutions/api3/"&gt;API3&lt;/a&gt;, &lt;a href="https://developers.rsk.co/solutions/chainbeat/"&gt;Chainbeat&lt;/a&gt;,&lt;br&gt;
and &lt;a href="https://github.com/money-on-chain/Amphiraos-Oracle/blob/master/README.md"&gt;Oracle MOC&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Users provide funding for the liquidity pools and get rewarded with transaction fees allocated for trades on the concerned pair. Such types of users, also known as liquidity providers execute orders. Traders could also earn interest in a trustless and permissionless manner. AMM-based DEXes are generally ranked on the basis of the total amount of funds locked in their smart contracts. &lt;/p&gt;

&lt;p&gt;The AMM-based DEXes can encounter &lt;em&gt;slippage&lt;/em&gt;, which emerges due to a lack of liquidity. Slippage is  evident when the lack of liquidity leads to the buyer paying more than the market price on their orders. In such cases, the larger orders are more likely to encounter higher slippage. Furthermore, liquidity providers could also face the risks of impermanent loss due to the volatility of one asset in trading pairs. &lt;/p&gt;

&lt;p&gt;The notable examples of AMM DEXes on RSK include &lt;a href="https://www.sovryn.app/"&gt;Sovryn&lt;/a&gt;, &lt;a href="https://app.blindex.io/"&gt;Blindex&lt;/a&gt;, and &lt;a href="https://app.rskswap.com/"&gt;RSKSwap&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Next
&lt;/h2&gt;

&lt;p&gt;Be sure to check out our next article in this guide, about &lt;a href="https://developers.rsk.co/guides/dex/dex-vs-cex/"&gt;The difference between a Centralized and a Decentralized Exchange&lt;/a&gt; on the RSK Developer Portal. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://developers.rsk.co/guides/dex/overview/"&gt;This article was originally posted on the RSK Developer Portal&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>blockchain</category>
      <category>cryptocurrency</category>
      <category>dex</category>
    </item>
    <item>
      <title>The difference between stablecoins and other digital assets</title>
      <dc:creator>Gino Osahon</dc:creator>
      <pubDate>Wed, 14 Sep 2022 09:22:30 +0000</pubDate>
      <link>https://forem.com/ginowine/the-difference-between-stablecoins-and-other-digital-assets-3fkk</link>
      <guid>https://forem.com/ginowine/the-difference-between-stablecoins-and-other-digital-assets-3fkk</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Bh2VHri7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://i.imgur.com/3aO4ehf.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Bh2VHri7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://i.imgur.com/3aO4ehf.jpg" alt="stablecoin banner" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this section, we will cover the difference between a stablecoin and other digital assets like bitcoins, fiat currency, fungible tokens, Central Bank Digital Currency (CBDCs), and Altcoins.&lt;/p&gt;

&lt;h2&gt;
  
  
  Stablecoin vs Bitcoins
&lt;/h2&gt;

&lt;p&gt;A stablecoin is a token that has a non-volatile price and Bitcoin is a cryptocurrency whose price is volatile in nature. Stablecoins are used  to minimize the price volatility of cryptocurrencies like Bitcoins.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--_Z-itVVc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://i.imgur.com/H8UL26o.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--_Z-itVVc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://i.imgur.com/H8UL26o.png" alt="StablecoinVsBitcoins" width="800" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Stablecoin vs Altcoin
&lt;/h2&gt;

&lt;p&gt;Altcoins are cryptocurrencies other than Bitcoin. Similar comparisons apply, with regards to volatility.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--750aYhvg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://i.imgur.com/sYeoZi1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--750aYhvg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://i.imgur.com/sYeoZi1.png" alt="Stablecoinvsaltcoin" width="800" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Stablecoin vs Fiat
&lt;/h2&gt;

&lt;p&gt;Stablecoins are issued by crypto companies that are backed by traditional financial investment tools. They can be pegged to any fiat currency, foreign exchange-traded commodities, precious or industrial metals.&lt;/p&gt;

&lt;p&gt;While fiat currencies are issued by central banks, they are not asset-backed. Their value depends on the central bank. The central bank can regulate the total supply in circulation by printing and withdrawing them from use.&lt;/p&gt;

&lt;h2&gt;
  
  
  Stablecoin vs Fungible Tokens
&lt;/h2&gt;

&lt;p&gt;A stablecoin is a type of fungible token whose value is fixed to another asset, often currencies such as the US dollar or the Euro, and other assets.&lt;/p&gt;

&lt;p&gt;Read: &lt;a href="https://developers.rsk.co/kb/get-crypto-on-rsk/cryptocurrency-vs-token/"&gt;Cryptocurrency vs Token&lt;/a&gt; or watch the explainer video below:&lt;/p&gt;

&lt;p&gt;YouTube: &lt;iframe width="710" height="399" src="https://www.youtube.com/embed/GWoNxoaIsbQ"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  Stablecoin vs CBDCs
&lt;/h2&gt;

&lt;p&gt;A stablecoin may or may not be regulated, while Central Bank Digital Currency (CBDC) is completely regulated by the monetary authorities of a nation. This means stablecoins are decentralized while CBDCs are centralized. Furthermore, CBDCs may be implemented with fungible tokens, in a manner similar to stablecoins, or they may be implemented using other technologies, including centralised ones.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--CIcCuv8F--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://i.imgur.com/7iPLuIL.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--CIcCuv8F--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://i.imgur.com/7iPLuIL.png" alt="Stablecoin vs CBDCs" width="800" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Next
&lt;/h2&gt;

&lt;p&gt;See the Complete Guide to &lt;a href="https://developers.rsk.co/guides/stablecoin/"&gt;Stablecoins&lt;/a&gt; on the RSK Developers Portal. &lt;/p&gt;

&lt;p&gt;Thanks for reading!&lt;/p&gt;




</description>
      <category>blockchain</category>
      <category>rsk</category>
      <category>crypto</category>
      <category>stablecoins</category>
    </item>
    <item>
      <title>Introduction | Deploy an NFT project on the RSK Testnet</title>
      <dc:creator>Gino Osahon</dc:creator>
      <pubDate>Wed, 27 Jul 2022 14:33:00 +0000</pubDate>
      <link>https://forem.com/ginowine/introduction-deploy-an-nft-project-on-the-rsk-testnet-2dbl</link>
      <guid>https://forem.com/ginowine/introduction-deploy-an-nft-project-on-the-rsk-testnet-2dbl</guid>
      <description>&lt;p&gt;Welcome to the Complete Guide on How to Create and Deploy an NFT Smart Contract on RSK.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Introduction&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In this tutorial, we will take you through a step by step process on how to write a ERC-721 smart contract, and deploy to the RSK testnet using the following tools: Solidity, Hardhat, Ether.js, RSK Testnet, IPFS, Pinata, and Test RBTC from a faucet. Not to worry, if these terms are new to you - we will explain them!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;We will do the following in this tutorial.&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A brief introduction to NFTs, and ERC-721&lt;/li&gt;
&lt;li&gt;Setting up your environment&lt;/li&gt;
&lt;li&gt;What is IPFS?&lt;/li&gt;
&lt;li&gt;How to set up your Pinata account&lt;/li&gt;
&lt;li&gt;Create NFT metadata (JSON File)&lt;/li&gt;
&lt;li&gt;Create ERC 721 smart contract&lt;/li&gt;
&lt;li&gt;Deploy smart contract on the RSK blockchain&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Prerequisites&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To follow this tutorial, you should have knowledge in:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Smart contract fundamentals using Solidity&lt;/li&gt;
&lt;li&gt;JavaScript&lt;/li&gt;
&lt;li&gt;Command line&lt;/li&gt;
&lt;li&gt;Git&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you are not familiar with the above, it will be advisable to learn the basics by clicking the links above, before proceeding with this tutorial on how to create and deploy your NFT project to the RSK Testnet.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What is a Non-fungible Token (NFT)?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Fungibility, is about whether something is interchangeable and divisible. A fungible token has both of those properties, and behave in a manner similar to fiat cash; whereas a non-fungible token is neither interchangeable nor divisible, and behave in a manner similar to many real-world objects.&lt;/p&gt;

&lt;p&gt;ERC-20 is the most commonly used technical standard for fungible tokens (FTs); and ERC-721 is the most commonly used technical standard for non-fungible tokens (NFTs).&lt;/p&gt;

&lt;p&gt;Non-fungible is a term used to describe digital assets that represent real-world objects like art, furniture, a song file, in-game items, your computer, or even real estate. Unlike ERC-20 tokens, tokens that are created under ERC-721 are not interchangeable, this comes from the fact that while two NFTs may look identical to each other, they both hold unique information. Non-fungible tokens also lack another feature of their ERC-20 counterparts - they are not divisible, which means that you cannot own a portion of an NFT.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;NFTs can be used in the following use cases:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Medical Records and Identity Verification - NFT ledgers can store an individual's medical records without compromising confidentiality or risking tampering from external sources&lt;/li&gt;
&lt;li&gt;Real Estate - NFTs could be used to transfer land deeds, provide proof of ownership and even keep track of changes in property value over time using timestamped NFTs.&lt;/li&gt;
&lt;li&gt;Ensuring Authenticity of Products - NFTs can be used to ensure that the product you are purchasing is authentic. NFTs can also be used to store information about the manufacturing process, ensuring that everything is fair trade&lt;/li&gt;
&lt;li&gt;Academic Credentials - NFTs are also a good way to represent academic credentials. NFTs can provide proof of attendance, degree earned, and other important information which will be stored on the NFT chain that cannot be altered or hacked into.&lt;/li&gt;
&lt;li&gt;Gaming Industry - NFTs can be integrated into the gaming world by allowing NFT cross-platform playability.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;What is ERC-721?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://docs.openzeppelin.com/contracts/3.x/erc721#:~:text=ERC721%20is%20a%20standard%20for,across%20a%20number%20of%20contracts." rel="noopener noreferrer"&gt;ERC-721&lt;/a&gt; is a standard for representing ownership of non-fungible tokens, where each token is unique. It provides functionalities like to transfer tokens from one account to another, getting the current token balance of an account, getting the owner of a specific token, and also the total supply of the token available on the network.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://eips.ethereum.org/EIPS/eip-721" rel="noopener noreferrer"&gt;EIP-721&lt;/a&gt; is a standard interface for non-fungible tokens.&lt;/p&gt;

&lt;p&gt;**Setting up your Development Environment&lt;/p&gt;

&lt;p&gt;What is Hardhat?**&lt;/p&gt;

&lt;p&gt;Hardhat is a development environment that enables you to compile, deploy, test, and debug your RSK software. It helps to manage and automate the recurring tasks that are inherent to the process of building Blockchain applications.&lt;/p&gt;

&lt;p&gt;Check out this step-by-step tutorial on &lt;a href="https://developers.rsk.co/kb/hardhat-setup-on-rsk/" rel="noopener noreferrer"&gt;how to set up a Hardhat project to connect to the RSK Testnet&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What is ethers.js?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Ethers.js is a JavaScript library that allows developers to interact with the blockchain. The library includes utility functions in JavaScript and TypeScript, and can also support wallets.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What is tRBTC (Smart Bitcoin in Testnet)?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The Test Smart Bitcoin (tRBTC) is the token used to pay for the execution of transactions in the RSK Testnet environment.&lt;br&gt;
Watch this video tutorial on &lt;a href="https://www.youtube.com/watch?v=twfK8Rd5hak" rel="noopener noreferrer"&gt;How to Get tRBTC from the RSK Testnet Faucet&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What is IPFS?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;IPFS (Interplanetary File System) is a file system/protocol for storing and sharing content, it allows you to store files, keeping track of them on a distributed network. This storage system allows direct interaction through a secure and global P2P network.&lt;/p&gt;

&lt;p&gt;IPFS files are content-addressable. This means that it uses content identifiers, or CIDs, as a label to point to material in IPFS. These CIDs are based on the contents of the files themselves, and may be thought of as hashes. It doesn't indicate where the content is stored, but it forms a kind of address based on the content itself. This property makes IPFS a suitable platform for referencing images within smart contracts. We will use IPFS to host/store our NFT images.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Configure the metadata for your NFT using Pinata&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To get our tokenURI parameter, which should resolve to a JSON document describing our NFT's metadata which will include properties such as name, description, image, and other attributes, we would need to set up Pinata, a convenient IPFS API and toolkit, to store our NFT asset and metadata.&lt;/p&gt;

&lt;p&gt;To simply put, a tokenURI on an NFT is a unique identifier of what the token "looks" like. A URI could be an API call over HTTPS, an IPFS hash, or anything else that is unique.&lt;/p&gt;

&lt;p&gt;If you don't have a Pinata account, &lt;a href="https://app.pinata.cloud/" rel="noopener noreferrer"&gt;sign up for a free account here&lt;/a&gt; and complete the steps to verify your email.&lt;/p&gt;

&lt;p&gt;Once you've created an account:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Navigate to the "Files" page and click the blue "Upload" button at the top-left of the page.&lt;/li&gt;
&lt;li&gt;Upload two cat images to Pinata - this will be the image asset for your NFTs. Feel free to name the asset whatever you wish&lt;/li&gt;
&lt;li&gt;After you upload, you'll see the file info in the table on the "Files" page. You'll also see a CID column. You can copy the CID by clicking the copy button next to it. You can view your upload at: &lt;a href="https://gateway.pinata.cloud/ipfs/" rel="noopener noreferrer"&gt;https://gateway.pinata.cloud/ipfs/&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now, let's create and upload two other files to pinata, each containing details of two cats in JSON format.&lt;/p&gt;

&lt;p&gt;In your root directory, make a new folder called nft- metadata and add the following json codes:&lt;br&gt;
 &lt;br&gt;
File one is named &lt;code&gt;doerak.json&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"attributes"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"trait_type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Breed"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"value"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"European short hair"&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"trait_type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Parent"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"value"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Gino Osahon"&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Doerak. Gray &amp;amp; white kitty"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"image"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ipfs://QmX7P1aswXLKLPd7RqbtwrNGD9CzGjvNFKmdEhWtBmoyiS"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Doerak"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;File two is named &lt;code&gt;luna.json&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"attributes"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"trait_type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Breed"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"value"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"European short hair"&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"trait_type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Parent"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"value"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Alex Shenshin"&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Luna. Ginger kitty"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"image"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ipfs://QmZZfJcrppaRiq5dWtC6zpnGZRNoVwdyh69VoA89xGW5Yt"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Luna"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Feel free to change the data in the json. You can remove or add to the attributes section. Most importantly, make sure the image field points to the location of your IPFS image.&lt;br&gt;
Once you're done editing the JSON file, save it and upload it to Pinata, following the same steps we did for uploading the image.&lt;br&gt;
 &lt;br&gt;
&lt;strong&gt;Generate a seed phrase&lt;/strong&gt;&lt;br&gt;
 &lt;br&gt;
In your root directory, create a file called secret.json and add your seed phrase.&lt;/p&gt;

&lt;p&gt;Seed phrases are a human-readable version of your private keys. You can sign transactions and recover lost accounts using part of your mnemonic phrase. Mnemonic or seed phrases can range from 12–24 words depending on the blockchain ecosystem you are dealing with. Any app can generate its mnemonic phrase for security purposes.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"mnemonic"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"please put your twelve words long mnemonic phrase to this string now"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To interact with the RSK blockchain, you need an account, which consists of a private key, a public key, and an address.&lt;/p&gt;

&lt;p&gt;BIP-39 is a technical standard that allows the generation of multiple accounts from a set of dictionary words, plus a derivation path. Many software libraries and wallet software implement this technical standard, including both ethers.js and MetaMask, which we'll be using in this tutorial. Note that seed phrases should be treated as securely as private keys, so do not use the one in this tutorial on RSK Mainnet- the usage here is sufficient for use on RSK Testnet only.&lt;br&gt;
 &lt;br&gt;
&lt;strong&gt;Hardhat Configuration&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Let's explain the hardhat.config.js file, the configuration file is always executed on startup before anything else happens, and it has two main tasks. You can define a task as a &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function" rel="noopener noreferrer"&gt;JavaScript async function&lt;/a&gt; with some associated metadata. This metadata is used by Hardhat to automate tasks, or as asynchronous JavaScript functions that get access to the Hardhat Runtime Environment, which exposes its configuration and parameters.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nf"&gt;task&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;deploy&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Deploys smart contract to a blockchain&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;setAction&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;meowContractFactory&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;ethers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getContractFactory&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Meow&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
 &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;meowNft&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;meowContractFactory&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;deploy&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
 &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;meowNft&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;deployed&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
 &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
 &lt;span class="s2"&gt;`Meow NFT deployed to: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;meowNft&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;address&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;\nCopy this address and paste to the 'mint' task in 'hardhat.config.js'`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When the deploy task is called, hardhat will deploy your smart contract to the RSK Blockchain. The function takes two metadata, and the second line const meowContractFactory = await ethers.getContractFactory('Meow'); gets a contractFactory of the compiled source code.&lt;/p&gt;

&lt;p&gt;ContractFactory in ethers.js is an abstraction used to deploy new smart contracts, so Meow here is a factory for instances of our Meow contract.&lt;/p&gt;

&lt;p&gt;The line const meowNft = await meowContractFactory.deploy(); sends a deploy transaction, and the next line await meowNft.deployed(); waits for the transaction to be mined. The last line in the deploy task uses console.log print logging message that says NFT has been deployed to the contract variable address.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nf"&gt;task&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;mint&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Mint new NFT collectibles&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;setAction&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;deployedAddress&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;0xE360F4BFb74A1B2B1d102f40BE6c7D0f5C9d12C8&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;newCIDsToMint&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
 &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;QmaXZxVGYcCY36seYTVuGeY9mWchC1WjMscV1FLNfZsM3f&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;QmR5mspowKw6B68QPSuYE9SGH1A6gPKxjdVRokhAZZh4LD&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="p"&gt;];&lt;/span&gt;
 &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;api&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;ethers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getContractFactory&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Meow&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="kr"&gt;interface&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;signer&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;ethers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getSigners&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
 &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;meowNft&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;ethers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Contract&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;deployedAddress&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;api&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;signer&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
 &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;mintSequentially&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;cid&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;newCIDsToMint&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;shift&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
 &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cid&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;tx&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;meowNft&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;mintNFT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;signer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;address&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;`ipfs://&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;cid&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
 &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;receipt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;tx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;wait&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
 &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;tokenId&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;receipt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;events&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Minted NFT &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;deployedAddress&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; #&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;tokenId&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
 &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;mintSequentially&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
 &lt;span class="p"&gt;}&lt;/span&gt;
 &lt;span class="p"&gt;}&lt;/span&gt;
 &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;mintSequentially&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Task mint when called will mint a new NFT. The line const deployedAddress = '0xE360F4BFb74A1B2B1d102f40BE6c7D0f5C9d12C8'; takes the address where the smart contract source code was deployed to in the deploy task. This means that you need to first run the deploy task, then copy the address of the deployed source code and then assign it here to the deployedAddress constant.&lt;/p&gt;

&lt;p&gt;The below lines contain the IPFS content identifier (CIDs) obtained from Pinata.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;newCIDsToMint&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
 &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;QmaXZxVGYcCY36seYTVuGeY9mWchC1WjMscV1FLNfZsM3f&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;QmR5mspowKw6B68QPSuYE9SGH1A6gPKxjdVRokhAZZh4LD&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;];&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The lines below get the smart contract application programming interface, get the deployers account information, and instantiates the smart contract representation object.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;api&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;ethers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getContractFactory&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Meow&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="kr"&gt;interface&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;signer&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;ethers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getSigners&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
 &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;meowNft&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;ethers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Contract&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;deployedAddress&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;api&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;signer&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The below mintSequentially function mints all items from the newCIDsToMint array one after another. The statement const cid = newCIDsToMint.shift(); removes the first CID from the newCIDsToMint array, if the array is already empty (minted all items). The if statement is called, if there are still items to be minted, it calls the smart contracts mintNFT function thereby initiating a transaction. It then waits for the transaction to be mined, gets the transaction receipt, extracts the ID of the newly minted NFT from the transfer event emitted by the smart contract, and recursively calls itself until the newCIDsToMint array is empty.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;mintSequentially&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;cid&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;newCIDsToMint&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;shift&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
 &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cid&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;tx&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;meowNft&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;mintNFT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;signer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;address&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;`ipfs://&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;cid&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
 &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;receipt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;tx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;wait&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
 &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;tokenId&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;receipt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;events&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Minted NFT &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;deployedAddress&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; #&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;tokenId&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
 &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;mintSequentially&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
 &lt;span class="p"&gt;}&lt;/span&gt;
 &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The module.export section has already been explained in the JSON-RPC base networks section of the "How to set up a Hardhat project for RSK Testnet " tutorial referred to in this article.&lt;br&gt;
 &lt;br&gt;
&lt;strong&gt;Complete Config File&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Your final configuration file should now look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="cm"&gt;/* eslint-disable no-undef */&lt;/span&gt;
&lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@nomiclabs/hardhat-waffle&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;mnemonic&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./.secret.json&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nf"&gt;task&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;deploy&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Deploys smart contract to a blockchain&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;setAction&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;meowContractFactory&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;ethers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getContractFactory&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Meow&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
 &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;meowNft&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;meowContractFactory&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;deploy&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
 &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;meowNft&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;deployed&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
 &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
 &lt;span class="s2"&gt;`Meow NFT deployed to: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;meowNft&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;address&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;\nCopy this address and paste to the 'mint' task in 'hardhat.config.js'`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nf"&gt;task&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;mint&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Mint new NFT collectibles&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;setAction&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;deployedAddress&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;0xE360F4BFb74A1B2B1d102f40BE6c7D0f5C9d12C8&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;newCIDsToMint&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
 &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;QmaXZxVGYcCY36seYTVuGeY9mWchC1WjMscV1FLNfZsM3f&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;QmR5mspowKw6B68QPSuYE9SGH1A6gPKxjdVRokhAZZh4LD&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="p"&gt;];&lt;/span&gt;
 &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;api&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;ethers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getContractFactory&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Meow&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="kr"&gt;interface&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;signer&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;ethers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getSigners&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
 &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;meowNft&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;ethers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Contract&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;deployedAddress&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;api&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;signer&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
 &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;mintSequentially&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;cid&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;newCIDsToMint&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;shift&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
 &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cid&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;tx&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;meowNft&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;mintNFT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;signer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;address&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;`ipfs://&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;cid&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
 &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;receipt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;tx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;wait&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
 &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;tokenId&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;receipt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;events&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Minted NFT &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;deployedAddress&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; #&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;tokenId&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
 &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;mintSequentially&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
 &lt;span class="p"&gt;}&lt;/span&gt;
 &lt;span class="p"&gt;}&lt;/span&gt;
 &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;mintSequentially&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="na"&gt;solidity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;0.8.12&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="na"&gt;defaultNetwork&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;rsktestnet&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="na"&gt;networks&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="na"&gt;hardhat&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{},&lt;/span&gt;
 &lt;span class="na"&gt;rsktestnet&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="na"&gt;chainId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;31&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://public-node.testnet.rsk.co/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="na"&gt;accounts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="nx"&gt;mnemonic&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;m/44'/60'/0'/0&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="p"&gt;},&lt;/span&gt;
 &lt;span class="p"&gt;},&lt;/span&gt;
 &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Create your Smart Contract&lt;/strong&gt;&lt;br&gt;
 &lt;br&gt;
In your root directory, start by creating a new directory called contracts and create a file inside the directory called Meow.sol.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mkdir contracts
touch contracts/Meow.sol
code contracts/Meow.sol
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Below is our NFT smart contract code, which is based on the OpenZeppelin library's ERC-721 implementation. Copy and paste the contents below into your Meow.sol file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
// using OpenZeppelin libraries
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/utils/Counters.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol";
contract Meow is ERC721URIStorage, Ownable {
 /** 
 From the `Counters` docs:
 Provides counters that can only be incremented, decremented or reset. 
 This can be used e.g. to track the number
 of elements in a mapping, issuing ERC721 ids, or counting request ids.
 Include with `using Counters for Counters.Counter;` 
 */
using Counters for Counters.Counter;
 // tracks the number of minted NFTs
 Counters.Counter private _tokenIds;
// calling ERC721 constructor
 constructor() ERC721("Meow NFT", "MEO") {}
// mints new NFTs. Can be called only by the deployer (s/c owner)
 function mintNFT(address recipient, string memory tokenURI)
 public onlyOwner
 returns (uint256)
 {
 // increment counter
 _tokenIds.increment();
 // get new NFT id
 uint256 newItemId = _tokenIds.current();
 // call internal ERC721 mint function
 _mint(recipient, newItemId);
 // write token URI to newly minted NFT
 _setTokenURI(newItemId, tokenURI);
return newItemId;
 }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We are inheriting classes from the OpenZeppelin contracts library, in the command line run npm install @openzeppelin/contracts to install the library into our folder.&lt;/p&gt;

&lt;p&gt;So, what does this code do exactly? Let's break it down, line-by-line.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/utils/Counters.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol";
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At the top of our smart contract, we import three OpenZeppelin smart contract classes and one extension:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;@openzeppelin/contracts/token/ERC721/ERC721.sol contains the implementation of the ERC-721 standard, which our NFT smart contract will inherit. To be a valid NFT, your smart contract must implement all the methods of the ERC-721 standard. To learn more about the inherited ERC-721 functions, see the full ERC-721 specification.&lt;/li&gt;
&lt;li&gt;@openzeppelin/contracts/utils/Counters.sol provides counters that can only be incremented or decremented by one. Our smart contract uses a counter to keep track of the total number of NFTs minted and set the unique ID on our new NFT. (Each NFT minted using a smart contract must be assigned a unique ID-here our unique ID is just determined by the total number of NFTs in existence. For example, the first NFT we mint with our smart contract has an ID of 1, our second NFT has an ID of 2, etc.)&lt;/li&gt;
&lt;li&gt;@openzeppelin/contracts/access/Ownable.sol sets up access control on our smart contract, so only the owner of the smart contract (you) can mint NFTs. Note that including access control is entirely a preference. If you'd like anyone to be able to mint an NFT using your smart contract, remove the word Ownable on line 10 and onlyOwner on line 17.&lt;/li&gt;
&lt;li&gt;@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol - This is a more flexible but more expensive way of storing metadata.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using Counters for Counters.Counter;
 // tracks the number of minted NFTs
 Counters.Counter private _tokenIds;
// calling ERC721 constructor
 constructor() ERC721("Meow NFT", "MEO") {}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After our import statements, we have our custom NFT smart contract, which is surprisingly short - it only contains a counter, a constructor, and single function! This is thanks to our inherited OpenZeppelin contracts, which implement most of the methods we need to create an NFT, such as ownerOf which returns the owner of the NFT, and transferFrom, which transfers ownership of the NFT from one account to another.&lt;/p&gt;

&lt;p&gt;In our ERC-721 constructor, you'll notice we passed 2 strings, Meow-NFT, and MEO. The first variable is the smart contract's name, and the second is its symbol. You can name each of these variables whatever you wish!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// mints new NFTs. Can be called only by the deployer (s/c owner)
 function mintNFT(address recipient, string memory tokenURI)
 public onlyOwner
 returns (uint256)
 {
 // increment counter
 _tokenIds.increment();
 // get new NFT id
 uint256 newItemId = _tokenIds.current();
 // call internal ERC721 mint function
 _mint(recipient, newItemId);
 // write token URI to newly minted NFT
 _setTokenURI(newItemId, tokenURI);
return newItemId;
 }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally, we have our function mintNFT(address recipient, string memory tokenURI) that allows us to mint an NFT! You'll notice this function takes in two variables: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;address recipient specifies the address that will receive your freshly minted NFT &lt;/li&gt;
&lt;li&gt;string memory tokenURI is a string that should resolve to a JSON document that describes the NFT's metadata. An NFT's metadata is really what brings it to life, allowing it to have configurable properties, such as a name, description, image, and other attributes.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;mintNFT calls some methods from the inherited ERC-721 library, and ultimately returns a number that represents the ID of the freshly minted NFT.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How to deploy your NFT to RSK&lt;br&gt;
Steps&lt;/strong&gt;&lt;br&gt;
 &lt;br&gt;
we will do the following steps;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Switch to Node.js 12 for Hardhat to work nvm use 12&lt;/li&gt;
&lt;li&gt;compile Meow-NFT smart contract npx hardhat compile&lt;/li&gt;
&lt;li&gt;deploy Meow-NFT smart contract to RSK testnet. See other possible networks in hardhat.config.js npx hardhat deploy --network rsktestnet&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;you will see a message:&lt;/p&gt;

&lt;p&gt;Meow NFT deployed to: 0xE360F4BFb74A1B2B1d102f40BE6c7D0f5C9d12C8 Copy this address and paste to the 'mint' task in 'hardhat.config.js'&lt;/p&gt;

&lt;p&gt;Paste the address to the mint task!&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;mint your NFTs from CIDs specified in the mint task of project.config.js&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;npx hardhat mint --network rsktestnet&lt;br&gt;
 &lt;br&gt;
&lt;strong&gt;View NFT using Metamask&lt;/strong&gt;&lt;br&gt;
 &lt;br&gt;
&lt;strong&gt;Metamask&lt;/strong&gt;&lt;br&gt;
 &lt;br&gt;
Metamask is a kind of web wallet which facilitates transactions using yours accounts. It can be used with RSK networks too. It has versions for several browsers, like Chrome, Firefox, Opera and Brave.&lt;/p&gt;

&lt;p&gt;Go to metamask.io and install it.&lt;br&gt;
Create an account.&lt;/p&gt;

&lt;p&gt;Write down your 12 word seed phrase. This is used to recover your account, in case you lose your password.&lt;/p&gt;

&lt;p&gt;The seed phrase is the most important thing in a wallet / account!&lt;br&gt;
 &lt;br&gt;
&lt;strong&gt;Connect MetaMask to RSK testnet&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Go to networks -&amp;gt; Custom RPC, and enter the following values:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Network Name RSK Testnet&lt;/li&gt;
&lt;li&gt;New RPC URL &lt;a href="https://public-node.testnet.rsk.co" rel="noopener noreferrer"&gt;https://public-node.testnet.rsk.co&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;ChainID (optional) 31&lt;/li&gt;
&lt;li&gt;Symbol (optional) tRBTC&lt;/li&gt;
&lt;li&gt;Block Explorer URL (optional) &lt;a href="https://explorer.testnet.rsk.co" rel="noopener noreferrer"&gt;https://explorer.testnet.rsk.co&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;After configuring it, select the RSK Testnet.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa4vix88b8adzfeko14sl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa4vix88b8adzfeko14sl.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;MetaMask screenshot before adding NFT collection&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You should now see an account connected to the RSK Testnet.&lt;br&gt;
Not to worry if you see "No NFTs yet" under the NFTs tab,&lt;br&gt;
there is one more step before we'll be able to see them!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Add NFT to Metamask&lt;/strong&gt;&lt;br&gt;
 &lt;br&gt;
Once you're on the RSK network, select the "NFTs" tab on the right and add the NFT smart contract address and the ERC-721 token ID of your NFT - which you should be able to find on &lt;a href="https://explorer.testnet.rsk.co/" rel="noopener noreferrer"&gt;RSK Testnet Explorer&lt;/a&gt; based on the transaction hash from your NFT deployed to RSK Testnet.&lt;/p&gt;

&lt;p&gt;You may need to refresh the page to see your newly minted NFT.&lt;br&gt;
MetaMask screenshot after adding NFT collection&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5p46wxnt91yawwu2o9ry.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5p46wxnt91yawwu2o9ry.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Congratulations! In this article, we learnt about NFTs, IPFS, Hardhat, and we have successfully created and deployed our NFT project to the RSK Testnet.&lt;/p&gt;

&lt;p&gt;If you would like to delve deeper, here are some resources and tools that we recommend.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Resources&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Visit Our Developers Portal &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://open-rsk-dev.slack.com/join/shared_invite/zt-m0pbuyia-QW~WEI27Ag3Do7qWEjW41w#/shared-invite/email" rel="noopener noreferrer"&gt;RSK Open Slack Community&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/channel/UCYQSvSaqX8Q-XMbQmUG0yJg" rel="noopener noreferrer"&gt;RSK Youtube&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://developers.rsk.co/guides/nft/" rel="noopener noreferrer"&gt;This article was originally posted on the RSK Developer Portal.&lt;/a&gt;&lt;/p&gt;

</description>
      <category>blockchain</category>
      <category>rsk</category>
    </item>
  </channel>
</rss>
