主页 > imtoken手机钱包 > 开发一个区块链app多少钱 使用 OpenZeppelin 和以太币

开发一个区块链app多少钱 使用 OpenZeppelin 和以太币

imtoken手机钱包 2023-09-27 05:12:18

使用 OpenZeppelin 和 Ethers.js 在 Solidity 中使用 ECDSA 验证链下结果和白名单

未标题-3

img

介绍

作为该领域的区块链开发者或爱好者开发一个区块链app多少钱,我们对以太坊的高gas问题应该并不陌生。以太坊的价格坚挺在 3000 美元区域,而 gas 价格平均上涨了 50-70 Gwei,每笔交易的 gas 费用越来越贵,一次简单的转账费用约为 4 美元。

有一种解决gas问题的方法,就是把这个计算放到链下,让服务器来做。

许多在线 ECDSA 教程都涉及到数学的使用,我们所有开发人员都同意的关于 s、r、v 的东西很无聊,而且很难在没有错误的情况下实现。因此,在本文中,我们将使用 OpenZeppelin 和 Ethers.js 编写的合约中的内置函数来构建此功能。

实际例子

在这个项目中,我们将使用 ECDSA 的常见用例、将 NFT 项目列入白名单来演示这种方法,并包含代码片段来帮助我们入门。

这个项目是用 JavaScript 和 Solidity 编写的。

1. 设置

为了准备 ECDSA,我们应该创建一个新钱包,并将其仅作为签名者用于该项目。请勿将此钱包用于任何其他目的,仅用于在此项目中签署消息。

创建钱包后,保存其私钥以备后用。

2. 链下签名

2.1 首先,我们需要运行以下命令来安装 Ether.js:

npm run ethers

然后通过以下方式导入项目:

import ethers from ethers

2.2 然后我们可以使用该库创建一个新的钱包来初始化签名者实例:

const signer = new ethers.Wallet("0x" + "");

如果直接从 Metamask 导出,请记住在私钥的前缀中添加 0x。

2.3 将消息打包在一起,我们可以尝试打包地址和nonce进行白名单:

let message = ethers.utils.solidityPack(["address", "uint256"], ["0xabc", "0"]);

这是为了在下一节中将消息连接在一起以进行散列。ether.js 支持广泛的变量,包括字符串和数组,如`uint256[]:

2.4 使用 keccak256 对消息进行哈希处理,并使用签名者钱包对其进行签名:

message = ethers.utils.solidityKeccak256(["bytes"], [message]);
const signature = await 
signer.signMessage(ethers.utils.arrayify(message));

该签名是使用签名者的私钥对消息进行签名的签名。

我们可以将此签名连同经过验证的参数一起传递给区块链,以确保参数有效。

整个代码片段:

const signer = new ethers.Wallet("0x" + "abc"); // replace abc with your private key
let message = ethers.utils.solidityPack(["address", "uint256"], ["0xabc", "0"]);
message = ethers.utils.solidityKeccak256(["bytes"], [message]);
const signature = await signer.signMessage(ethers.utils.arrayify(message));

3. 链上验证

3.1 为了验证链上签名,我们可以使用 OpenZeppelin 编写的合约 EDCSA。要使用它,您需要在本地安装 Openzepplin 或在 Remix 中使用它:

npm install @openzeppelin/contracts

3.2 使用 setter 为链上签名者设置存储:

address signer;function setSigner(address _signer) external { 
    signer = _signer;
}

3.3 然后用 abi.encodePacked 将值打包在一起,用 keccack256 散列:

bytes32 hash = keccak256(abi.encodePacked(msg.sender, nonce));

3.4 将签名转换为以太坊签名的消息:

bytes32 message = ECDSA.toEthSignedMessageHash(hash);

3.5 从签名中恢复签名者地址:

address receivedAddress = ECDSA。恢复(消息、签名);

3.6 检查消息的签名者是否与链上签名者存储库匹配,只有匹配时才批准:

require(receivedAddress != address(0) && receivedAddress == signer);

整个代码片段是:

import "@openzeppelin/contracts/utils/cryptography/ECDSA.sol";
...
address signer;
function setSigner(address _signer) external {
      signer = _signer;
}
...
function verifySignature(uint256 nonce, bytes calldata signature) public {
      bytes32 hash = keccak256(abi.encodePacked(msg.sender, nonce));
      bytes32 message = ECDSA.toEthSignedMessageHash(hash);
      address receivedAddress = ECDSA.recover(message, signature);
      require(receivedAddress != address(0) && receivedAddress == signer);
}

综上所述

现在我们已经学会了如何尽可能简单地使用 ECDSA,而不需要任何复杂的数学。但是,将计算置于链下需要权衡取舍,这超出了本文的范围。

来源:

关于

ChinaDeFi - ChinaDeFi.com 是一家研究驱动的 DeFi 创新机构开发一个区块链app多少钱,我们也是区块链开发团队。每天从全球500多个优质信息源的近900条内容中,寻找更深入思考、更系统的内容,以最快的速度同步到中国市场提供决策辅助材料。