dapp获取钱包地址,及签名

复制代码
npm install ethers

import {ethers} from 'ethers'
复制代码
const accounts = await ethereum.request({method: 'eth_requestAccounts'});
// 获取钱包地址
this.form.address = accounts[0]
console.log("accounts:" + this.address)

const provider = new ethers.BrowserProvider(window.ethereum)
//签名
const signer = await provider.getSigner()
const signature = await signer.signMessage(this.form.address)
console.log("signature:" + signature);        

ethers.verifyMessage(nonce, signature) 在后端的实现

Java 后端项目 maven导入web3j

复制代码
<dependency>
   <groupId>org.web3j</groupId>
   <artifactId>core</artifactId>
   <version>4.5.16</version>
</dependency>

Java main方法示例代码

复制代码
import org.web3j.crypto.ECDSASignature;
import org.web3j.crypto.Hash;
import org.web3j.crypto.Keys;
import org.web3j.crypto.Sign;
import org.web3j.utils.Numeric;

import java.math.BigInteger;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;

public class SignInWithEthereum {
   public static void main(String[] args) {
      String address = "0x4adbe2009cff6a1e9d280d28815c49e91b8ebad0";
      String nonce = "3618473";
      String signature = "0x9a38fb504315869609ef2e948b1a80f670e6ff725d16b5ae443b118eb2d108bc3c659c2417d96bbff240b44d4f1078fde73b72f83cc71e4e726640bc19a9c2a91c";
      String MESSAGE_PREFIX = "\u0019Ethereum Signed Message:\n";
      try {
         String digest = Hash.sha3(
                 Numeric.toHexStringNoPrefix(
                         (MESSAGE_PREFIX + nonce.length() + nonce).getBytes(StandardCharsets.UTF_8)));

         byte[] signatureBytes = Numeric.hexStringToByteArray(signature);
         byte v = signatureBytes[64];
         if (v < 27) {
            v += 27;
         }
         byte[] r = (byte[]) Arrays.copyOfRange(signatureBytes, 0, 32);
         byte[] s = (byte[]) Arrays.copyOfRange(signatureBytes, 32, 64);

         Sign.SignatureData signatureData = new Sign.SignatureData(v, r, s);
         int header = 0;
         for (byte b : signatureData.getV()) {
            header = (header << 8) + (b & 0xFF);
         }
         if (header < 27 || header > 34) {
            System.out.println("false");
         }
         int recId = header - 27;
         BigInteger key = Sign.recoverFromSignature(
                 recId,
                 new ECDSASignature(
                         new BigInteger(1, signatureData.getR()), new BigInteger(1, signatureData.getS())),
                 Numeric.hexStringToByteArray(digest));
         if (key == null) {
            System.out.println("false");
         }
         String signAddress = ("0x" + Keys.getAddress(key)).trim();
         System.out.println("signAddress:" + signAddress);
         if (address.toLowerCase().equals(signAddress.toLowerCase())) {
            System.out.println("true");
         }
      } catch (Exception e) {
         System.out.println("false");
      }
   }
}

Java 封装的工具类

复制代码
import java.math.BigInteger;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;

import org.web3j.crypto.ECDSASignature;
import org.web3j.crypto.Hash;
import org.web3j.crypto.Keys;
import org.web3j.crypto.Sign;
import org.web3j.crypto.Sign.SignatureData;
import org.web3j.utils.Numeric;

public class EthersUtils {
  private static final String MESSAGE_PREFIX = "\u0019Ethereum Signed Message:\n";

  public static String verifyMessage(String message, String signature) {
    return EthersUtils.recoverAddress(EthersUtils.hashMessage(message), signature);
  }

  public static String hashMessage(String message) {
    return Hash.sha3(
        Numeric.toHexStringNoPrefix(
            (EthersUtils.MESSAGE_PREFIX + message.length() + message).getBytes(StandardCharsets.UTF_8)));
  }

  public static String recoverAddress(String digest, String signature) {
    SignatureData signatureData = EthersUtils.getSignatureData(signature);
    int header = 0;
    for (byte b : signatureData.getV()) {
      header = (header << 8) + (b & 0xFF);
    }
    if (header < 27 || header > 34) {
      return null;
    }
    int recId = header - 27;
    BigInteger key = Sign.recoverFromSignature(
        recId,
        new ECDSASignature(
            new BigInteger(1, signatureData.getR()), new BigInteger(1, signatureData.getS())),
        Numeric.hexStringToByteArray(digest));
    if (key == null) {
      return null;
    }
    return ("0x" + Keys.getAddress(key)).trim();
  }

  private static SignatureData getSignatureData(String signature) {
    byte[] signatureBytes = Numeric.hexStringToByteArray(signature);
    byte v = signatureBytes[64];
    if (v < 27) {
      v += 27;
    }
    byte[] r = (byte[]) Arrays.copyOfRange(signatureBytes, 0, 32);
    byte[] s = (byte[]) Arrays.copyOfRange(signatureBytes, 32, 64);
    return new SignatureData(v, r, s);
  }
}
相关推荐
晓宜8 小时前
Solidity入门实战—web3
web3·区块链
晓宜8 小时前
Solidity基础入门2—web3
web3·区块链
电报号dapp11917 小时前
Web3游戏全栈开发实战指南:智能合约与去中心化生态构建全解析
游戏·web3·去中心化·区块链·智能合约
晓宜1 天前
Solidity基础入门—web3
web3·区块链
Footprint_Analytics2 天前
3.31-4.06 Web3 游戏周报:Pebble 玩家留存率登顶,Treasure DAO 面临重组危机
游戏·web3
markzzw2 天前
《浏览器插件钱包(二) - 处理DApp请求》
前端·web3·区块链
半间烟雨3 天前
Web3(阶段一:入门)——哈希算法
算法·web3·区块链·哈希算法
CertiK3 天前
重磅 | CertiK《Hack3d:2025第一季度安全报告》(附报告全文链接)
安全·web3·区块链·智能合约
Sui_Network3 天前
Webacy 利用 Walrus 技术构建链上风险分析决策层
人工智能·游戏·web3·去中心化·区块链
小钰能吃三碗饭5 天前
打造类 RainbowKit 的 Solana 钱包连接套件
前端·web3·区块链