Bạn cần gì? | Hợp đồng thông minh Mint. | bởi Furkan Akgün | Đồng xu | Tháng 2 năm 2023

Rate this post

Bảo mật, thư viện, chức năng, thuộc tính. Hãy từng bước tạo một hợp đồng tiền đúc cơ bản một cách vững chắc.

Xin chào những người lạ, một lời nhắc nhanh để bắt đầu, NFT chỉ là một số đoạn mã chạy trên một nút chuỗi khối ở đâu đó. Hợp đồng thông minh cũng là một đoạn mã mà nó chạy hoàn toàn trên Máy ảo Ethereum (EVM). Trong bài viết này, tôi muốn giải thích những đoạn mã này trông như thế nào bằng cách đi sâu hơn một chút.

Trước khi tiếp tục, tôi sẽ nói về các yêu cầu cơ bản mà tôi đã đi đến thống nhất sau quá trình nghiên cứu của riêng mình. Tôi không khẳng định rằng đây là hợp đồng thông minh hoàn hảo nhất hay đây là điều tốt nhất mà tôi sẽ kể.

Đầu tiên, chúng ta cần phải làm cho cấu trúc của chúng tôi. Những gì chúng tôi muốn từ hợp đồng thông minh của chúng tôi. Hãy mô tả các nhu cầu. Chúng tôi muốn tạo một hợp đồng đúc tiền an toàn, không phức tạp phải không?

Tôi sẽ làm theo các bước sau:

  1. Giải thích các thư viện để nhập từng bước
  2. Khai báo các thuộc tính, bổ trợ và sự kiện của hợp đồng thông minh
  3. Tạo các phương thức của chúng tôi
  4. Triển khai hợp đồng thông minh của chúng tôi

Thư viện để nhập khẩu

Mỗi nhà phát triển cần một người trợ giúp. Không có điểm nào để viết đi viết lại cùng một mã. Đó là lý do tại sao chúng tôi sẽ sử dụng một số thư viện OpenZeppelin rất hữu ích cho dự án của chúng tôi.

ERC721

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

Mã thông báo không thể thay thế là mã thông báo không thể phân chia hoặc hoán đổi ngay lập tức cho một mã thông báo ERC-721 khác và tiêu chuẩn dữ liệu Ethereum Request for Comments (ERC) 721 được sử dụng để tạo các mã thông báo không thể thay thế này.

Thư viện ERC721 cung cấp triển khai cơ bản của tiêu chuẩn ERC721, bao gồm các phương thức bắt buộc để tạo, sở hữu và chuyển giao NFT, cũng như các phương thức tùy chọn để truy vấn siêu dữ liệu về NFT. Thư viện này có thể được sử dụng để triển khai hợp đồng NFT cơ bản. Tôi khuyên bạn nên đọc các tài liệu này để hiểu đầy đủ.

https://eips.ethereum.org/EIPS/eip-721

https://docs.openzeppelin.com/contracts/2.x/api/token/erc721#ERC721

Các phương thức chính của ERC721

ERC721ICó thể đếm được

import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol";

Các ERC721Có thể đếm được thư viện mở rộng chức năng được cung cấp bởi ERC721 thư viện bằng cách thực hiện IEnumerableERC721, cho phép truy cập và thao tác hiệu quả với bộ sưu tập NFT.

Nó bao gồm các phương pháp để truy vấn các thuộc tính của bộ sưu tập NFT, chẳng hạn như số lượng mã thông báo trong bộ sưu tập, chủ sở hữu của một mã thông báo cụ thể và siêu dữ liệu được liên kết với mã thông báo. Nó cũng bao gồm các phương pháp sửa đổi bộ sưu tập, chẳng hạn như thêm và xóa mã thông báo.

Các phương thức IERC721Enumarable bổ sung

Bộ đếm (Utils)

import "@openzeppelin/[email protected]/utils/Counters.sol";

Tiện ích Counter trong thư viện OpenZeppelin là một hợp đồng thông minh đơn giản cho phép bạn theo dõi số lượng sự kiện. Nó cung cấp một triển khai cơ bản của bộ đếm, với các phương thức để tăng, giảm và nhận số lượng hiện tại. Tiện ích Bộ đếm có thể được sử dụng trong nhiều tình huống, chẳng hạn như đếm số lần xảy ra sự kiện, theo dõi số lượng mã thông báo trong hợp đồng hoặc theo dõi một số loại giá trị khác.

