# 如何监测巨鲸钱包地址

By [JamesTsao的个人成长笔记](https://paragraph.com/@pigfly) · 2022-08-01

---

本文和大家分享如何监测巨鲸钱包的链上活动，这里主要关注NFT的Mint与售出。

用到的是Python、Alchemy api还有一点爬虫知识。

Alchemy提供了非常丰富且实用的api接口，今天我们用到的是Alchemy的Websocket功能。

官方示例：

[https://docs.alchemy.com/alchemy/tutorials/how-to-track-ethereum-transactions](https://docs.alchemy.com/alchemy/tutorials/how-to-track-ethereum-transactions)

首先需要去Alchemy官网注册并获得我们的Alchemy Key。然后通过create connection建立Websocket连接：

    create_connection("wss://eth-mainnet.g.alchemy.com/v2/"+ALCHEMY_KEY)
    

成功建立链接后，发送监听：

    ws.send(json.dumps({
            "jsonrpc":"2.0",
            "method":"eth_subscribe",
            "params":[
                "alchemy_filteredNewFullPendingTransactions",
                {"fromAddress":
                    ["whale address 1",
                     "whale address 2",
                    ]
                }
            ],
            "id":1}))
    

id指的是链的id，以太坊主网则为1。

这里监听的是地址发出的pending transaction，也就是还没有被链上确认的transaction。如果监听到了地址发出的pending，那么会传到ws.recv()当中。这个时候我们通过解析这个结果，就可以得到transaction的信息了。通常一个返回的ws.recv()会包含以下的信息：

    {"id":1,"result":"0xf13f7073ddef66a8c1b0c9c9f0e543c3","jsonrpc":"2.0"}
    
    {
      "jsonrpc": "2.0",
      "method": "eth_subscription",
      "params": {
        "result": {
          "blockHash": null,
          "blockNumber": null,
          "from": "0x098bdcdc84ab11a57b7c156557dca8cef853523d",
          "gas": "0x1284a",
          "gasPrice": "0x6fc23ac00",
          "hash": "0x10466101bd8979f3dcba18eb72155be87bdcd4962527d97c84ad93fc4ad5d461",
          "input": "0xa9059cbb00000000000000000000000054406f1ec84f89532f83768f3f159b73b237257f0000000000000000000000000000000000000000000000000000000001c9c380",
          "nonce": "0x11",
          "to": "0xdac17f958d2ee523a2206206994597c13d831ec7",
          "transactionIndex": null,
          "value": "0x0",
          "type": "0x0",
          "v": "0x26",
          "r": "0x93ddd646056f365352f7e53dfe5dc81bde53f5b7c7bbe5deea555a62540d6995",
          "s": "0x79ed82a681930feb11eb68feccd1df2e53e1b96cf9171ae4ffcf53e9b2a40e8e"
        },
        "subscription": "0xf13f7073ddef66a8c1b0c9c9f0e543c3"
      }
    }
    

我们只需要取出我们需要的信息即可，比如from address、to address、hash、input。因为我们监控的是巨鲸地址铸造或者售出NFT的活动，所以from address一般都是巨鲸地址。不过光有这些数据还不够，我们想知道这笔交易究竟是做了啥，光看tx啥也看不出来。

我们需要在etherscan上面去查询这个hash，获取一些补充信息。从下面这个页面可以看到这笔hash背后的transaction action，是Mint of Sybilverse。不过目前etherscan并不提供获取这个transaction action的api，所以我们需要通过爬虫去抓取这个网页的元素，来获得我们想要的信息。

![](https://storage.googleapis.com/papyrus_images/50eb9b3c90dcfda06a69e48112a339f61de337b51cb57e663716b7afda691a87.png)

由于我们监听到的是pending的transaction，所以需要等transaction的状态为success之后才能查看到其对应的transaction action。

    url = "https://etherscan.io/tx/"+hash
            headers={ 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36',}
    
            for i in range(10):
                req = requests.get(url, headers=headers,data={'_InField1': 'RESTRIC', '_InField2': 'code', '_InField3': '13d2'})
                html = req.text
                tree = etree.HTML(html)
                pendingstatus = tree.xpath('//div[@class="col col-md-9"]/span/text()')
                print(pendingstatus)
                try:
                    if  pendingstatus[0] == 'Success':
                        break
                    else:
                        time.sleep(3)
                except:
                    time.sleep(3)
    

另外，这个transaction action的信息在html中的位置还不是一成不变的，需要多抓取几个地方，判断一下抓取的内容。比如Mint和Sale这两种action，在页面上的位置就是不一样的，需要做出自己的判断。

    method = tree.xpath('//span[@class="mr-1 d-inline-block"]/text()')
    method2 = tree.xpath('//span[@class="text-secondary mr-1"]/text()')
    projectName = tree.xpath('//span[@class="hash-tag text-truncate mr-1" and @data-toggle="tooltip"]/@title')
    profit = tree.xpath('//div[@class="media-body"]/span[@class="mr-1"]/text()')
    
    if method[0] == 'Transfer of':
      event = method2[0] + " " + profit[0] + " " + projectName[0] + ' ' + 'For' + ' ' + profit[1]
    else:
      event = method[0] + " " + projectName[0]
            
    

抓取到了etherscan页面上的详细信息之后，我们就可以通过发送到钉钉、discord或者telegram之类的通讯软件上来提醒自己了。

最后补充一下，如果想要监听已经确认的transaction，需要用到Alchemy的notify功能。这里需要自己提供一个webhook url，网上免费的webhook url不是很稳定，感觉监听pending的transaction就够了，还更快一点得到通知。

如果想要把监听的程序挂到云服务器运行的话，在爬虫环节云服务器的ip容易被etherscan阻拦，需要通过代理ip的方式来爬取信息。免费的代理ip基本上没有能用的，如果需要挂到云服务器的话还是用付费proxy吧。

---

*Originally published on [JamesTsao的个人成长笔记](https://paragraph.com/@pigfly/yxoTAWwwiz1gYMt8mYb1)*
