3

新版以太坊Ethereum库ethersV5.0配合后端Golang1.18实时链接区块链钱包(Metamask/Okc)...

 1 year ago
source link: https://v3u.cn/a_id_262
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
新版以太坊Ethereum库ethersV5.0配合后端Golang1.18实时链接区块链钱包(Metamask/Okc)以及验签操作

    区块链去中心化思想无处不在,比如最近使用个体抗原自检替代大规模的中心化核酸检测,就是去中心化思想的落地实践,避免了大规模聚集导致的交叉感染,提高了检测效率,本次我们使用Ethereum最新的ethersV5.0以上版本链接去中心化区块链钱包,并且通过后端Golang1.18服务进行验签。

    在之前的一篇文章:青山不遮,毕竟东流,集成Web3.0身份钱包MetaMask以太坊一键登录(Tornado6+Vue.js3)中,我们使用的是ethersV4.0版本链接Metamask钱包,后端使用基于Python3.10的Tornado6.0框架,为了避免同质化,这里换成Okc钱包,客户端插件安装地址:https://chrome.google.com/webstore/detail/okx-wallet/mcohilncbfahbmgdjkbpemcciiolgcge

    前端链接浏览器钱包

    首先卸载Vue2.0项目:

npm uninstall vue-cli -g

    这里node版本要在8.9以上,npm版本要在6以上;

    随后安装Vue3.0以上版本:

npm install -g @vue/cli

    然后安装pnpm:

npm install -g pnpm

    pnpm解决了传统npm的node_modules依赖困境,主要通过软链接和硬链接的结合使用,最终达到节省磁盘空间,安装速度快,严格高效等目的,这里推荐使用pnpm进行包管理。

    接着,在当前项目中安装ethers库:

pnpm install [email protected] --save

    注意这里版本要求v5.0以上。

    根据ethers5.4官方文档所述:https://docs.ethers.io/v5/getting-started/#getting-started--connecting-rpc

    ethers5.0版本支持异步async操作,提高了效率,async函数就是使用async关键字声明的函数。它是 AsyncFunction 构造函数的实例,并且其中允许使用 await 关键字。async 和 await 关键字让我们可以用一种更简洁的方式写出基于 Promise 的异步行为,而无需刻意地链式调用 promise。

    声明异步链接方法:

//链接逻辑
connect:async function(){


},

    随后请求链接当前的区块链钱包,并且异步获取公钥地址:

const provider = new ethers.providers.Web3Provider(window.ethereum);

const accounts = await provider.send("eth_requestAccounts", []);

    打印钱包地址:

console.log(accounts);

    如图所示:

20221204171220_58763.png

    这里已经打印出了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);
});

    这里通过provider对象获取签名者对象signer,接着调用signMessage方法来进行签名操作,加签算法采用最简单的字符串+时间戳的形式。

    前端返回签名和公钥地址:

0x5cae6c39a56d99d68e7a20c76da0ec387e34249b 
0x1093b6dc7c6ae1340b2ebcf819dac1a7160b69a2abbb14d86a0696bd96d6b36923d5f3f82588f30a9353b327014338f51d4e7a90baa8052791a8017f156b57511c

    后端Golang验签

    验签的目的很好理解,如果在链接钱包的一瞬间,客户端被监听的其他软件恶意篡改公钥地址,那么很可能会给客户造成不可挽回的经济损失,所以暴露在前端的一切数据都需要后端进行校验,之前我们采用的是Python3.10版本进行验签操作:

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

    这里通过签名反向解析出了公钥地址,并且和前端获取的地址保持一致。

    下面我们采用Golang1.18版本来验签,看看有什么不一样,首先安装Golang1.18,请移步:兔起鹘落全端涵盖,Go lang1.18入门精炼教程,由白丁入鸿儒,全平台(Sublime 4)Go lang开发环境搭建EP00

    随后安装基于Golang的Ethereum库:

go get github.com/storyicon/sigverify

    根据官方文档指引:https://github.com/storyicon/sigverify

    构建main.go文件:

package main

import (
"fmt"

ethcommon "github.com/ethereum/go-ethereum/common"
"github.com/storyicon/sigverify"
)

func main() {
valid, err := sigverify.VerifyEllipticCurveHexSignatureEx(
ethcommon.HexToAddress("0x5cae6c39a56d99d68e7a20c76da0ec387e34249b"),
[]byte("Signing in at 1670142219"),
"0xc7b06789e6710652d8540487055e0e75918c9c4366ec47c9e7008760df1dedd6506a908f466e448481afed3fe009bbdbfdfa16c28585eff68be54d600083d4251b",
)
fmt.Println(valid, err) // true <nil>
}

    这里sigverify.VerifyEllipticCurveHexSignatureEx方法有三个参数,分别是公钥地址,签名字符集以及前端返回的签名字符串,返回值为valid:

➜  mydemo git:(master) ✗ go run "/Users/liuyue/wodfan/work/mydemo/src/mytest.go"
true <nil>

    如果验签通过会返回布尔值:true。

    至此,后端验签流程就结束了。

    总体而言,前端Ethers采用了ES7新语法async/await实现了重大改进,它提供了一种使用同步代码样式异步链接钱包对象的方式,而且不会阻塞主线程,而后端Golang作为编译型语言验签流程反而比解释型的Python更加简单方便。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK