已完成,整理后开源
\small\color{red}{写在前面:笔者资历尚浅,经验欠缺,若有缺漏错误之处,恳请读者斧正。}
实录详案
详案前置
- 开发目的
- 验证Discord用户是否持有StoneAeon NFT
- 为持有StoneAeon NFT用户赋予holder身份组
- 开发工具
- Node.js
- Discord.js
- MetaMask
- WebSocket协议
- VScode IDE
- Discord Bot
- Node.js
- 开发环境
- 测试环境:
- Windows10 家庭版
- 8C16G 256GSSD
- Node version:v14.15.5
- npm version:6.14.11
- 生产环境
- Ubuntu 18.04 TLS
- 4C8G 240GSSD
- Node version:v16.14.0
- npm version:8.3.1
- 测试环境:
开发思路
- 创建Verify Channel——点击频道内信息按钮带参跳转到外部连接进行Holder Verify
- 外部链接提供Connect Wallet按钮,点击后呼起MetaMask,连接当前用户钱包
- \small\color{red}{仅用于连接获取用户地址,不做签名}
- 用户确认连接并提交验证后,将用户信息传值后端处理
- userId(Discord)
- userAddress(MetaMask)
- \small\color{blue}{兼容EVM底层的地址均可使用}
- 接收前端数据,POST请求StoneAeon NFT持有人列表
- 查询当前用户是否在列表中
- 存在:userIsHolder = 1
- 不在:userIsHolder = 0
文件目录
\small\color{red}{暂不提供,开发完毕后见Github}
实录详情
服务器端
- 创建server.js监听6060端口
server.js
const http = require('http')
const fs = require('fs')
const url = require('url')
const path = require('path')
let server = http.createServer(function (request, response) {
//获取输入的url解析后的对象
let pathname = url.parse(request.url, true).pathname;
if (pathname == '/') {
pathname = '/index.html';
}
//static文件夹的绝对路径
let staticPath = path.resolve(__dirname, 'public');
//获取资源文件绝对路径
let filePath = path.join(staticPath, pathname);
console.log(filePath);
//异步读取file
fs.readFile(filePath, function (err, data) {
if (err) {
console.log(err);
// 如果找不到文件资源报错可以显示准备好的 404页面
let errPath = path.join(staticPath, '/404.html');
fs.readFile(errPath, (err, data404) => {
if (err) {
console.log('error');
response.write('404 Not Found');
response.end();
} else {
response.writeHead(404, { "Content-Type": "text/html;charset='utf-8'" });
response.write(data404);
response.end();
}
})
} else {
console.log('ok');
response.write(data);
response.end();
}
})
})
server.listen(6060)
console.log('visit http://localhost:6060')
- 页面目录【public】
- index.html
- js
- index.js
- css
- index.css
- images
- favicon.ico
- platon.png
-
\small\color{red}{浏览器访问}
Your Public IP or Domain:6060
- 采用提交form表单的方式,将前端钱包地址以POST方法传递给服务器端
- 服务器接收地址后,通过axios异步请求StoneAeon NFT的持有人列表,做查询操作
-
\small\color{red}{axios获取的持有人列表,address参数均为Bech32的LAT地址}
- 因此需要将用户传值做地址格式转换,从EIP55变更为Bech32,即0x转为lat
//举例
web3.utils.decodeBech32Address('lat', 'lat1zg69v7yszg69v7yszg69v7yszg69v7y30mluqx');
web3.utils.toBech32Address('lat', '0x1234567890123456789012345678901234567891');