# Essential Patterns and Practices in Smart Contract Development

## 1.1 Overwiew

{% hint style="info" %}
Smart contracts are self-executing agreements with the terms encoded within the code. They operate on blockchain networks such as Ethereum and are primarily written in Solidity. This documentation provides guidance on best practices and patterns in developing and deploying smart contracts for both fungible tokens (ERC-20) and non-fungible tokens (ERC-721).
{% endhint %}

***

## 1.2 Setting Up Development Environment

#### Prerequisites

* **Node.js** and **npm** to manage dependencies.
* **Truffle** or **Hardhat** framework for compiling, testing, and deploying contracts.
* **Solidity** (usually installed with Truffle or Hardhat) as the primary programming language for Ethereum-based smart contracts.
* **Ganache** for local blockchain testing.

#### Installation of Tools

```bash
# Install Truffle or Hardhat
npm install -g truffle
# or
npm install --save-dev hardhat
```

#### Directory Structure

```
project-directory/
│
├── contracts/                    # Contains Solidity contract files
│   ├── Token.sol                  # ERC-20 contract
│   ├── NFT.sol                    # ERC-721 contract
│
├── migrations/                    # Migration scripts for deployment
│
├── test/                          # Test files for contracts
│   ├── Token.test.js
│   ├── NFT.test.js
│
├── truffle-config.js              # Configuration file for Truffle
└── hardhat.config.js              # Configuration file for Hardhat
```

***

## 1.3 ERC-20 Smart Contract for Tokens

The ERC-20 standard defines a fungible token, which means each token is identical to another token. Below is an example of a basic ERC-20 contract with Solidity.

### 1.3.1 ERC-20 Contract Code

```solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";

contract MyToken is ERC20 {
    constructor(uint256 initialSupply) ERC20("MyToken", "MTK") {
        _mint(msg.sender, initialSupply * (10 ** decimals()));
    }

    // Optional functions for additional functionality
    function mint(address to, uint256 amount) external {
        _mint(to, amount);
    }

    function burn(address from, uint256 amount) external {
        _burn(from, amount);
    }
}
```

### 1.3.2 Explanation

{% tabs %}
{% tab title="ERC20" %}
This contract inherits the ERC20 implementation from OpenZeppelin for secure and standard-compliant functions.
{% endtab %}

{% tab title="Initial Supply" %}
The constructor initializes the token supply by minting an amount to the deployer's address.
{% endtab %}

{% tab title="Mint and Burn" %}
Additional functions allow minting and burning, which can be useful for applications like staking or supply control.
{% endtab %}
{% endtabs %}

### 1.3.3 Deployment of ERC-20 Contract

Use Truffle or Hardhat migration scripts to deploy this contract.

#### Truffle Migration Script

```javascript
const MyToken = artifacts.require("MyToken");

module.exports = function (deployer) {
    const initialSupply = web3.utils.toWei("1000", "ether");
    deployer.deploy(MyToken, initialSupply);
};
```

#### Hardhat Deployment Script

```javascript
const { ethers } = require("hardhat");

async function main() {
    const initialSupply = ethers.utils.parseEther("1000");
    const MyToken = await ethers.getContractFactory("MyToken");
    const myToken = await MyToken.deploy(initialSupply);
    await myToken.deployed();

    console.log("MyToken deployed to:", myToken.address);
}

main();
```

***

## 1.4 ERC-721 Smart Contract for NFTs

The ERC-721 standard defines a non-fungible token (NFT), meaning each token is unique and cannot be exchanged on a 1-to-1 basis with another token.

### 1.4.1 ERC-721 Contract Code

```solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol";
import "@openzeppelin/contracts/access/Ownable.sol";

contract MyNFT is ERC721URIStorage, Ownable {
    uint256 public nextTokenId;
    address public admin;

    constructor() ERC721("MyNFT", "MNFT") {
        admin = msg.sender;
    }

    function mint(address to, string memory uri) external onlyOwner {
        uint256 tokenId = nextTokenId;
        _safeMint(to, tokenId);
        _setTokenURI(tokenId, uri);
        nextTokenId++;
    }

    function burn(uint256 tokenId) external onlyOwner {
        _burn(tokenId);
    }
}
```

### 1.4.2 Explanation

{% tabs %}
{% tab title="ERC721URIStorage" %}
This contract extension from OpenZeppelin allows for storing metadata (such as the token's URI) on the blockchain.
{% endtab %}

{% tab title="Minting and Burning" %}
Functions are restricted to the contract owner to mint unique tokens with specific URIs and burn tokens when necessary.
{% endtab %}
{% endtabs %}

### 1.4.3 Deployment of ERC-721 Contract

#### Truffle Migration Script

```javascript
const MyNFT = artifacts.require("MyNFT");

module.exports = function (deployer) {
    deployer.deploy(MyNFT);
};
```

#### Hardhat Deployment Script

```javascript
const { ethers } = require("hardhat");

async function main() {
    const MyNFT = await ethers.getContractFactory("MyNFT");
    const myNFT = await MyNFT.deploy();
    await myNFT.deployed();

    console.log("MyNFT deployed to:", myNFT.address);
}

main();
```

***

## 1.5 Best Practices for Secure and Efficient Smart Contracts

### 1.5.1 Security Practices

{% tabs %}
{% tab title="Reentrancy Guard" %}
Use `nonReentrant` from OpenZeppelin's `ReentrancyGuard` contract to prevent reentrancy attacks.
{% endtab %}

{% tab title="SafeMath" %}
Use safe math functions to prevent integer overflows (integrated in Solidity 0.8.0 and higher).
{% endtab %}

{% tab title="Access Control" %}
Restrict sensitive functions (like minting) to only authorized accounts by using `Ownable` or `AccessControl`.
{% endtab %}

{% tab title="Code Reviews" %}
Perform code reviews and audits to detect vulnerabilities.
{% endtab %}
{% endtabs %}

### 1.5.2 Gas Optimization

{% tabs %}
{% tab title="Use Constant Variables" %}
Use `constant` for variables that won’t change to reduce gas costs.
{% endtab %}

{% tab title="Batch Operations" %}
Consider batch operations for actions affecting multiple tokens to minimize gas fees.
{% endtab %}

{% tab title="Minimize Storage Writes" %}
Store data off-chain if feasible, especially for non-critical information.
{% endtab %}
{% endtabs %}

***

## 1.6 Testing and Deployment on Mainnet

Testing is essential before deploying to the mainnet. Use Truffle or Hardhat’s testing frameworks to test contract functions locally and on test networks.

#### Test in Truffle

```javascript
const MyToken = artifacts.require("MyToken");

contract("MyToken", accounts => {
    it("should mint initial supply to the deployer", async () => {
        const myToken = await MyToken.deployed();
        const balance = await myToken.balanceOf(accounts[0]);
        assert(balance.toString() === web3.utils.toWei("1000", "ether"));
    });
});
```

### 1.6.1 Deployment to Mainnet

1. Ensure the contract is fully tested.
2. Set up a deployment wallet with sufficient ETH for gas.
3. Use your `.env` to securely manage your private key and Infura/Alchemy endpoint.

```bash
npx hardhat run --network mainnet scripts/deploy.js
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://capsurelabs.gitbook.io/technical-documentation-1/smart-contract-development-and-deployment/essential-patterns-and-practices-in-smart-contract-development.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
