博客开发NFT功能

特别声明

本文档只限于技术交流学习,不涉及任何价值交易,所有内容都在测试环境中部署,不具有任何经济价值。

简介

NFT是一种非同质化代币,看到这个解释理解起来有点困难,通俗的说,NFT可以理解为一种不可以分割的物质,你可以理解为NFT具有原子性,不能再次进行分割(最小单位)。在网络上NFT通常与一张图片联系在一起,这是一种表现形式,你也可以使用一段视频来表示NFT。

本质

NFT 是一种 ERC721标准代币,在理解概念之前,我们先来了解ERC20代币,ERC20代币有以下特性:

  • name-代币名称,例如 Decentraland
  • symbol-代币标识符,可以理解为缩写:例如:mana
  • decimals 精度,我们可以理解为有几位小数,通常为 :18,那么我们可以理解为小数点后面可以精确到第18位,例如:0.000000000000000001
  • totalSupply 发行总量,例如:1000000000,发行10亿
  • ....(其它属性和方法不重要,有兴趣可以前往 EIP20提案进行了解)

上述属性中,decimals 是重点内容,我们可以将区块链理解为一个分布式的大账本,所有参与其中的节点(运行区块链提供服务的节点)都维护一份相同的账本,ERC20代币可以理解为一种积分标准,例如我们发行时间海绵博客积分,账本中将会记录以下内容:

  • 李雷 -> 2.5 积分
  • 韩梅梅 -> 5.5 积分
  • ....

ERC20表示的是某类数字余额的概念,这种余额有精度概念,可以将 1 分割成 0.8 + 0.2 进行转移使用。

ERC721则是另外一种概念,它表示的是一种不可分割的概念,它有以下特性:

  • name-代币名称,例如 CryptoPunks
  • symbol-代币标识符,可以理解为缩写:例如:punk
  • tokenId-uint256类型数字(32位的整数)
  • .....

ERC721没有decimals属性,增加了tokenId属性,因此不能表示余额的概念,但是可以表示你对某个事物的所有权,例如,使用TokenId属性与游戏中的某个道具进行绑定,那么TokenId就代表了特定物品,TokenId不会重复,我们要确保TokenId所对应的物品也不能重复。

小结

  • ERC20可以理解为余额的概念,可以进行拆封使用
  • ERC721可以理解为不可分割物品,每个TokenId对应的物品都是独一无二的,当然你可以按照自己的理解进行使用

博客NFT

回归正题,在博客系统中,将NFT中的TokenId与图片一一对应,我们将发行一万个NFT,每张图片各不相同(艺术细胞有限,我们参考CryptPunks图片进行开发),约定部署在 Rinkeby 环境(ETH的测试环境,主要是没钱,ETH太贵了)中,使用NFT需要开发两个功能:

  • NFT 合约(基于Soliditiy),记录谁拥有了该NFT
  • 后端使用web3j 连接 ETH Rinkeby 环境进行交易交互

NFT合约开发

目前有多种框架都可以实现快速开发Solidity合约,HardHatTruffleSuite是两个最热门的框架,提供了完整的开发环境,包括本地运行模拟链,开发、调试、编译、部署等功能,有兴趣的可以前往观看文档了解更多,Truffle发展的较早,接触的较多,在这里使用 Truffle框架进行开发,同时引入了OpenZeppelin Contracts 合约库简化开发

Truffle 工具的安装和使用不在此介绍,如果感兴趣可以在博客留言,看情况写介绍文档(truffle配合npm完全类似于前端项目开发)。

安装完成后使用 truffle init,初始化项目,同时使用引入依赖:@openzeppelin/contracts: ^4.5.0,编写NFT.sol合约:(这里使用了OpenZeppelin的合约库,因此不需要写很多代码)

/// 指定 Solidity开发版本
pragma solidity ^0.8.0;
 引入openzeppelin 依赖
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";

