一个NFT可以在存在owner授权的operator的情况下,由owner转账给其他账户地址吗?

  • 本篇文章将对ERC-1155标准规范进行简单介绍,在介绍之前我们先来看一下之前的ERC-20、ERC-721、ERC-777都解决了什么问题,主要应用与那些场景...

  • 在经典的ERC-20场景中,如果用户想要授权给第三方账户或者智能合约进行转账操作,那么需要通过两个事务来完成整个转账的操作,在这里需要注意的是在授权是需要指定对...

  • 在经典的ERC-20场景中,如果用户想要授权给第三方账户或者智能合约进行转账操作,那么需要通过两个事务来完成整个转账的操作,在这里需要注意的是在授权是需要指定对...

  • ERC-20为以太坊智能合约提供了一套编写规范,而IERC-20则规定了一个Token需要实现的基本接口,本篇文章将对此进行解读。

  • OpenTracing(http://opentracing.io/)是分布式跟踪系统,当我们把系统拆成服务化,分布式系统的时候,查询一个问题,很可能需要多个登...

  • 数据挖掘标准规范之CRISP-DM基础

      每每提到数据挖掘,总有些人上来就是ETL、是算法、是数学模型,作为搞工程实施的我而言,很是头疼。其实作为数据挖掘的而言,算法只是其实现手段、是工具和实现手段...

  • 软件定义边界(SDP)标准规范2.0报告(文末附下载)

    作者:云安全联盟大中华区 内容摘要 软件定义边界(SDP)架构提供了动态灵活的网络安全边界部署能力,以在不安全网络上对应用和服务进行隔离。SDP 提供了隔离的、...

  • W3C标准及规范_地脚螺栓标准规范

    1.概念:W3C标准 中文名:万维网联盟,外文名:World Wide Web Consortium 万维网联盟标准不是某一个标准,而是一些列标准的集合。 ...

  • 第二十课 【ERC1155实践】欧阳询书法复制品从确权设计到买卖测试

    【本文目标】 通过本文学习,了解以太坊ERC1155标准规范和ERC1155Mintable可增发智能合约函数功能,并通过一个有趣的故事完成功能测试。

  • NFT不同协议标准NFT不同协议标准

    ERC 是「Ethereum Request for Comments」的缩写,意思是以太坊开发者公开征求意见,希望定义出统一的沟通接口,建立出一套可以遵循的标...

  • 【ERC1155实践】区块链游戏的平行宇宙和为此而生的Enjin钱包

    恩金(Enjin)花了大半年的时间一直在完善ERC-1155这个通证协议,毫不夸张地说,该标准是现有以太坊上最适用于游戏资产的通证标准,将主流游戏中道具涉及到的...

  • 数据仓库专题22-网络用户行为数据采集标准规范设计

       网络用户行为数据采集的趋势渐成,尤其是移动应用普及的今天,不再只是传统的互联网公司的专宠,传统企业也是趋之若鹜。但是遗憾的却始终没有一个规范标准,全凭企业...

  • 【ERC1155实践】ENJ铸造第一个有价值背书的游戏资产-WOC参考

    【导读】我们见证了太多没有价值背书的游戏资产击鼓传花的游戏,在音乐停止那一刻,这些资产是不存在价值的,而Enjin的资产铸造的方式,赋予了游戏资产的基础价值支撑...

  • 什么是NFT、链、加密货币、加密钱包

    NFT,全称为Non-Fungible Token,指非同质化代币,是用于表示数字资产(包括jpg和视频剪辑形式)的唯一加密货币令牌,可以买卖。

这段时间总是与NFT打交道,大部分NFT都采用了EIP721标准,且均采用了Openzepplin的EIP721实现。前段时间详细看过Openzepplin的相关实现,但是偷懒了,没有整理成文档,导致后面的记忆总是不深刻,理解也不深刻。此次正好将其实现全部整理一下。

这段时间总是与NFT打交道,大部分NFT都采用了EIP721标准,且均采用了Openzepplin的EIP721实现。前段时间详细看过Openzepplin的相关实现,但是偷懒了,没有整理成文档,导致后面的记忆总是不深刻,理解也不深刻。此次正好将其实现全部整理一下。

首先简单介绍下EIP-721标准,可以参考

在EIP-721标准中,定义了如下的标准函数和标准事件,任何NFT合约都必须实现EIP-721标准中定义的函数和事件

要求from字段必须填写owner地址,不能是其他地址
要求该tokenId必须是有效的NFT,即存在

在实现EIP-721的合约中,其必须也要实现EIP-165标准,即通用接口注册标准。用于接口发现和验证。其思路是合约实现EIP-165中定义的supportsInterface(bytes4 interfaceId)方法,该方法中将一个合约中所有的external函数签名进行亦或求值得到一个bytes4. 然后验证时遵循如下思路进行验证:

在目前的NFT合约实现中,基本所有的NFT都实现了MetaData这一部分的接口定义。其主要作用是定义NFT的名称,符号和tokenURI. 在EIP-721中,tokenURI的定义是要符合RFC-3986标准,但事实上目前的NFT合约中基本上都是一个自定义的状态。可能是项目方的一个网址,或者是一个IPFS文件,也可能是一串字符串。

Enumerable的目的是给用户提供一个快速查询NFT的方法。接口设计上是让用户可以根据用户自己的索引查询她所拥有的NFT对应的tokenId,另一个是根据索引查询合约中的NFT的tokenId, 然后是总的供给量查询,很多的NFT合约的总供给量反应的是现在所有的NFT的数量。简单来讲就是提供两个索引,一个索引用来索引整个合约中的NFT,另一个索引是用来索引用户所拥有的NFT

由于目前见到的所有的NFT合约其都是基于Openzepplin的EIP-721实现,故充分了解Openzepplin的EIP-721实现是非常有必要的,也是非常有帮助的。

  1. 首先是需要设计全局变量:

然后是依次实现EIP-721中定义的接口方法:

//address(0)能否是一个被授权的地址呢?是可以的,意味着该TokenId不对其他任何地址授权 //要求from必须是owner的地址,不能是operator的地址或者其他地址 //要求当transfer结束时,检查to地址是否是合约地址,如果是合约地址则需要调用onERC721Received方法,返回特定的值 //要求from必须是owner的地址,不能是operator的地址或者其他地址 //要求from必须是owner的地址,不能是operator的地址或者其他地址 //更改tokenId对应的所有权,取消相应tokenId的授权地址的权限,但不能取消经销商的权限 //作用是判断地址to是否是一个合约地址,如果不是一个合约地址则直接返回true,如果是一个合约地址,则需要调用地址to的onERC721Received方法来判断返回值是否是一个特定的返回值 //是EOA,必须同我直接交互,不能通过proxy //这样写会把to地址的报错给吞掉,没有把报错信息抛出来 //这样写可以把to地址的报错抛出来 //要求经销商不能是自己

关键点:自己不能是自己的经销商!

并没有清除相应的经销商的授权。同时,清除经销商的权限也是不合理的。其实此时作为经销商的alice还是无法再去transfer一次tokenId

  1. 其他的辅助方法:mint,burn

在当前的NFT合约中,大量使用了mint方法,然而此方法并不是EIP-721中规定的方法,但是其已经成为事实标准。简单来讲mint方法是新增一个tokenId,该tokenId不能是已经存在的,然后把该tokenId添加到对应的owner中。burn方法是删除该tokenId即可。mint和burn在openzeppelin的实现中都遵循了safeTransfeFrom的思路。mint方法并未提供一个公开的方法,而是一个_safeMint()内部方法,需要项目方自己去结合逻辑实现一个mint方法。

//要求清除该tokenId对应的授权地址,但不能清除经销商的授权

ERC721的枚举部分,该部分与ERC721主体部分分开,其实现的功能主要是提供totalSupply以及提供了两个索引,一个索引是tokenByIndex全局索引,另一个索引是tokenOfOwnerByIndex,即用户的索引。

//要得到最新的总供应量,即返回目前被NFT合约追踪下来的总的有效NFT数量
//根据全局索引来查找对应的tokenId
//根据特定的owner的索引查找其拥有的所有tokenId
 





 
 
这里需要思考枚举中的set方法应该在什么时候调用:其应该在每一次transfer之前都需要调用一次,因为transfer时肯定就发生了状态的变化。这里就需要用到ERC721中预先留下来的勾子函数:
在这个函数中,需要做如下的逻辑判断:

根据上述表格可以看到有三种类型的操作,transfer,mint和burn,需要针对三种不同的类型来分别更新mapping中的值

//为了解决上面提出的问题,这里删除时,预先将要删除的tokenId放置在最后一个槽位,然后只删除最后一个槽位 //swap 为节约gas费用,不考虑是否是最后一个槽位

从抽象概念上讲,智能合约是一种可以自动化执行的规则,现实生活中的合约,合约制定完成后需要有专门的执行角色,而智能合约将这个步骤自动化,只有满足智能合约中制定的条件就会被执行。

从具体概念上讲,我们之前有一篇文章讲中提到每个账户都有状态树,而智能合约的目的就是通过一系列逻辑执行触发合约账户的状态变化以及通过交易改变外部账户的状态,关于合约账号和外部账户可见""一文。

编程语言的一些基础概念

编程语言中,变量起着重要作用,用来存储内存数据。变量内存储的数据有各种各样的类型,有的是简单的整型,字符串,有的是较为复杂的集合类型,比如列表,映射表或上自定义的类型。变量还有1个很重要的概念就是作用域。

作用域代表变量的生命周期,是函数级别-函数执行完就销毁,还是对象级别,依附对象销毁就会销毁,或又是全局级别,只有程序在运行就一直都在。在智能合约中合约中声明的变量都是存储在状态树中,所以只要合约账户存在,这个变量就存在。这一点认识非常重要,后面在讲NFT的时候会讲1个误区。

函数代表着逻辑的执行,函数的输入有几种 1。可以访问的内存 磁盘 网络中的输入 2.调用函数者传入的参数,函数的输出也是有2种 1.可以访问的内存 磁盘 网络的输出 2.函数返回值 。

有一种纯函数的概念 即 输入只包含了调用函数者传入的参数,输出只包含了返回值。

在智能合约中,非依赖库所有能够让外部账户或者合约账户调用的函数都不应该是纯函数,否则就是对gas的浪费。

如上图,智能合约由外部账户发起调用,合约直接也可以相互调用,每个合约内部执行函数转移状态。

1.合约变量,即状态每个状态代表了什么含义。

2.函数 即合约中的函数是如何运转的,又是如何影响状态变化。

// 这声明了一个状态变量,为每个可能的地址存储一个 `Voter`。

这3个变量就是这个智能合约的状态

function开头的代表是一系列函数就是和前面说到的3个状态交互

如上图所示,智能合约中对外可调用的函数围绕着如何修改 或 读取状态而来,如同文章开始所讲到的,智能合约执行的过程就是以太坊中状态树变化的过程。

智能合约相比于其他编程非常要注意的1点就是运行逻辑需要收取gas费用,这使得合约编写过程要额外注重代码的高效性,尽可能地减少冗余代码。

gas费用存在的原因以及gas费用为什么高昂,之前中有讲,简单来说gas费用存在是因为计算需要耗费资源,存在gas费用可以避免恶意消耗资源的情况发生。gas费用高昂主要是因为竞争激烈。

gas费用计算可以看这里

,这里是一些操作码,我们写的代码最终都会编译成字节码指令运行在EVM上。

这是一个函数的修饰符,只有被payable修饰过的函数才可以在调用时附带ETH。

调用到智能合约没有的函数时会走到fallback函数, 如果没有写fallback会抛出异常,如果是涉及到附加ETH,fallback必须被payable修饰,否则也会抛出异常

对合约单纯转账会进入这个函数,前提是有这个函数,如果没有会进入被payable修饰的fallback函数,否则会抛出异常。

可以看到合约语言无不透露着对交易属性,这在一般的编程语言中是不会看到的。

合约一旦发布,即使存在漏洞就不可更改,所以对于逻辑要格外严谨。我们来看看1个常见漏洞

上面的代码中A给B转账会走到B的fallback函数,而B的fallback函数又调用A的转账函数,这样会导致A向B不停转账。

改进办法就是先修改状态再转账

NFT是最近比较热门的话题,很多人认为NFT代表了数字化的确权,也有人认为目前就是一张jpg图片,我们这里不讨论他的经济价值,讨论NFT的技术实现。在每一组NFT背后都是一份智能合约。这些智能合约都遵守着相同的规范。

上面的函数就是NFT智能合约需要遵守的规范- ERC721。

在编程语言中有个概念-接口。之前讲过函数的概念,而接口就是一组函数声明,要实现类似的东西大家都要有个规范,于是乎就有了接口。接口不负责具体实现,只是告诉你要实现什么能力,才能够满足规范。

我们从接口中挑1个大家有过讨论的函数看看。

这个函数目的是给这组NFT某个编号 设置一个url,这个url我们可以简单地理解为是一张图片(先简单理解)。这个接口的出现导致了,如果可以成功调用该接口,那么你高价购买到的NFT将有可能变成另外1张没有任何艺术价值的图片。

有的说法是这个url没有上链,如果上链了就不会有这个问题。所以我们接下来讨论下什么是上链。

当我们讨论上链时,什么是上链

很多人讨论链上的数据不可被更改,那到底什么是上链呢?在之前文章中曾经提到以太坊当中的状态树,只要存在这棵状态树里面的数据都是上链了的。而智能合约中每个合约状态都是存在状态树中的,所以只要是合约中声明的变量都可以称为上链 。另外1个问题,链上数据是否不可更改呢?准确回答说按照规则就可以更改,不按照规则就不可以更改。什么是按照规则,按照规则就是如果智能合约中有对应修改这个状态的函数,满足调用函数的条件,就可以改掉它!

回到NFT url的问题,这个url肯定是存到状态树上了,毋容置疑也是上链了的,但就因为暴露了这个接口所以才导致可以被更改。

这里另外提1个NFT url篡改的风险在于同1个url内映射的文件也可能被更改,这里就需要用到不可变更的存储,如ipfs等,后面我们专门有一篇内容来分析分布式存储。

本篇文章我们简单介绍了智能合约的一些基础概念,并针对没有编程基础的同学介绍了编程中常见的概念。说到学习代码唯有2招最为有效,1.多读代码 2.多写代码 所以我们和大家一起分析了个简易版的智能合约帮助大家了解智能合约的整体结构,并分析了智能合约一些针对交易设计的特点。最后结合智能合约比较热门的应用NFT了解了接口的概念,再次讨论了什么是上链。文中我们多次涉及到之前写的一文,可见底层知识的重要性。

更多web3相关文章 可关注公众号 "web3探索者"

我要回帖

更多关于 owners是什么意思 的文章

 

随机推荐