区块链—NFT介绍及发行

NFT介绍

NFT 或非同质化代币一种是代表数字物品所有权的独特数字资产。与传统的数字文件不同,NFT 由区块链技术保护,使其具有防篡改和可验证性。这为在数字世界中建立所有权和真实性提供了一种新的方法。

NFT 依靠区块链技术来确保其所有权记录的完整性和安全性。NFT 交易历史和所有者顺序的完整记录安全地存储在区块链上,每个参与节点都有助于确保其准确性并防止篡改。

虽然 NFT 的元数据、监管链以及真实性记录都存储在区块链上,但 NFT 所代表的媒体往往不是这样。区块链上存储大型图像文件会很昂贵,因此许多人选择在链外存储NFT的媒体文件,并通过NFT的内存储的链接指向该文件。

去中心化媒体存储(如Arweave或星际文件系统(IPFS))作为替代方案,解决了中心化媒体存储服务相关的许多漏洞。

如要将 NFT 的媒体文件存储在星际文件系统 (IPFS) 上,用户可以通过 Pinata 或 Filecoin 等平台上传他们的文件。该文件将被分配一个唯一的密码散列,该散列与区块链上 NFT 的元数据相关联。这种去中心化的方法确保了媒体的可访问性和安全性,降低了与中心化存储相关的修改或删除风险。

IPFS介绍

星际文件系统(InterPlanetary File System,缩写为IPFS)是一个旨在实现文件的分布式存储、共享和持久化的网络传输协议。它是一种内容可寻址的对等超媒体分发协议。在IPFS网络中的节点构成一个分布式文件系统。

在IPFS系统中,内容会分块存放(如果内容很小就会直接存在DHT中),并分散存储在IPFS网络中的节点上(不过目前的IPFS实现,一个节点会完整保存内容的所有区块)。系统会给内容的每一个块计算哈希值,然后把所有块的哈希值拼凑起来,再计算一次哈希值,从而得到最终的哈希值。同时每个节点会维护一张DHT(分布式哈希表),包含数据块与目标节点的映射关系。

在IPFS中是通过哈希去请求文件的,它就会使用这个分布式哈希表找到文件所在的节点,取回文件根据哈希重新组合文件(同样也会验证文件)。

NFT发行合约

csharp 复制代码
import {ERC721} from "@openzeppelin/contracts/token/ERC721/ERC721.sol";

contract BasicNft is ERC721 {
    error BasicNft__TokenUriNotFound();

    mapping(uint256 tokenId => string tokenUri) private s_tokenIdToUri;
    uint256 private s_tokenCounter;

    constructor() ERC721("Dogie", "DOG") {
        s_tokenCounter = 0;
    }

    function mintNft(string memory tokenUri) public {
        s_tokenIdToUri[s_tokenCounter] = tokenUri;
        _safeMint(msg.sender, s_tokenCounter);
        s_tokenCounter = s_tokenCounter + 1;
    }

    function tokenURI(uint256 tokenId) public view override returns (string memory) {
        if (ownerOf(tokenId) == address(0)) {
            revert BasicNft__TokenUriNotFound();
        }
        return s_tokenIdToUri[tokenId];
    }

    function getTokenCounter() public view returns (uint256) {
        return s_tokenCounter;
    }
}

AI写代码bash
1234567891011121314151617181920212223242526272829

接下来我们做逐行讲解

csharp 复制代码
    error BasicNft__TokenUriNotFound();

    mapping(uint256 tokenId => string tokenUri) private s_tokenIdToUri;
    uint256 private s_tokenCounter;

AI写代码bash
1234

上述代码定义了一个 自定义错误 BasicNft__TokenUriNotFound(),在没找到 tokenURI 时抛出。

s_tokenIdToUri:存储 tokenId → 元数据 URI(比如指向 IPFS 上的 JSON)。

s_tokenCounter:计数器,记录一共铸造了多少个 NFT,并作为 tokenId 使用。

