很多朋友在Opensea上购买NFT时,会发现自己的钱包正在调用一个名为Atomic Match_的方法,正好这段时间做的项目需要和Opensea交互,研究了一下Opensea的合约,今天就从
atomicMatch_开始,分析一下Opensea的合约源码,希望能够帮到大家。

当用户初次使用opensea上架NFT时,会被要求初始化钱包(”lnitialize your wallet”),其本质是创建一个代理合约,做为下一步授权(”Approve this item for sale”)的目标。最后一步为签名(签名的信息为配对参数信息,且保存到Opensea的中心化服务器中)。


2.1 buy now 模式
当buyer点击buy now 对已经list的订单进行购买时,首先在前端获取order.buy部分,同时在Opnesea数据库获取order.sell部分并将其加入缓存,封装后作为参数调用atomicMatch_方法,在方法内部确认订单可用且匹配后,通过调用代理合约来实现transferfrom方法。

2.2 make offer 模式
make offer同理

可以看到,atomicMatch_在其中起到至关重要的作用,现在就让我们来看看这个方法究竟实现了哪些功能

可以看到它的参数很多,但其本质只是将order.sell和order.buy集合到了一起。
atomicMatch的四个参数分别为(买方order参数合集,买方签名vrs,卖方order参数合集,卖方签名vrs)
我们从Order和Sig切入:
order:order结构体包含了如交换合约,订单创建者,订单获取者等大量和交易有关的数据(因篇幅原因不全部展示,可以到区块链浏览器中获取,下同)

Order信息存储在Opnesea的中心化服务器中,可以通过API获取

Sig:Sig结构体就简单很多,其主要作用是为了验证签名。

1.验证
1.1验证order参数

在这两个条件判断中,Opense逻辑是这样的, 如果是buy now模式,即buyer交易的发起者,在这里对buyer进行订单参数校验,对seller进行签名校验 如果是make offer模式,即seller是交易的发起者,在这里对seller进行订单参数校验,对buyer进行签名校验

validateOrderParameters 主要从四个方面来验证
1.当前合约是否为规定的交换合约
2.订单创建者地址是否为空
3.订单价格是否固定+是否在有效期内
4.判断费率是否正常
1.2 验证后通过orderCanMatch判断order.sell和order.buy的信息是否匹配

1.3验证calldate是否匹配

在讲解代码前,先从流程见一下大概原理,方便大家理解。
首先获取由NFT拥有者创建的代理合约(即获得NFT授权的合约)的实例,调用代理合约的implement合约的proxy方法,proxy方法指向并调用target合约,由target合约进行最后校验与token的转移。
2.1 获取target地址

2.2 获取代理合约实例


2.3 获取包含implement proxy方法的代理合约实例


在这里要强调一下,有的朋友可能会有疑问,为什么这里明明是implement 的contract,为什么要传入代理合约的地址? 这是因为implement合约并没有获取NFT的授权。又有朋友有疑问了,代理合约没有写transferFrom方法,或者调用方法,他是怎么做到去调用transferFrom的呢。其实代理合约合约还真的写了,只不过在区块链浏览器上没办法显示出来。


这里运用了内联汇编的方法,调用implement的proxy方法。
新版的完整区块链浏览器显示,应该是这样的

2.4将该签名的状态锁定

2.5转移费用

2.6验证implement的地址和转移NFTproxy方法指向并调用target合约,由target合约进行最后校验与token的转移。

proxy通过对contracts(msg.sender)的调用来判断目前调用该方法的地址是否为被注册为可调用地址

更多有关Opensea的内容,可能会在下期更新。
discord:johnn#0104
