当前位置: 首页 > news >正文

区块链—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发行合约

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;}
}

接下来我们做逐行讲解

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

上述代码定义了一个 自定义错误 BasicNft__TokenUriNotFound(),在没找到 tokenURI 时抛出。
s_tokenIdToUri:存储 tokenId → 元数据 URI(比如指向 IPFS 上的 JSON)。
s_tokenCounter:计数器,记录一共铸造了多少个 NFT,并作为 tokenId 使用。

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

上述代码做了下面这些事

  • 构造函数,初始化 NFT 的名字(Dogie)和符号(DOG)。
  • OpenZeppelin 的 ERC721 构造函数会处理名字和符号。
  • s_tokenCounter 初始化为 0,意思是目前还没有nft被初始化。
function mintNft(string memory tokenUri) public {s_tokenIdToUri[s_tokenCounter] = tokenUri;_safeMint(msg.sender, s_tokenCounter);s_tokenCounter = s_tokenCounter + 1;
}
  • 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 的合约里。
function tokenURI(uint256 tokenId) public view override returns (string memory) {if (ownerOf(tokenId) == address(0)) {revert BasicNft__TokenUriNotFound();}return s_tokenIdToUri[tokenId];
}
  • tokenURI:返回某个 tokenId 的元数据 URI。
  • ownerOf(tokenId): 检查该 token 是否存在(如果是零地址表示没被 mint)。如果没找到,就报错。否则返回之前存储的 URI(比如 IPFS 链接)。
function getTokenCounter() public view returns (uint256) {return s_tokenCounter;
}

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

验证

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

https://bafybeig37ioir76s7mg5oobetncojcm3c3hxasyd4rvid4jqhy4gkaheg4.ipfs.dweb.link/?filename=1-PUG.json

连接自己的钱包后执行并确认后,我们发现自己的钱包中出现了自己发行的NFT
dog
测试合约地址:0xD3B0A4ECAA26cDEbab5810acb58E2BA5103E7fEc

引用

https://www.kraken.com/zh-cn/learn/what-are-non-fungible-tokens-nft

https://brave.com/zh/web3/what-are-nfts/

https://blog.csdn.net/inthat/article/details/106206591

https://learnblockchain.cn/2018/12/12/what-is-ipfs

https://github.com/Cyfrin/foundry-nft-cu


文章转载自:

http://zevK4w5o.spnky.cn
http://0Fhabv05.spnky.cn
http://ECIHofY7.spnky.cn
http://7UC50aKE.spnky.cn
http://KxvZwAkU.spnky.cn
http://VUuxQbFn.spnky.cn
http://eG17pBa6.spnky.cn
http://p2x4dsgs.spnky.cn
http://1X5u8NPT.spnky.cn
http://0pJzbxcv.spnky.cn
http://FvYvyczb.spnky.cn
http://nZ20mxAE.spnky.cn
http://WFdbatTX.spnky.cn
http://mW4EyjUR.spnky.cn
http://oySkfEc3.spnky.cn
http://DiNlyvXx.spnky.cn
http://PSS8dgGh.spnky.cn
http://Drltv0F3.spnky.cn
http://ZKpSvSpg.spnky.cn
http://f9BLCVEY.spnky.cn
http://Ag3XuX5v.spnky.cn
http://QfyYVyYE.spnky.cn
http://gKwPJ0kH.spnky.cn
http://SLrL8vLL.spnky.cn
http://Olj8f0MZ.spnky.cn
http://BMCh9oru.spnky.cn
http://OxtcaRYb.spnky.cn
http://zKbEheVk.spnky.cn
http://0102siqu.spnky.cn
http://FbfYpv5u.spnky.cn
http://www.dtcms.com/a/372384.html

相关文章:

  • JavaSSM框架-MyBatis 框架(一)
  • c6-类和对象-对象特征-初始化列表
  • ThermoSeek:热稳定蛋白数据库
  • 不同Autosar CAN版本的主要实现差异
  • Jakarta EE课程扩展阅读(二)
  • 算法模板(Java版)
  • 【多模态学习】QA2:Tokenize和Embedding?BPE算法?交叉熵损失函数?
  • ViT学习
  • 【Java实战㉚】深入MyBatis:从动态SQL到缓存机制的进阶之旅
  • 腾讯云EdgeOne免费套餐:零成本开启网站加速与安全防护
  • Cookie-Session 认证模式与Token认证模式
  • Redis哨兵模式在Spring Boot项目中的使用与实践
  • [工作表控件13] 签名控件在合同审批中的应用
  • 【图像理解进阶】MobileViT-v3核心技术解析和应用场景说明
  • 前端拖拽功能实现全攻略
  • AI赋能软件开发|智能化编程实战与未来机会有哪些?
  • 335章:使用Scrapy框架构建分布式爬虫
  • Docker|“ssh: connect to host xxx.xxx.xxx.xxx port 8000: Connection refused“问题解决
  • OneCode 可视化揭秘系列(三):AI MCP驱动的智能工作流逻辑编排
  • 数据结构深度解析:二叉树的基本原理
  • Supabase02-速通
  • LLM学习:大模型基础——视觉大模型以及autodl使用
  • 嵌入式Secure Boot安全启动详解
  • 【倍增】P3901 数列找不同|普及+
  • 数据结构:堆
  • 继续优化基于树状数组的cuda前缀和
  • 数组常见算法
  • 数仓建模理论
  • 致远A8V5 9.0授权文件
  • 【New Phytologist】​​单细胞多组学揭示根毛对盐胁迫的特异性响应文献分享