javascript 复制代码
constructor() ERC721("Dogie", "DOG") {
    s_tokenCounter = 0;
}

AI写代码bash
123

上述代码做了下面这些事

  • 构造函数,初始化 NFT 的名字(Dogie)和符号(DOG)。
  • OpenZeppelin 的 ERC721 构造函数会处理名字和符号。
  • s_tokenCounter 初始化为 0,意思是目前还没有nft被初始化。
ini 复制代码
function mintNft(string memory tokenUri) public {
    s_tokenIdToUri[s_tokenCounter] = tokenUri;
    _safeMint(msg.sender, s_tokenCounter);
    s_tokenCounter = s_tokenCounter + 1;
}

AI写代码bash
12345
  • mintNft函数:用户调用它来铸造一个 NFT。
  • 把 tokenUri 存进映射,跟 tokenId 对应。
  • 调用 _safeMint(OpenZeppelin 提供的安全铸造函数),把 NFT 发给调用者(msg.sender)。
  • tokenId 用 s_tokenCounter,然后自增。

_safeMint(address to, uint256 tokenId) 功能详解:

  1. 只是把一个新的 NFT(tokenId)分配给 to 地址。
  2. 如果 to 是一个智能合约地址,就会调用它的 onERC721Received 函数。
  3. 如果这个合约没实现 onERC721Received,整个交易会 revert(回滚),避免 NFT 被"卡死"在一个不能处理 NFT 的合约里。
scss 复制代码
function tokenURI(uint256 tokenId) public view override returns (string memory) {
    if (ownerOf(tokenId) == address(0)) {
        revert BasicNft__TokenUriNotFound();
    }
    return s_tokenIdToUri[tokenId];
}

AI写代码bash
123456
  • tokenURI:返回某个 tokenId 的元数据 URI。
  • ownerOf(tokenId): 检查该 token 是否存在(如果是零地址表示没被 mint)。如果没找到,就报错。否则返回之前存储的 URI(比如 IPFS 链接)。
csharp 复制代码
function getTokenCounter() public view returns (uint256) {
    return s_tokenCounter;
}

AI写代码bash
123

返回当前的计数器,也就是总共 mint 了多少个 NFT。

验证

我们可以在remix部署上述合约,或者使用foundary部署合约,然后在etherscan中调用mintNft函数,传入一个标准的部署在ipfs上的json文件,例如:

bafybeig37ioir76s7mg5oobetncojcm3c3hxasyd4rvid4jqhy4gkaheg4.ipfs.dweb.link/?filename=1...

连接自己的钱包后执行并确认后,我们发现自己的钱包中出现了自己发行的NFT

测试合约地址:0xD3B0A4ECAA26cDEbab5810acb58E2BA5103E7fEc

引用

www.kraken.com/zh-cn/learn...

brave.com/zh/web3/wha...

blog.csdn.net/inthat/arti...

learnblockchain.cn/2018/12/12/...

github.com/Cyfrin/foun...

相关推荐
古城小栈15 小时前
Go实现的区块链 分片技术优化
golang·区块链·php
公链开发16 小时前
区块链赋能乡村振兴:重塑信任,激活乡土新价值
区块链
TechubNews16 小时前
Stripe 拟于本月 12 日上线稳定币支付功能
web3·区块链
兵bing17 小时前
区块链理解
区块链
公链开发18 小时前
开发一条公链大概得多少钱?
去中心化·区块链
小明的小名叫小明18 小时前
Solidity入门(6)-合约实战2
区块链
MicroTech202518 小时前
微算法科技(NASDAQ MLGO)采用分层实用拜占庭容错(H-PBFT)共识算法,提高区块链模型的共识效率、安全性和可扩展性
科技·区块链·共识算法
古城小栈18 小时前
Go语言原生智能合约开发与部署完全指南
golang·区块链·智能合约
区块链小八歌18 小时前
Pi Network Ventures首笔投资落地OpenMind,探索区块链+AI真实应用
区块链
YSGZJJ1 天前
股指期货交割日前后应当如何应对?
区块链