【源码解读】你买的NFT到底是什么?

这篇具有很好参考价值的文章主要介绍了【源码解读】你买的NFT到底是什么?。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前菜

内容概要

如果你是WEB3加密界的新手,面对众多概念无从入手,那么欢迎你,来对地方了!!本文围绕标准 ERC721协议,描述了Mint、 safeMint、 transfer等是如何实现资产管理的,并通过解读代码来了解它的安全性设计和以太坊数据上链成本构成。

目录大纲

  1. ​所谓NFT资产是什么?

  2. Mint和safeMint的差别

  3. 交易时会发生什么?有哪些细节设计

  4. NFT哪些数据也存储在链上?

  5. 以太坊上存储有多贵?

面向对象

  • Web3新手,有无技术背景均可:

    • 研发——可无障碍阅读,理解精美的合约设计

    • 非研发——可能读不懂列举的代码,但能体会标准协议的设计思路


正文

1.所谓NFT资产是什么?

在opensea上,可看到每个NFT都有个唯一的编号。比如azuki系列中第4132号,在页面的Details栏目可以看到其合约地址,ID编号,部署所在公链等信息,而Properties栏目则是其设定的具备各种属性,对应的稀有度(非azuki本身携带,而是opensea整合计算的)。

erc721: transfer to non erc721receiver implementer,合约分析,web3,区块链

1.1 资产在标准ERC721协议里是什么?

而咱们回顾到源代码(此处取ERC721标准库openzepplin代码),会发现程序记录了全局性的两个字典类型的变量,通过 _owners中用数字映射地址的方式记录每一个ID 当前对应的所有者,同时也附带用_balances 记录了当前所有者总计持有的NFT数量

mapping(uint256 => address) private _owners;
mapping(address => uint256) private _balances;

并且由于ERC721创新性的赋予了一个ID对应地址的变量 _owners,从而与ERC20仅_balances 进行地址与余额的管理,区分出了FT(同质化)与NFT(非同质化)的差别。

2.Mint和safeMint的差别

2.1 Mint是如何进行的

Mint 

意思为铸造,即每个NFT的创造过程,例如之前的

爱死机NFT十四君,公众号:十四君 当奈飞的NFT忘记了web2的业务安全

Mint获取到该NFT的资产证明。从源代码中可以看到,Mint 主要是进行了安全判断:

  • 判断1:确保转入的不是0x00地址(黑洞地址无法转出,转入则资产损失)

  • 判断2:确保此交易所操作的NFTID是不存在的

最终代码执行的操作是:

  • 操作1:将转入地址的_balances所持有总数加1

  • 操作2:将对应 NFTID的所有者修改为转入的地址

  • 操作3:完成交易则发出emit事件,可以让链下监听到这次交易的数据

    /**
     * @dev Mints `tokenId` and transfers it to `to`.
     * Emits a {Transfer} event.
     */
    function _mint(address to, uint256 tokenId) internal virtual {
        require(to != address(0), "ERC721: mint to the zero address");
        require(!_exists(tokenId), "ERC721: token already minted");
        _beforeTokenTransfer(address(0), to, tokenId);
        _balances[to] += 1;
        _owners[tokenId] = to;
        emit Transfer(address(0), to, tokenId);
        _afterTokenTransfer(address(0), to, tokenId);
    }

中间有 _beforeTokenTransfer 和  _afterTokenTransfer属于虚函数,作为标准,是让项目方可以在不修改标准协议的情况下增加一些特定的逻辑代码用的。

2.2 为何safeMint更安全

safeMint意为安全的铸造,从代码实现中可以看到他本身也是调用了Mint但是他额外增加了 _checkOnERC721Received 的判断,这点是属于 ERC165 的标准,相当于在完成转入操作后,则判断对方地址,是否是黑洞地址(即无法发起交易NFT操作的地址)是防止转入对象为合约地址时候,其合约没有预设置好转出的函数,导致资产在内无法被转走,从而造成永久损失:

/**
 * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is
 * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.
 */