/// NFT合约,继承了 Ownable(权限控制),ERC721(实现了ERC721标准合约)
contract TimestampSpongeNFT is Ownable,ERC721 {
    /// 合约构造器
    constructor() ERC721("TimeStamp Sponge NFT","TSN") {}
    /// 批量发布TokenId
    function mintNFT(address to,uint256[] calldata tokenIds) external onlyOwner {
        for (uint256 i = 0; i < tokenIds.length; i++) {
            _mint(to,tokenIds[i]);
        }
    }
    // 发布单TokenId
    function mintNFT(address to,uint256 tokenId) external onlyOwner {
        _mint(to,tokenId);
    }
    /// 批量发布TokenId
    function mintNFT(address[] calldata tos,uint256[] calldata tokenIds) external onlyOwner {
        require(tos.length == tokenIds.length,"ILLEGAL_ARGUMENTS");
        for (uint256 i = 0; i < tokenIds.length; i++) {
            _mint(tos[i],tokenIds[i]);
        }
    }
}

部署脚本

在migrations/2_deploy.js中编写部署脚本:

///引入NFT合约
const TimestampSpongeNFT = artifacts.require('TimestampSpongeNFT');
module.exports = async (deployer,network) => {
   if (network == 'rinkeby') {
        /// 部署NFT
        await deployer.deploy(TimestampSpongeNFT);
    }
}

部署合约需要消耗Gas,因此需要指定账户信息,在truffle-config.js中配置账户,配置信息如下:


const HDWalletProvider = require('@truffle/hdwallet-provider');

module.exports = {
  networks: {
     配置
    rinkebyeth: {
      provider: () => new HDWalletProvider({
        /// 这里配置私钥信息
        privateKeys: ['xxxxxxxx'],/// 这里配置rpc地址
        providerOrUrl: 'https://rinkeby.infura.io/v3/{infura网站提供的projectId}'
      }),/// 网络id 代表 特定区块链id,这里的4代币 ETH 的测试网络 Rinkeby 区块链
      network_id: 4,gasPrice: 20000000000,gas: 9000000,confirmations: 1,networkCheckTimeout: 20000,timeoutBlocks: 200,skipDryRun: true
    }
  },// Set default mocha options here,use special reporters etc.
  mocha: {
    timeout: 100000,useColors: true
  },// Configure your compilers
  compilers: {
    solc: {
      version: "0.8.11",settings: {
       optimizer: {
         enabled: true,runs: 200
       },}
    }
  },plugins: [
    'truffle-contract-size','truffle-plugin-verify'
  ],/// Etherscan 区块浏览器账号,用于 合约代码验证
  api_keys: {
    etherscan: 'MY_API_KEY',bscscan: 'MY_API_KEY',snowtrace: 'MY_API_KEY',polygonscan: 'MY_API_KEY',ftmscan: 'MY_API_KEY',hecoinfo: 'MY_API_KEY',moonscan: 'MY_API_KEY'
  },};

编译合约

使用npx truffle compile对合约进行编译,日志信息如下:

blog.hzchendou.com:nft 时间博客$ npx truffle compile

Compiling your contracts...
===========================
> Compiling ./contracts/NFT.sol
> Compiling @openzeppelin/contracts/access/Ownable.sol
> Compiling @openzeppelin/contracts/token/ERC721/ERC721.sol
> Compiling @openzeppelin/contracts/token/ERC721/IERC721.sol
> Compiling @openzeppelin/contracts/token/ERC721/IERC721Receiver.sol
> Compiling @openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol
> Compiling @openzeppelin/contracts/utils/Address.sol
> Compiling @openzeppelin/contracts/utils/Context.sol
> Compiling @openzeppelin/contracts/utils/Strings.sol
> Compiling @openzeppelin/contracts/utils/introspection/ERC165.sol
> Compiling @openzeppelin/contracts/utils/introspection/IERC165.sol
> Artifacts written to /repo/时间博客/nft/build/contracts
> Compiled successfully using:
   - solc: 0.8.11+commit.d7f03943.Emscripten.clang