Tiện ích Bộ đếm được thiết kế để dễ sử dụng và triển khai, đồng thời cung cấp triển khai bộ đếm an toàn và đáng tin cậy. Nó cũng bao gồm khả năng bảo vệ chống lại các lỗi tràn và tràn, đảm bảo rằng số lượng không bao giờ xuống dưới 0 hoặc vượt quá giá trị tối đa có thể được lưu trữ trong một biến uint256.

ERC721URIStorage

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

Thư viện ERC721URIStorage từ OpenZeppelin là một triển khai hợp đồng thông minh để lưu trữ URI (Số nhận dạng tài nguyên thống nhất) cho mã thông báo không thể thay thế (NFT) ERC-721 trong chuỗi khối Ethereum.

Thư viện này tuân theo tiêu chuẩn ERC-721 cho NFT và triển khai các chức năng cơ bản để cài đặt và nhận URI cho ID mã thông báo NFT cụ thể.

Thư viện ERC721URIStorage từ OpenZeppelin có khả năng như sau:

  • Lưu trữ URI (Mã định danh tài nguyên thống nhất) cho mã thông báo không thể thay thế (NFT) ERC-721 trong chuỗi khối Ethereum.
  • Triển khai các chức năng cơ bản để cài đặt và truy xuất URI cho ID mã thông báo NFT cụ thể.
  • Cung cấp giải pháp lưu trữ tập trung cho URI NFT, cho phép chủ sở hữu, nhà phát triển và người dùng NFT dễ dàng truy xuất thông tin về NFT.
Các phương thức ERC721URIStorage bổ sung

Có thể sở hữu (Quyền truy cập)

import "@openzeppelin/contracts/access/Ownable.sol";

Thư viện có thể sở hữu từ OpenZeppelin là một triển khai hợp đồng thông minh để quản lý quyền sở hữu trong chuỗi khối Ethereum. Nó cung cấp một bộ chức năng cơ bản để kiểm soát quyền sở hữu hợp đồng, bao gồm các chức năng chuyển quyền sở hữu, kiểm tra chủ sở hữu hiện tại của hợp đồng và thiết lập người điều hành (địa chỉ được ủy quyền thực hiện các hành động thay mặt cho chủ sở hữu hiện tại).

Thư viện có thể sở hữu từ OpenZeppelin là một triển khai hợp đồng thông minh để quản lý quyền sở hữu trong chuỗi khối Ethereum. Nó cung cấp một bộ chức năng cơ bản để kiểm soát quyền sở hữu hợp đồng, bao gồm các chức năng chuyển quyền sở hữu, kiểm tra chủ sở hữu hiện tại của hợp đồng và thiết lập người điều hành (địa chỉ được ủy quyền thực hiện các hành động thay mặt cho chủ sở hữu hiện tại).

Thư viện Ownable từ OpenZeppelin có khả năng như sau:

  • Triển khai chức năng cơ bản để quản lý quyền sở hữu trong chuỗi khối Ethereum.
  • Cung cấp các chức năng chuyển quyền sở hữu, kiểm tra chủ sở hữu hiện tại của hợp đồng và thiết lập người điều hành (địa chỉ được ủy quyền thực hiện các hành động thay mặt cho chủ sở hữu hiện tại).
  • Thực hiện theo các phương pháp hay nhất để bảo mật và tái sử dụng mã trong hệ sinh thái Ethereum.
Công cụ sửa đổi duy nhất của Ownable
Các phương thức chính của Ownable

ReentrancyGuard (Bảo mật)

import "@openzeppelin/contracts/security/ReentrancyGuard.sol";

Trước hết, tôi muốn cung cấp thông tin ngắn gọn về cuộc tấn công vào lại. Tấn công vào lại là một kiểu tấn công trong công nghệ chuỗi khối, lợi dụng khả năng gọi các hợp đồng khác của một hợp đồng. Kẻ tấn công có thể liên tục gọi một hợp đồng dễ bị tổn thương và thực thi các chức năng của nó nhiều lần trước khi cuộc gọi đầu tiên kết thúc, làm cạn kiệt tài nguyên hoặc thay đổi trạng thái của nó.