function _safeMint(address to,uint256 tokenId,bytes memory _data) 
    internal virtual {
    _mint(to, tokenId);
    require(
        _checkOnERC721Received(address(0), to, tokenId, _data),
        "ERC721: transfer to non ERC721Receiver implementer"
    );
}

2.3 ERC165 是如何防止资产转入黑洞的?

设计初衷可见: https://eips.ethereum.org/EIPS/eip-165

是让合约接口标准化的提案,在编程语法中interface 是接口的意思,在其中定义的函数可以不实现仅仅放上函数名字相关参数,在程序复杂的时候,相当于目录一般告诉别人我都有什么功能。但是接口的写法各有千秋,名字定义参数类型,甚至是否存在都有不同,所以此提案最终形成了ERC165标准,规范了接口的识别规则:

interface ERC165 {
    /// @notice 查询合约所实现的接口
    /// @param interfaceID  参数:接口ID
    /// @return true 如果函数实现了 interfaceID (interfaceID 不为 0xffffffff )返回true, 否则为 false
    function supportsInterface(bytes4 interfaceID) external view returns (bool);
}

使用流程是:

STEP 1  判断是否存在 supportsInterface 函数,并且其符合165标准STEP 2  通过 supportsInterface 函数,判断是否具有转出NFT的函数(PS:让合约具备NFT接收转出功能,可通过引入 IERC721Receiver.sol拓展包来实现)

3.交易时会发生什么?有哪些细节?

标准协议设计有两种转移方式,transfer和 transferFrom,作用于两种场景:

  • transfer转移:由用户调用,将本消息发送的钱包所持有的NFTID转移到指定地址

  • transferFrom从转移:用某机构调用,需要用户先授权某地址,让其有权可转移

类比一下:

  • transfer 就是现金交易,从自己口袋里拿钱支付
  • transferFrom就是扫码扣款,由店家申请扣款,受制于用户是否开通小额代扣权限

接下来咱们从代码来看看,其中可能有会意想不到的细节。

3.1 transfer是如何进行的

他会检测当前交易的 from 方是否是此NFTID的持有者,并且限制该NFT转入0x00地址。其次进行 from 转出地址和 to 转入地址的余额刷新,修改 _balances全局变量并且重新设置_owners此NFTID的所有者地址修改为to。

这里有个防护的细节会先执行 _approve(address(0), tokenId);清空历史授权,如果没有这一步,则资产完成了转移,但是其NFTID的转移授权依旧在,细思极恐:

function _transfer(address from,address to,uint256 tokenId) internal virtual {
        require(ERC721.ownerOf(tokenId) == from, "ERC721: transfer from incorrect owner");
        require(to != address(0), "ERC721: transfer to the zero address");
        _beforeTokenTransfer(from, to, tokenId);
        _approve(address(0), tokenId);// Clear approvals from the previous owner
        _balances[from] -= 1;
        _balances[to] += 1;
        _owners[tokenId] = to;
        emit Transfer(from, to, tokenId);
        _afterTokenTransfer(from, to, tokenId);
    }

3.2 transferFrom是如何进行的

这里的交易本质调用的是_safeTransfer所以他的核心逻辑是require部分,这的一大细节是:_msgSender()这是openzepplin 的标准库Context.sol中的方法。其实就是获取当前交易的发送者地址,但这里使用了封装版本,而不是直接使用msg.sender 是考虑到,可能存在一种交易类型

“元交易”,即交易的付费gas方和交易发起方不相同的情况。所以一些处于中间环节的,类似library的合约需要考虑这种特殊情况。其余部分判断是确定是否有授权记录,易于理解,不作赘述:

function safeTransferFrom(address from,address to,uint256 tokenId,bytes memory _data) public virtual override {      require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: transfer caller is not owner nor approved");      _safeTransfer(from, to, tokenId, _data);}

4.NFT哪些数据也存储在链上?

交易的环节也看完后,其实很多新同学也顿感奇怪,原来我买的NFT只有一个ID的归属地址指向了我,从而达成了唯一性。那就算如此,稀有度信息放在哪里?我的NFT图像本身在哪里?这就是涉及到ERC721的元数据拓展IERC721Metadata.sol。要放什么都可以,但是项目方往往在链上只存储最基础的ID+IPFS的地址。咱们可以通过之前Etherscan教程方法来看看一些项目数据有什么,

先取Azuki上合约地址:0xed5af388653567af2f388e6224dc7c4b3241c544再通过Read Contract 可以查阅到,其元数据只存放了ipfs上的指向地址。而近期兴起的Metaverse项目元宇宙土地SandboxDecentraland,以及去年火热的Axie Infinity,基本链上存储元数据也只是ID+网

erc721: transfer to non erc721receiver implementer,合约分析,web3,区块链

像mirror那些是专门设计低费用可进行高存储,一个块常规都是30M起步,大约是以太坊的1000倍。

5.以太坊上存储有多贵?

以下是本文稍难理解的地方。咱们从源码来分析链上存储的成本构成以及金额换算,成本产生将有2个方面,按执行流程来看:

  • 用户发起一笔交易,将数据作为参数传入,其大小是一笔成本
  • 交易执行合约代码,依据修改和使用,EVM计算消耗的gas成本

5.1 交易发起的成本

咱们可以核对下以太坊黄皮书,里对交易数据大小所消耗gas有清晰的定义

erc721: transfer to non erc721receiver implementer,合约分析,web3,区块链

可以看到交易所附带的参数的价格:

  • 每笔交易都有21000 GAS需要支付

  • 为交易的每个非零字节数据或代码支付68 GAS

  • 为交易的每个零字节数据或代码支付4 GAS

所以如果是再 Mint的时候,登记上若干NFT属性信息,交易的data部分会将abc等字符转成2个十六进制表示,而每个字符为一个八位二进制,等于一个byte。所以可以约等于将data的长度除以2作为byte数。而1kb的数据,如果都是非0的有信息量的文本信息,则等于增加是68*1000=6.8W 的gas消耗。按20gwei的gas价格和2000的eth兑换美元价格,可以估算出,每上链1kb数据在交易发起端就要:20*(21000+68000)*1e9/1e18 * 2000 =3.5美金

5.2合约存储的成本

由于交易发起后,还有智能合约上存储的逻辑,咱们从以太坊go源代码中(

EIP1283),来分析具体的消费量,代码具体在函数内,太长了不全粘来:

func gasSStore(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error)

历史上GAS消耗的估算有经过若干迭代,如果是Petersburg或者 Constantinople 未激活的话,则不按下面逻辑进行计算gas消耗计算,依赖3个种数据的管理形式(增删改)

  • 从零值地址到非零值(NEW VALUE),每个存储槽需消耗2Wgas
  • 从非零值地址到零值地址(DELETE),每个存储槽需消耗5Kgas,但会有奖励1.5W gas退回
  • 从非零到非零(CHANGE),每个存储槽需消耗 200 gas

注意,上述每一个存储槽算32byte,1kb存储则是32个存储槽。

Mint的过程是新增存储,所以如果新增1kb的数据存储在链上代价将是64Wgas,换算成金额则是:20*(640000)*1e9/1e18 * 2000 =25美金真可谓寸土寸金!


写在最后:

前文回顾

EIP-5058 能否防止NFT项目方提桶跑路?

当我们在看Etherscan的时候,到底在看什么?

当奈飞的NFT忘记了web2的业务安全

欢迎各位同学从后台提交有趣的合约或交易哈希。

关注十四,用技术的眼光发现价值。

看到这里,帅气的你不点个赞吗?文章来源地址https://www.toymoban.com/news/detail-745234.html

到了这里,关于【源码解读】你买的NFT到底是什么?的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 探索 ERC721A:下一代NFT智能合约标准

    项目地址:https://gitcode.com/chiru-labs/ERC721A 在区块链世界中,非同质化代币(NFT)已经成为了一种创新的艺术形式和数字资产所有权的代表。随着市场的发展,对于更高效、更安全的NFT发行协议的需求日益增长。这就是我们今天要介绍的 ERC721A 出现的原因。这是一个针对以太坊网

    2024年03月27日
    浏览(54)
  • 以太坊区块链ERC-721协议的实现(NFT代币标准)

    ERC-721是以太坊区块链上用于NFT(非同质化代币)的一个标准,是一种其他开发人员都遵守的模板或者格式,用于创建代表数字资产的独特代币,并且每个ERC-721代币都是独一无二的。使用统一的标准可以使合约代码变得更简单,复用性更强。ERC-721的出现促进了NFT的创建,并在

    2024年02月04日
    浏览(55)
  • conflux开发NFT智能合约(ERC721 & 工厂合约 & 可升级合约)

    以下场景可借鉴本文内容 需要创建很多合约 需要使用conflux代付机制(只需将工厂合约设置为代付,即可无限创建新合约) 合约想要有可升级的能力(如:特殊玩法 or 代码有bug) ERC-721 NFT 基于以上场景,需要三个主要合约实现 工厂合约 代理合约 逻辑合约 想要完全掌握本文

    2024年01月17日
    浏览(50)
  • 【ERC-721与ERC-1155有什么区别?】

    无论您是加密爱好者还是第一次使用密码,您都可能听说过以太坊。它是最具影响力的开源区块链平台之一,用于创建智能合约、加密货币和去中心化应用程序。以太坊的智能合约改变了加密货币的世界,区块链技术现在渴望成为全球多个行业的标准。 大多数区块链发烧友已

    2024年02月01日
    浏览(48)
  • 第8节 了解你买的票吗——股东构成

    在股票交易中,了解公司股东构成的 目的 在于: 判断个股是否存在大资金建仓,以进行买进或卖出的操作; 判断个股是否存在大资金大幅度拉升或减仓,以预测个股走势; 判断个股是否有大资金在维护股价,以减少操作风险。 获取所有高管持股数据,也可以根据参数进行

    2024年02月10日
    浏览(36)
  • 通俗解释什么是NFT,NFT到底是什么

    一、快速了解 NFT,可以简单类比 房产证 ,把房子换成图片、视频、声音等各种数字资产,纸质证书换成去中心化的数字认证,就变成NFT了。 拥有一个NFT就代表拥有“对应某个数字资产所有权”的证书。 最早的NFT养猫游戏 CryPtoKitties 二、扩展知识 1. 详细解释 NFT全称Non-Fung

    2024年02月03日
    浏览(42)
  • ERC721和加密收藏品(ERC721 & Crypto-Collectibles)

    唷!这里的气氛开始升温了…… 在这节课中,我们将更深入一些。 我们将讨论代币、ERC721标准和加密可收集资产。 换句话说,我们要做的是让你可以和朋友交换僵尸。 我们来谈谈代币。 如果你在以太坊领域呆过一段时间,你可能听过人们谈论代币——特别是 ERC20代币 。 以

    2024年03月11日
    浏览(43)
  • ERC20 | ERC-20/ERC-721/ERC-1155/ERC-3525 区别

    EIP 20 的地址:https://eips.ethereum.org/EIPS/eip-20 ERC 是 Ethereum Request for Comment 的缩写,也就是以太坊改进建议。提交 ERC 后,以太坊社区会对这个草案进行评估,最终会接受或者拒绝该建议。如果接受的话,ERC 会被确认为 EIP。 EIP 是 Ethereum Improvement Proposals 的缩写,也就是被接纳的

    2024年02月05日
    浏览(41)
  • Eth Of Erc20 And Erc721

    public,可以修饰变量和函数, 被修饰的函数或变量可以被任何合约调用(或访问),默认的变量和函数使用该属性。 private,可以修饰变量和函数,被修饰者只能被当前合约内部的代码所调用(或访问),不能被外部合约调用或继承它的子合约调用(或访问)。 extermal,只能修饰函数

    2024年02月15日
    浏览(44)
  • OpenZeppelin——ERC721

    ERC721是一个代币标准,ERC721官方简要解释是Non-Fungible Tokens,简写为NFT,多翻译为非同质化代币。 那怎么理解 非同质化 代币呢? 非同质化代表独一无二,以卡牌游戏为例,盲盒开出的英雄属性是随机生成,尽管职业相同,但每个英雄不一样,一个英雄对应一个TokenId,就是一个

    2024年02月22日
    浏览(54)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包