部署合约

部署合约之前需要确保你的账户余额不少于0.003 ETH,你可以在Rinkeby水龙头网站领取免费 ETH 地址 (不一定能领取成功,我就被坑了好多次,提交之后没有任何转账信息)

使用npx truffle migrate --network rinkeby可以将编译完成的合约部署到Rinkeby网络中,很遗憾的是我这里一直提示网络问题,因此只能使用另外一种方式进行部署(部署方式有很多种,本质上都是将编译后的代码提交到区块网络中,发起转账交易。创建合约比较特殊,接受地址为空),我们采用MetaMask来完成部署交易,使用发送交易方法:

let params = [{
  /// 部署合约的账户
  "from": "0xxxxxxxxxxxxxxxxxxxxxx",/// 在 build/contracts/TimestampSpongeNFT.json文件中的 bytecode 属性
  "data": "xxxxxx"
}]

ethereum.request({
  /// 发送交易请求
  method: 'eth_sendTransaction',params: params,/// 部署合约的账户
  from: '0xxxxxxxxxxxxxxxxxxxxxx',})
.then(function (result) {
  console.log('result',result)
})
.catch(function (reason) {
 console.log('reason',reason)
})

合约部署完成:交易信息

部署完成后需要进行验证才能在浏览器中查看到源码信息,在 Truffle 中引入 truffle-plugin-verify 依赖,使用 命令 npx truffle run verify TimestampSpongeNFT@0xxxxxxxxxxxxxx --network rinkeby进行验证,完成后就可以在浏览器中看到合约源码,本合约地址

后端开发Web3

Web3j是一个RPC客户端,实现了ETH客户端提供的API方法,可以进行远程调用,不建议自行搭建ETH客户端,比较耗费资源。infura网站提供ETH网络服务,有一定的免费额度(注意网络环境,本项目使用测试网络Rinkeby),可以满足个人用户开发使用。在项目中引入依赖:

<dependency>
   <groupId>org.web3j</groupId>
   <artifactId>core</artifactId>
   <version>4.8.7</version>
</dependency>

本项目使用4.8.7版本,支持EIP-1559(优化交易费用提案),注意`com.squareup.okhttp3`的使用版本,如果报错建议使用okhttps:4.9.0,转账核心方法如下:

public String sendMintTransaction(String address,Long tokenId) throws IOException {
        /// 获取账号已经发起的交易数量,这个用于指定这是账号的哪一笔交易,依据nonce可以实现交易信息替换
        BigInteger nonce = getNonce();
        /// 创建交易信息,address 是获得 NFT 的ETH账户地址,contractAddress是合约地址
        RawTransaction transaction = createMintNFTTransaction(address,contractAddress,tokenId,nonce); 
        ///进行交易信息签名
        byte[] transactionBytes = TransactionEncoder.signMessage(transaction,credentials);
        String hexValue = Numeric.toHexString(transactionBytes);
         发送交易信息
        EthSendTransaction ethSendTransaction =
                web3j.ethSendRawTransaction(hexValue).send();
        /// 交易Hash,可以根据Hash在浏览器中查看交易信息
        String transactionHash = ethSendTransaction.getTransactionHash();
        return transactionHash;
}
private static RawTransaction createMintNFTTransaction(String to,String contractAddress,Long tokenId,BigInteger nonce) {
        /// 对调用函数信息进行编码
        org.web3j.abi.datatypes.Function function = new org.web3j.abi.datatypes.Function(
                FUNC_mintNFT,Arrays.<Type>asList(new org.web3j.abi.datatypes.Address(to),new org.web3j.abi.datatypes.generated.Uint256(BigInteger.valueOf(tokenId))),Collections.<TypeReference<?>>emptyList());
        DefaultFunctionEncoder encoder = new DefaultFunctionEncoder();
        String data = encoder.encodeFunction(function);
        /// 区块链id,4代表的是Rinkeby测试链
        long chainId = 4L;
        /// 这里是手动设置gas使用上限,稳妥的方式是依据调用函数去查看Gas使用上限
        BigInteger gasLimit = BigInteger.valueOf(106230L);
         转账金额,这里是NFT转账,不需要转账ETH,设置为 0 
        BigInteger value = BigInteger.ZERO;
         /// maxPriorityFeePerGas ,这个是给矿工的小费,我们设置为 1GETH,稳妥的方式是依据最近100个交易计算
        /// maxFeePerGas 这个是最大 Gas价格(矿工小费 + 基础费用,基础费用是算法计算的),/// maxFeePerGas - maxPriorityFeePerGas - BaseGas 剩余的费用将会进行退还(不需要深入研究,了解即可)
        return RawTransaction.createTransaction(chainId,nonce,gasLimit,value,data,maxPriorityFeePerGas,maxFeePerGas);
    }