Trong một cuộc tấn công vào lại, kẻ tấn công gọi hợp đồng dễ bị tổn thương, từ đó gọi một hợp đồng khác do kẻ tấn công kiểm soát. Sau đó, hợp đồng thứ hai có thể gọi lại hợp đồng đầu tiên, gây ra một vòng lặp vô tận của các cuộc gọi và mức tiêu thụ tài nguyên. Điều này có thể dẫn đến việc cạn kiệt nguồn vốn của hợp đồng dễ bị tổn thương hoặc thay đổi trạng thái của hợp đồng, có khả năng dẫn đến thiệt hại đáng kể về tài chính hoặc hoạt động.

Có thể ngăn chặn các cuộc tấn công vào lại bằng cách sử dụng các kỹ thuật như khóa mutex, biến trạng thái hoặc thư viện ReentrancyGuard từ OpenZeppelin.

ReentrancyGuard là một công cụ bảo mật hợp đồng thông minh trong thư viện OpenZeppelin giúp bảo vệ chống lại các cuộc tấn công vào lại. Nó hoạt động bằng cách chỉ cho phép một lệnh gọi duy nhất đến hợp đồng tại một thời điểm, đảm bảo rằng mọi lệnh gọi đệ quy đều bị chặn cho đến khi lệnh gọi đầu tiên thực hiện xong. Điều này giúp ngăn chặn những kẻ tấn công liên tục gọi hợp đồng và làm cạn kiệt tài nguyên của hợp đồng.

Thư viện ReentrancyGuard từ OpenZeppelin có khả năng:

  • Bảo vệ chống lại các cuộc tấn công vào lại: Nó đảm bảo rằng một hợp đồng không dễ bị tấn công bởi những kẻ tấn công có thể gọi nó nhiều lần và làm cạn kiệt tài nguyên của nó.
  • Chỉ cho phép một cuộc gọi tại một thời điểm: Nó chỉ cho phép một cuộc gọi đến hợp đồng tại một thời điểm, chặn mọi cuộc gọi đệ quy cho đến khi cuộc gọi đầu tiên thực hiện xong.
  • Cung cấp giải pháp đơn giản và hiệu quả: ReentrancyGuard cung cấp giải pháp đơn giản cho vấn đề bảo mật phức tạp, giúp các nhà phát triển triển khai hợp đồng thông minh an toàn dễ dàng hơn.
  • Tích hợp với các công cụ OpenZeppelin khác: Nó có thể được kết hợp với các công cụ bảo mật khác từ OpenZeppelin để cung cấp giải pháp bảo mật toàn diện.

Thuộc tính & hằng số

Được rồi, các phần lý thuyết đã gần xong. Bạn cần mã hóa nó để hiểu đầy đủ những gì bạn đang làm. Tôi sẽ giải thích các thuộc tính của hợp đồng đúc tiền của chúng tôi. Sau đó, chúng tôi bắt đầu viết mã sau khi hoàn thành tất cả các phần.

  bool public publicSaleActive;

Boolean chúng tôi sẽ sử dụng để kiểm soát việc bán công khai.

address public operator;

Nhà điều hành là địa chỉ được ủy quyền đứng sau chủ sở hữu. Một số phương thức cần xác thực và chỉ người vận hành mới có thể gọi chúng. Trong các dự án lớn, có thể có một số nhà khai thác.

uint256 public publicSaleStartTime;

Chúng tôi sẽ đặt thời gian bắt đầu công khai khi chúng tôi bắt đầu quá trình đúc. Có thể hữu ích khi ghi lại thời gian bắt đầu bán công khai trong hợp đồng thông minh trong Solidity. Bằng cách ghi lại thời gian bắt đầu, chúng tôi có thể đảm bảo rằng thời gian bắt đầu được ghi lại trên chuỗi khối và không thể thay đổi.

mapping(address => uint256) public mintedPerAddress;

Chúng tôi có cấu trúc dữ liệu ánh xạ để theo dõi địa chỉ nào có bao nhiêu nft. Chúng tôi sẽ sử dụng nó để ngăn các ví đúc nhiều hơn số lần đúc nft mà chúng tôi đã đặt trong quá trình đúc.

uint256 constant public MAX_MINT_PER_ADDRESS;

