关于NFT提前从网站获取签名

这篇文章我觉得很有含金量,哈哈。

最近打的NFT项目,有一些是需要从前端获取签名的。这个时候,市面上大部分的Mint工具都未必能过得了这一关。

我在网上搜索了很多的资料,目前关于提前获取签名的教程几乎没有。科学家们的分享基本上都止步于合约mint、16进制mint等常规的mint方法,这些在我之前的文章里面也有提到。目前基本上来说超过半数的人都会这些mint方法,统称为非网页端mint方法吧。

当一个NFT项目限制了必须要获取前端服务器签名才能mint的时候,大部分人就只能干瞪眼或者老老实实去前端mint了(当然前端大概率是抢不到的)。

首先说下限制前端服务器签名才能mint的原理。这里以ApeDog为例。在合约的mint方法中,加了一个限制条件。

require(isAuthorized(sig,digest),"CONTRACT_MINT_NOT_ALLOWED");

就是说,每个钱包都需要提供一个签名才能调用mint的方法。这个签名需要从前端网页获取,是由项目方的钱包进行签署的。用户拿着签名去调用合约的mint方法时,合约就会根据签名反推出签名的内容,如果得到的内容(一般就是调用者的地址)是正确的,那么就允许用户进行mint。理论上,签名应该是对调用者的钱包进行签名,这样就不会出现所有人都共用一个签名的伪签名方式。之前有许多项目出现过类似的BUG,后来的人拿到前面人的签名就可以跳过前端直接合约mint。ApeDog这个项目,不光是对调用者的钱包进行了签名,还为每个签名给定了一个有效时间,过了这个有效时间签名就会作废。这个设置挡住了许多提前获取签名的人。

那么前端是如何拿到签名的呢?我们在前端进行mint的时候,一般先连接小狐狸钱包,然后点击mint的按钮,就会跳出小狐狸窗口了,在小狐狸窗口中提交交易即可进行mint。其实在跳出小狐狸窗口的时候,我们看data里面的内容,就已经包含了我们所需要的签名信息了。这是最正规的获取签名的渠道。如果我们想要通过科学家的方式来获取签名的话,首先需要了解前端获取签名的过程。

当我们点击mint按钮的时候,在前端网页就会触发一个event。这个event就会通过一个接口把我们的钱包地址等信息发给后台,后台在收到这些信息后,会调用项目方的钱包对这些信息进行签名,然后返回给前端。这个就是前端获取签名的基本流程。

所以,如果我们不想老老实实的点击mint按钮去获得签名的话,就需要我们自己直接去调用这个接口来和后台进行互动。

调用接口的方式很简单,一般就是两种方法,GET和POST。获取签名的话一般会用POST。调用POST方法的时候,需要输入两个参数,一个是目标url,一个是headers。url就是接口的地址,headers就是我们需要代入的参数。

那么如何获得接口的url地址呢?两种方法,第一个,在前端页面的上通过f12打开开发者模式,在network选项卡中抓包。点击mint按钮后,找到网页对应发送的post请求,在请求中就可以得到我们需要的url了,顺便还能看到我们的headers中包含的参数,一举两得。这种方法的前提是网页要能打得开,一般情况下,比较火爆的项目在发售的时候,前端都会卡的根本没有机会点击mint按钮…

第二种方法的门槛就比较高了,那就是阅读网页的源代码。大部分的NFT项目的源代码都会暴露在网页上,通过开发者模式就可以查看到。通过f12进入开发者模式下,就可以看到网页的js文件。这些js文件可能也是经过了处理,一般可读性都很差…还是以ApeDog项目为例,因为迄今为止我只从它这找到了接口地址。

在apedog.wtf这个目录下只有一个js文件,所以找起来目标就比较明确了。有的项目目录下还有好多文件,找起来就不太好定位了。

点击打开js文件,搜索POST,会出来许多匹配结果。一个一个看一下,看到这里,就需要注意下了。后面跟着一个sigurl。推测这个sigurl就是接口地址。接着搜索sigurl。

这下就看到了,后面的这个url应该就是我们要找的接口url了。接着看,下面一行还有一个auth,这个一般需要写在headers里面,类似一个授权的东西。

接着搜索sigurl,看到这个部分。这里有两个参数,一个是sender,应该就是我们的钱包地址了,还有一个Authorization,就是需要我们刚才看到的auth的内容。那么,接下来我们就可以去调用POST方法了。

这里用python的request库。

import requests

url = 'https://1-0-0--wen-wl.rekttt.autocode.gg/'
auth = 'tok_prod_DxcW8FCKenfdpGDbGD8puUfjqmEYCpPTZ5DijpGLd1XHpzaep19jxyds6y6HLMQ1'
headers = {
  'user-agent': 'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Mobile Safari/537.36',
  'Authorization': 'Bearer ' + auth,
  'sender': 'wallet address'
}

res = requests.post(url,headers)
print(res.text)

填入我们扒出来的url、auth还有我们自己的钱包地址。运行结果如下:

{"signature":"0xf5d836dbeb2662e5066256456d8a2d05d6de926d28e4e70861cd90dbd755345710d83b290bce4dfd530042d2c32f8fc2d287a535fcf89187b008baf8e386e816","expireTime":1658179246}

看看这是啥,这就是我们需要得到的签名了。我们绕过了前端,直接通过接口的方式提前获取到了签名,拿着这个签名就可以去mint啦。这个方法需要我们能够从js文件中找到接口的地址,还需要弄清楚接口需要发送那些参数,比较考验我们的经验还有阅读代码的能力。不同的项目的代码都是不一样的,所以基本上每个项目都得重新修改获取签名的方式。对于普通玩家就非常不友好了。这里也非常佩服市面上的一些工具,能够自动获取签名,让用户赢在起跑线。不得不说,收费有收费的道理啊!

Subscribe to JamesTsao的个人成长笔记
Receive the latest updates directly to your inbox.
Nft graphic
Mint this entry as an NFT to add it to your collection.
Verification
This entry has been permanently stored onchain and signed by its creator.
More from JamesTsao的个人成长笔记

Skeleton

Skeleton

Skeleton