至此完成功能开发,前端界面的开发就不介绍了,这里没有使用MetaMask钱包功能。

博客NFT

博客提供了10000个NFT,地址:地址,功能分为两部分:

  • 在网站获取 NFT
  • 将网站 NFT 转账到 自己 ETH账户中

领取NFT

点击领取按钮获取NFT(所有的NFT都是代码自动生成确保独一无二,领取需要登录,微信扫码进行登录),然后就可以在我的NFT中查看领取到的NFT信息:

链上转账

完成领取后,并没有在区块链上生成任何转账信息,你需要在点击链上转账按钮,在弹出框里填写你的ETH地址信息,后台会将你领取的NFT转账到你的ETH账户,完成后你就可以在脸上查看到转账信息,嘿嘿,我已经完成我的NFT领取啦,你也快来试试吧,先到先得噢,转账信息: 交易信息

总结

  • ERC721 代币与头像对应
  • 基于 Rinkeby 环境开发
  • Rinkeby 水龙头:地址
  • Rinkeby浏览器:地址
  • NFT合约源码具有特殊性,如有需要进群领取,QQ群:901856121

参考文档

联系方式

技术更新换代速度很快,我们无法在有限时间掌握全部知识,但我们可以在他人的基础上进行快速学习,学习也是枯燥无味的,加入我们学习牛人经验:

点击:加群讨论

原文地址:https://blog.csdn.net/pactoer/article/details/125050932

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


