package test
import (
"encoding/json"
"fmt"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/crypto"
"io/ioutil"
"log"
"net/http"
"strings"
"testing"
)
func TestNameHash(t *testing.T) {
res, err := PostEns("wangbin.eth")
if err != nil {
panic(err)
}
fmt.Printf(res)
}
/*
ens域名->哈希id
python伪代码
def namehash(name):
if name == '':
return '\0' * 32
else:
label, _, remainder = name.partition('.')
return sha3(namehash(remainder) + sha3(label))
*/
func NameHash(name string) common.Hash {
node := common.Hash{}
if len(name) > 0 {
labels := strings.Split(name, ".")
for i := len(labels) - 1; i >= 0; i-- {
labelSha := crypto.Keccak256Hash([]byte(labels[i]))
node = crypto.Keccak256Hash(node.Bytes(), labelSha.Bytes())
}
}
return node
}
func PostEns(name string) (string, error) {
id := NameHash(name).String()
client := &http.Client{}
// "operationName":"getRegistrantFromSubgraph","variables":{"id":""},"query":"query getRegistrantFromSubgraph($id: ID!) 注册人信息
s := fmt.Sprintf(`{"operationName":"getResolverFromSubgraph","variables":{"id":"%s"},"query":"query getResolverFromSubgraph($id: ID!) {\n domain(id: $id) {\n id\n name\n resolver {\n coinTypes\n texts\n __typename\n }\n __typename\n }\n}\n"}`, id)
var data = strings.NewReader(s)
req, err := http.NewRequest("POST", "https://api.thegraph.com/subgraphs/name/ensdomains/ens", data)
if err != nil {
log.Fatal(err)
return "request failed", err
}
req.Header.Set("authority", "api.thegraph.com")
req.Header.Set("accept", "*/*")
req.Header.Set("accept-language", "zh-CN,zh;q=0.9")
req.Header.Set("content-type", "application/json")
req.Header.Set("origin", "https://app.ens.domains")
req.Header.Set("referer", "https://app.ens.domains/")
req.Header.Set("sec-ch-ua", `" Not A;Brand";v="99", "Chromium";v="100", "Google Chrome";v="100"`)
req.Header.Set("sec-ch-ua-mobile", "?0")
req.Header.Set("sec-ch-ua-platform", `"macOS"`)
req.Header.Set("sec-fetch-dest", "empty")
req.Header.Set("sec-fetch-mode", "cors")
req.Header.Set("sec-fetch-site", "cross-site")
req.Header.Set("user-agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Safari/537.36")
resp, err := client.Do(req)
if err != nil {
log.Fatal(err)
return "res failed", err
}
defer resp.Body.Close()
bodyText, err := ioutil.ReadAll(resp.Body)
if err != nil {
log.Fatal(err)
return "read failed", err
}
ens := make(map[string]interface{})
json.Unmarshal(bodyText, &ens)
domain_ := ens["data"].(map[string]interface{})
if domain_["domain"] == nil {
//fmt.Printf("可注册,null")
return "可注册,null", nil
} else {
doamin_st, _ := json.Marshal(domain_["domain"])
return "已被注册,域名信息:" + string(doamin_st), nil
}
}
打包命令行
package main
import (
"encoding/json"
"fmt"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/crypto"
"github.com/spf13/cobra"
"io/ioutil"
"log"
"net/http"
"strings"
)
/*
ens域名->哈希id
python伪代码
def namehash(name):
if name == '':
return '\0' * 32
else:
label, _, remainder = name.partition('.')
return sha3(namehash(remainder) + sha3(label))
*/
func NameHash(name string) common.Hash {
node := common.Hash{}
if len(name) > 0 {
labels := strings.Split(name, ".")
for i := len(labels) - 1; i >= 0; i-- {
labelSha := crypto.Keccak256Hash([]byte(labels[i]))
node = crypto.Keccak256Hash(node.Bytes(), labelSha.Bytes())
}
}
return node
}
func PostEns(name string) (string, error) {
id := NameHash(name).String()
client := &http.Client{}
// "operationName":"getRegistrantFromSubgraph","variables":{"id":""},"query":"query getRegistrantFromSubgraph($id: ID!) 注册人信息
s := fmt.Sprintf(`{"operationName":"getResolverFromSubgraph","variables":{"id":"%s"},"query":"query getResolverFromSubgraph($id: ID!) {\n domain(id: $id) {\n id\n name\n resolver {\n coinTypes\n texts\n __typename\n }\n __typename\n }\n}\n"}`, id)
var data = strings.NewReader(s)
req, err := http.NewRequest("POST", "https://api.thegraph.com/subgraphs/name/ensdomains/ens", data)
if err != nil {
log.Fatal(err)
return "request failed", err
}
req.Header.Set("authority", "api.thegraph.com")
req.Header.Set("accept", "*/*")
req.Header.Set("accept-language", "zh-CN,zh;q=0.9")
req.Header.Set("content-type", "application/json")
req.Header.Set("origin", "https://app.ens.domains")
req.Header.Set("referer", "https://app.ens.domains/")
req.Header.Set("sec-ch-ua", `" Not A;Brand";v="99", "Chromium";v="100", "Google Chrome";v="100"`)
req.Header.Set("sec-ch-ua-mobile", "?0")
req.Header.Set("sec-ch-ua-platform", `"macOS"`)
req.Header.Set("sec-fetch-dest", "empty")
req.Header.Set("sec-fetch-mode", "cors")
req.Header.Set("sec-fetch-site", "cross-site")
req.Header.Set("user-agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Safari/537.36")
resp, err := client.Do(req)
if err != nil {
log.Fatal(err)
return "res failed", err
}
defer resp.Body.Close()
bodyText, err := ioutil.ReadAll(resp.Body)
if err != nil {
log.Fatal(err)
return "read failed", err
}
ens := make(map[string]interface{})
json.Unmarshal(bodyText, &ens)
domain_ := ens["data"].(map[string]interface{})
if domain_["domain"] == nil {
//fmt.Printf("可注册,null")
return "可注册,null", nil
} else {
doamin_st, _ := json.Marshal(domain_["domain"])
return "已被注册,域名信息:" + string(doamin_st), nil
}
}
func ensDomain(cmd *cobra.Command, args []string) {
if len(args) == 0 {
fmt.Println("输入域名 多个空格隔开 ex: 'ens.eth' 'foo.eth' ")
}
for _, name := range args {
fmt.Println(name)
info, err := PostEns(name)
if err != nil {
fmt.Println(err)
return
}
fmt.Println(info)
}
}
var ensDomainCmd = &cobra.Command{
Use: "ens",
Short: "ens domain search",
Long: `ens domain search::TODO::`,
// 获取命令行参数 至少一个参数
// Args: cobra.MinimumNArgs(1),
Run: ensDomain,
}
var rootCmd = &cobra.Command{
Use: "rootCmd",
Short: "ens info",
Long: `usage description::TODO::`,
Run: mainRun,
}
func mainRun(_ *cobra.Command, _ []string) {
fmt.Println("get ens domain info ")
}
func init() {
// 添加子命令
rootCmd.AddCommand(ensDomainCmd)
}
func main() {
// os.Args
if err := rootCmd.Execute(); err != nil {
panic(err)
}
}
测试:
go build不同系统可执行程序:
1、Mac下编译Linux, Windows平台的64位可执行程序:
linux$ CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build test.go2
windows$ CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build test.go
2、Linux下编译Mac, Windows平台的64位可执行程序:
mac$ CGO_ENABLED=0 GOOS=darwin GOARCH=amd64 go build test.go
windows$ CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build test.go
3、Windows下编译Mac, Linux平台的64位可执行程序:
mac $SET CGO_ENABLED=0SET GOOS=darwin3 SET GOARCH=amd64 go build test.go
linux $SET CGO_ENABLED=0 SET GOOS=linux SET GOARCH=amd64 go build test.go