主页 > imtoken手机钱包 > 开发一个区块链app多少钱 使用 OpenZeppelin 和以太币
开发一个区块链app多少钱 使用 OpenZeppelin 和以太币
使用 OpenZeppelin 和 Ethers.js 在 Solidity 中使用 ECDSA 验证链下结果和白名单
介绍
作为该领域的区块链开发者或爱好者开发一个区块链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条内容中,寻找更深入思考、更系统的内容,以最快的速度同步到中国市场提供决策辅助材料。