文章浏览阅读903次。文章主要介绍了收益聚合器Beefy协议在币安智能链测试网网上的编译测试部署流程,以Pancake上的USDC-BUSD最新Curve版流动池的农场质押为例,详细介绍了完整的操作流程。_怎么在bsc网络上部署应用
文章浏览阅读952次。比特币的主要思路是,构建一个无中心、去信任的分布式记账系统。交易签名只能保证交易不是他人伪造的,却不能阻止交易的发起者自己进行多重交易,即交易的发起者将一个比特币同时转账给两个人,也就是所谓的双花。比特币应用的区块链场景也叫做公链,因为这个区块链对所有人都是公开的。除此之外,还有一种区块链应用场景,被称作联盟链。区块链的出现,使得低成本,去信任的跨组织合作成为可能,将重构组织间的关系,这个关系既包括企业间的关系,也包括政府和企业间的关系,还有政府部门间的关系。
文章浏览阅读2.5k次。虚拟人从最初的不温不火,到现在步入“出生高峰期”,元宇宙可以说是功不可没。此前,量子位发布了《虚拟数字人深度产业报告》,报告显示,到2030年我国虚拟数字人整体市场规模将达到2700亿元。其中,“身份型虚拟人”市场规模预计达到1750亿元,占主导地位,而“服务型虚拟人”总规模也将超过950亿元。得益于AI、VR/AR 等技术的发展,虚拟人的应用场景正在从传统的虚拟偶像等娱乐行业迈向更多元化的领域。_最喜欢的虚拟角色
文章浏览阅读1.3k次,点赞25次,收藏13次。通过调查和分析用户需求、兴趣和行为,你可以更好地定位你的目标受众,并在市场中找到你的定位。在设计你的Web3.0项目时,注重用户界面的友好性、交互流畅性和功能的创新性,以提供独特的用户体验。通过与有影响力的人或组织进行合作,推广你的Web3.0项目。通过与他们分享你的项目并抓住他们的推荐,可以迅速获得更多的关注度。通过优化你的网站和内容,将有助于提高你的排名,并增加有机流量。通过提供奖励激励计划,如空投、奖励机制等,激励用户参与你的Web3.0项目。的人或组织合作,可以增加你的项目的曝光度。
文章浏览阅读1.7k次。这个智能合约安全系列提供了一个广泛的列表,列出了在 Solidity 智能合约中容易反复出现的问题和漏洞。Solidity 中的安全问题可以归结为智能合约的行为方式不符合它们的意图。我们不可能对所有可能出错的事情做一个全面的列表。然而,正如传统的软件工程有常见的漏洞主题,如 SQL 注入、缓冲区超限和跨网站脚本,智能合约中也有反复出现的。_solidity安全漏洞
文章浏览阅读1.3k次。本文描述了比特币核心的编译与交互方法_编译比特币
文章浏览阅读884次。四水归堂,是中国建筑艺术中的一种独特形式。这种形式下,由四面房屋围出一个天井,房屋内侧坡向天井内倾斜,下雨时雨水会从东西南北四方流入天井,从而起到收集水源,防涝护屋的作用,寓意水聚天心,天人合一。在科技产业当中,很多时候我们需要学习古人的智慧与意蕴,尝试打通各个生态,聚四方之力为我所用,这样才能为最终用户带来最大化价值。随着数字化、智能化的发展,算力成为生产力的根基。在这一大背景下,算力需要贯通软..._超聚变csdn
文章浏览阅读1k次,点赞24次,收藏19次。云计算和区块链是当代科技领域两个备受关注的核心技术。本文将深入探讨云计算和区块链的发展历程,详细剖析其起初阶段的奠基、面临的问题、业务内容、当前研究方向、用到的技术、实际应用场景、未来发展趋势,并提供相关链接供读者深入了解。
文章浏览阅读1.5k次。融入对等网络的奥妙,了解集中式、全分布式和混合式对等网络的差异,以及区块链网络的结构与协议,让你跃入区块链的连结网络。揭开密码学的神秘面纱,探寻对称密码学、非对称密码学、哈希函数、数字签名等关键技术,让你了解信息安全的核心。解码共识算法的精髓,从理论到实践,从PoW、PoS到PBFT,让你深入了解区块链如何达成共识。探索智能合约的世界,从定义到生命周期,从执行引擎到开发与部署,带你进入无限可能的合约领域。了解令人惊叹的区块链世界,从概念到价值,从发展历程到政策法规,一篇章串联出区块链的精髓。
文章浏览阅读777次。8 月份,加密货币市场经历了明显的波动,比特币价格波动幅度较大。与此同时,NFT 市场出现大幅下跌,引发了人们对这一新兴行业未来发展趋势的担忧
文章浏览阅读8.8k次,点赞53次,收藏37次。近二十年来,我国信息科技发展日益成熟,出现的网络完全问题也是“百花齐放”。而元宇宙作为5G技术、AR/VR技术、云计算以及区块链等技术的组合体,其安全性指定会被人们所广泛关注。根据前面所讲,元宇宙融合了虚拟世界和现实世界,通过数据将现实世界的各种元素映射到数字化的虚拟世界中。所以没有数据,就等于没有元宇宙的一切;没有信息安全,元宇宙的社会生产、生活就不能正常有序地进行。所以足以可见数据安全、信息安全对元宇宙发展起到的重要作用!!_元宇宙 安全计算
文章浏览阅读1.4k次。最早使用历史 1991年采用 时间戳 追溯 数字文档,之后 2009年后创始人**中本聪** (satoshi nakamoto )日裔美国人,在设计比特币数字货币中将此理念写入应用程序中_web3.0学习
文章浏览阅读1.7k次。DeFi收益来源全面概述_drfi收益
文章浏览阅读941次,点赞17次,收藏21次。号外:教链内参1.28《从BTC现货ETF的近期数据看到的》隔夜BTC经历现货ETF通过后的情绪冷静,一度破位40k后又逐渐修复至42k上方。请珍惜42k的BTC吧。也许到下个周期,我们将不再有机会见到这个高度的BTC了。下面,让我们重温,42k的BTC,在过去四年穿越牛熊的过程中,带给我们的启迪吧。需要提醒的是,历史文字,自有历史局限性,回顾,也须带着批判性的目光阅读和审视。2021年2月8日,...
文章浏览阅读1.2k次,点赞23次,收藏21次。其实一开始我也是这么想的,但根据PoW算法机制,如果你的计算量不够大,是无法控制区块链的走向的,也就是说,即使你投入了大量的成本用于完成任务,也不能保证自己成功。例如,你持有100个币,总共持有了30天,那么,此时你的币龄就为3000,这个时候,如果你发现了一个PoS区块,那么你的币龄就会被减去一定的值,每减少365个币龄,将会从区块中获得0.05个币的利息(可理解为年利率5%),那么在这个案例中,利息=3000×5%/365=0.41个币。前面说过,谁的算力强,谁最先解决问题的概率就越大。
文章浏览阅读1.9k次。这里主要实现的部分继续下去,对 Blockchain 这个对象有一些修改,如果使用 TS 的话可能要修改对应的 interface,但是如果是 JS 的话就无所谓了。需要安装的依赖有:express现在的 express 已经不内置 body-parser,需要作为单独的依赖下载request不下载会报错,是使用 request-promise 所需要的依赖和已经 deprecated 了,具体 reference 可以参考。_js区块链
文章浏览阅读1k次,点赞19次,收藏19次。作者:Zach Pandl Grayscale编译:象牙山首席村民 碳链价值以太坊在2023年取得了丰厚的回报。但表现不如比特币以及其他一些智能合约公链代币。我们认为,这反映了今年比特币特有的积极因素以及以太坊链上活动的缓慢复苏。尽管以太坊的涨幅低于比特币,但从绝对值和风险调整值来看,今年以太坊的表现优于传统资产类别。以太坊不断增长的L2生态系统的发展可能会吸引新用户,并在2024年支撑以太币的...
文章浏览阅读908次,点赞20次,收藏20次。通证是以数字形式存在,代表的是一种权利、一种固有和内在的价值。徐教授告诉我:多年的职业经历,多年的为易货贸易的思考,认识到在处理贸易和经济领域的关系时,应以提高人民生活水平、保证社会成员充分就业、保证就业成员实际收入和有效需求的大幅稳定增长、实现世界资源的充分利用以及扩大货物的生产和交换为目的,期望通过达成互惠互利安排,实行公开、公平、公正的“三公原则”,开展国家与国家、企业与企业之间的易货贸易,规避因信用问题引起的各类风险,消除国际贸易中的歧视待遇,促进全球国家的经济发展,从而为实现上述目标做出贡献。
文章浏览阅读2.5k次。由于webase文档原因,查找起来比较局限,有时候想找一个api却又忘了在哪个模块的目录下,需要一步一步单独点,而利用文档自带的检索功能又因为查找文档全部信息,显得十分缓慢,所以整理了有关WeBASE的api列表但不可否认,现在只有列表,没有对应的页面跳转,文章目的也只是为了多了解webase的接口_webase私钥管理里获取
文章浏览阅读1.4k次,点赞28次,收藏21次。基于​openzeppelin来构建我们的NFT,并用一个例子来手把手的说明如何在opensea快速发布自己的NFT智能合约(ERC721)。