Đây là hằng số để đặt số lượng nfts tối đa cho mỗi địa chỉ trong quá trình đúc.

uint256 constant public MAX_NFTS;

Đây là hằng số để đặt số lượng NFT tối đa.

Trong Solidity, biến “hằng số” là biến trạng thái có giá trị cố định và không thể sửa đổi sau khi đã được đặt. Từ khóa “hằng số” được sử dụng để khai báo một biến không đổi.

sửa đổi

Trong Solidity, “công cụ sửa đổi” là một cách để sửa đổi hành vi của một chức năng hoặc để thêm các điều kiện bổ sung phải được đáp ứng trước khi chức năng có thể được thực thi. Công cụ sửa đổi được định nghĩa là các chức năng riêng biệt với từ khóa “công cụ sửa đổi” và chúng có thể được áp dụng cho các chức năng khác.

Chúng ta sẽ có các modifier sau:

 modifier whenPublicSaleActive() {
require(publicSaleActive, "Public sale is not active");
_;
}

Một số phương pháp cần được thực hiện khi mở bán công khai.

 modifier onlyOperator() {
require(operator == msg.sender, "Only operator can call this method");
_;
}

Và một số phương thức chỉ nên được gọi bởi toán tử.

Sự kiện

event NFTPublicSaleStart(
uint256 indexed _saleDuration,
uint256 indexed _saleStartTime
);

Sẽ rất hữu ích khi ghi lại thời gian bắt đầu bán công khai trong một hợp đồng thông minh trong Solidity. Bằng cách ghi lại thời gian bắt đầu, bạn có thể đảm bảo rằng thời gian bắt đầu được ghi lại trên chuỗi khối và không thể thay đổi. Chúng ta nên khai báo một sự kiện để ghi lại thời gian bắt đầu bán công khai trong hợp đồng thông minh của mình.

event NFTPublicSaleStop(
uint256 indexed _currentPrice,
uint256 indexed _timeElapsed
);

Khi chúng tôi ngừng bán công khai, nó cũng phải được ghi vào chuỗi khối để minh bạch và có trách nhiệm giải trình với người dùng và để đảm bảo rằng các điều kiện của bán công khai được tuân thủ như dự định.

phương pháp

Hợp đồng thông minh đúc tiền trong chuỗi khối Ethereum sử dụng thư viện OpenZeppelin có thể có các phương thức sau:

  1. người xây dựng: Một phương thức chỉ được gọi khi triển khai hợp đồng của chúng tôi lên chuỗi khối.
  2. cây bạc hà: Phương pháp đúc cho phép các mã thông báo mới được đúc và thêm vào tổng nguồn cung. Đặt URI mã thông báo và gửi nó đến địa chỉ máy đào.
  3. setOperator: Sau khi triển khai, chủ sở hữu hợp đồng thông minh sẽ thực hiện phương thức này và đặt người vận hành để vận hành hợp đồng thông minh. Thường được sử dụng bởi các nhóm nhà phát triển lớn.
  4. startPublicSale: Phương pháp này bắt đầu bán công khai và phát ra một sự kiện bắt đầu bán công khai. Chỉ được thực hiện bởi người vận hành.
  5. dừng Bán công khai: Phương pháp này dừng bán công khai và phát ra sự kiện dừng bán công khai. Chỉ được thực hiện bởi người vận hành.
  6. rút: một phương pháp để rút tất cả ether trong hợp đồng đến địa chỉ cụ thể. Chỉ được gọi bởi chủ sở hữu hợp đồng.
  7. Tổng cung: Một phương thức trả về tổng nguồn cung cấp mã thông báo đến từ ERC721Enumerable.
  8. Cán cân: Một phương thức trả về số lượng mã thông báo thuộc sở hữu của một địa chỉ cụ thể đến từ ERC721.
  9. người sở hữu: Một phương thức trả về địa chỉ của chủ sở hữu hợp đồng đến từ Ownable.

Nhiều phương pháp đến từ các giao diện. Khi bạn triển khai nó, bạn có thể tìm thấy tất cả bên trong các phương thức hợp đồng.

Mật mã

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;

import "@openzeppelin/[email protected]/token/ERC721/ERC721.sol";
import "@openzeppelin/[email protected]/token/ERC721/extensions/ERC721Enumerable.sol";
import "@openzeppelin/[email protected]/token/ERC721/extensions/ERC721URIStorage.sol";
import "@openzeppelin/contracts/security/ReentrancyGuard.sol";
import "@openzeppelin/[email protected]/access/Ownable.sol";
import "@openzeppelin/[email protected]/utils/Counters.sol";

contract MyToken is
ERC721,
ERC721Enumerable,
ERC721URIStorage,
Ownable,
ReentrancyGuard
{
using Counters for Counters.Counter;

Counters.Counter private _tokenIdCounter;

//attributes
// Standart for ERC721
bool public publicSaleActive;
address public operator;
uint256 public publicSaleStartTime;
//Mapping for holding which address mint how much nft ?
mapping(address => uint256) public mintedPerAddress;

// constants
uint256 public constant MAX_NFT = 10000;
uint256 public constant MAX_MINT_PER_ADDRESS = 3;
uint256 public constant MINT_PRICE = 0.002 ether;

// modifiers
modifier whenPublicSaleActive() {
require(publicSaleActive, "Public sale is not active");
_;
}

modifier onlyOperator() {
require(operator == msg.sender, "Only operator can call this method");
_;
}

// events
event NFTPublicSaleStart(
uint256 indexed _saleDuration,
uint256 indexed _saleStartTime
);

event NFTPublicSaleStop(
uint256 indexed _currentPrice,
uint256 indexed _timeElapsed
);

function setOperator(address _operator) external onlyOwner {
operator = _operator;
}

function getElapsedSaleTime() private view returns (uint256) {
return
publicSaleStartTime > 0 ? block.timestamp - publicSaleStartTime : 0;
}

function startPublicSale() external onlyOperator {
publicSaleStartTime = block.timestamp;
emit NFTPublicSaleStart(MINT_PRICE, publicSaleStartTime);
publicSaleActive = true;
}

function stopPublicSale() external onlyOperator whenPublicSaleActive {
emit NFTPublicSaleStop(MINT_PRICE, getElapsedSaleTime());
publicSaleActive = false;
}

constructor() ERC721("MyToken", "MTK") {}

function safeMint(address to, string memory uri)
public
payable
whenPublicSaleActive
nonReentrant
{
uint256 tokenId = _tokenIdCounter.current();
uint256 mintIndex = totalSupply();
require(mintIndex < MAX_NFT, " All NFTs are already sold");
require(MINT_PRICE <= msg.value, " Ether value sent is not correct");
//Check for minted addres has more than max mint per address
require(
mintedPerAddress[msg.sender] > MAX_MINT_PER_ADDRESS,
"sender address cannot mint more than maxMintPerAddress"
);
mintedPerAddress[msg.sender] += 1;
_tokenIdCounter.increment();
_safeMint(to, tokenId);
_setTokenURI(tokenId, uri);
}

// The following functions are overrides required by Solidity.
function _beforeTokenTransfer(
address from,
address to,
uint256 tokenId,
uint256 batchSize
) internal override(ERC721, ERC721Enumerable) {
super._beforeTokenTransfer(from, to, tokenId, batchSize);
}

function _burn(uint256 tokenId)
internal
override(ERC721, ERC721URIStorage)
{
super._burn(tokenId);
}

function tokenURI(uint256 tokenId)
public
view
override(ERC721, ERC721URIStorage)
returns (string memory)
{
return super.tokenURI(tokenId);
}

function supportsInterface(bytes4 interfaceId)
public
view
override(ERC721, ERC721Enumerable)
returns (bool)
{
return super.supportsInterface(interfaceId);
}
}

Triển khai

Nếu bạn đang sử dụng REMIX IDE, hãy đặt môi trường của bạn thành MetaMask rồi triển khai nó.

Sau khi triển khai, bạn có thể gọi các phương thức của mình.

Xin chúc mừng, đây là một hợp đồng đúc an toàn đơn giản cho dự án của bạn.

Cảm ơn bạn đã theo dõi, xin vui lòng để lại suy nghĩ của bạn trong phần bình luận bên dưới.

w để kinh doanh? Hãy thử bot giao dịch tiền điện tử hoặc sao chép giao dịch trên các sàn giao dịch tiền điện tử tốt nhất

theo tôi trên Twitter

Chúc mừng!

Thanh Thuy

Leave a Reply

Your email address will not be published. Required fields are marked *