區(qū)塊鏈去中心化思想無(wú)處不在,比如最近使用個(gè)體抗原自檢替代大規(guī)模的中心化核酸檢測(cè),就是去中心化思想的落地實(shí)踐,避免了大規(guī)模聚集導(dǎo)致的交叉感染,提高了檢測(cè)效率,本次我們使用Ethereum最新的ethersV5.0以上版本鏈接去中心化區(qū)塊鏈錢包,并且通過(guò)后端Golang1.18服務(wù)進(jìn)行驗(yàn)簽。
在之前的一篇文章:青山不遮,畢竟東流,集成Web3.0身份錢包MetaMask以太坊一鍵登錄(Tornado6+Vue.js3)中,我們使用的是ethersV4.0版本鏈接Metamask錢包,后端使用基于Python3.10的Tornado6.0框架,為了避免同質(zhì)化,這里換成Okc錢包,客戶端插件安裝地址:
https://chrome.google.com/webstore/detail/okx-wallet/mcohilncbfahbmgdjkbpemcciiolgcge
首先卸載Vue2.0項(xiàng)目:
npm uninstall vue-cli -g
這里node版本要在8.9以上,npm版本要在6以上;
隨后安裝Vue3.0以上版本:
npm install -g @vue/cli
然后安裝pnpm:
npm install -g pnpm
pnpm解決了傳統(tǒng)npm的node_modules依賴?yán)Ь?,主要通過(guò)軟鏈接和硬鏈接的結(jié)合使用,最終達(dá)到節(jié)省磁盤空間,安裝速度快,嚴(yán)格高效等目的,這里推薦使用pnpm進(jìn)行包管理。
接著,在當(dāng)前項(xiàng)目中安裝ethers庫(kù):
pnpm install ethers@
5.7
.2
--save
注意這里版本要求v5.0以上。
根據(jù)ethers5.4官方文檔所述:
https://docs.ethers.io/v5/getting-started/#
getting-started--connecting-rpc
ethers5.0版本支持異步async操作,提高了效率,async函數(shù)就是使用async關(guān)鍵字聲明的函數(shù)。它是 AsyncFunction 構(gòu)造函數(shù)的實(shí)例,并且其中允許使用 await 關(guān)鍵字。async 和 await 關(guān)鍵字讓我們可以用一種更簡(jiǎn)潔的方式寫出基于 Promise 的異步行為,而無(wú)需刻意地鏈?zhǔn)秸{(diào)用 promise。
聲明異步鏈接方法:
//鏈接邏輯
connect:
async
function(
){
},
隨后請(qǐng)求鏈接當(dāng)前的區(qū)塊鏈錢包,并且異步獲取公鑰地址:
const provider =
new ethers.providers.Web3Provider(
window.ethereum);
const accounts =
await provider.send(
"eth_requestAccounts", []);
打印錢包地址:
console.log(accounts);
如圖所示:
這里已經(jīng)打印出了okc錢包的公鑰地址,隨后生成簽名:
const signer = provider.getSigner();
var rightnow = (
Date.now()/
1000).toFixed(
0)
console.log(rightnow);
signer.signMessage(
"Signing in at "+rightnow)
.then(
(
signature) => {
//打印簽名和公鑰
console.log(accounts[
0],signature);
});
這里通過(guò)provider對(duì)象獲取簽名者對(duì)象signer,接著調(diào)用signMessage方法來(lái)進(jìn)行簽名操作,加簽算法采用最簡(jiǎn)單的字符串+時(shí)間戳的形式。
前端返回簽名和公鑰地址:
0x5cae6c39a56d99d68e7a20c76da0ec387e34249b
0x1093b6dc7c6ae1340b2ebcf819dac1a7160b69a2abbb14d86a0696bd96d6b36923d5f3f82588f30a9353b327014338f51d4e7a90baa8052791a8017f156b57511c
驗(yàn)簽的目的很好理解,如果在鏈接錢包的一瞬間,客戶端被監(jiān)聽的其他軟件惡意篡改公鑰地址,那么很可能會(huì)給客戶造成不可挽回的經(jīng)濟(jì)損失,所以暴露在前端的一切數(shù)據(jù)都需要后端進(jìn)行校驗(yàn),之前我們采用的是Python3.10版本進(jìn)行驗(yàn)簽操作:
from web3.auto
import w3
from eth_account.messages
import defunct_hash_message
import time
public_address =
"0x5cae6c39a56d99d68e7a20c76da0ec387e34249b"
signature =
"0xc7b06789e6710652d8540487055e0e75918c9c4366ec47c9e7008760df1dedd6506a908f466e448481afed3fe009bbdbfdfa16c28585eff68be54d600083d4251b"
#rightnow = int(time.time())
rightnow =
1670142219
print(rightnow)
original_message =
'Signing in at {}'.format(rightnow)
message_hash = defunct_hash_message(text=original_message)
signer = w3.eth.account.recoverHash(message_hash, signature=signature)
print(signer)
程序返回:
1670142219
0x5cAE6c39A56d99d68e7A20c76da0ec387e34249b
這里通過(guò)簽名反向解析出了公鑰地址,并且和前端獲取的地址保持一致。
下面我們采用Golang1.18版本來(lái)驗(yàn)簽,看看有什么不一樣,首先安裝Golang1.18,請(qǐng)移步:兔起鶻落全端涵蓋,Go lang1.18入門精煉教程,由白丁入鴻儒,全平臺(tái)(Sublime 4)Go lang開發(fā)環(huán)境搭建EP00
隨后安裝基于Golang的Ethereum庫(kù):
go get github.com/storyicon/sigverify
根據(jù)官方文檔指引:
https://github.com/storyicon/sigverify
構(gòu)建main.go文件:
package main
import (
"fmt"
ethcommon
"github.com/ethereum/go-ethereum/comm