MekaVerse NFT 智能合约正在使用 ECDSA,但我不明白它是如何工作的
MekaVerse NFT smart contract is using ECDSA, but I don't understand how it works
在 MekaVerse 的智能合约中,我可以看到这些行来启用白名单,但我不了解其背后的理论以及如何使用它。
function mint(uint256[] memory _tokensId, uint256 _timestamp, bytes memory _signature) public payable saleIsOpen {
uint256 total = totalToken();
require(_tokensId.length <= 2, "Max limit");
require(total + _tokensId.length <= MAX_ELEMENTS, "Max limit");
require(msg.value >= price(_tokensId.length), "Value below price");
address wallet = _msgSender();
address signerOwner = signatureWallet(wallet,_tokensId,_timestamp,_signature);
require(signerOwner == owner(), "Not authorized to mint");
require(block.timestamp >= _timestamp - 30, "Out of time");
for(uint8 i = 0; i < _tokensId.length; i++){
require(rawOwnerOf(_tokensId[i]) == address(0) && _tokensId[i] > 0 && _tokensId[i] <= MAX_ELEMENTS, "Token already minted");
_mintAnElement(wallet, _tokensId[i]);
}
}
function signatureWallet(address wallet, uint256[] memory _tokensId, uint256 _timestamp, bytes memory _signature) public view returns (address){
return ECDSA.recover(keccak256(abi.encode(wallet, _tokensId, _timestamp)), _signature);
}
我不明白的有趣部分在这里:
address signerOwner = signatureWallet(wallet,_tokensId,_timestamp,_signature);
require(signerOwner == owner(), "Not authorized to mint")
这里:
function signatureWallet(address wallet, uint256[] memory _tokensId, uint256 _timestamp, bytes memory _signature) public view returns (address){
return ECDSA.recover(keccak256(abi.encode(wallet, _tokensId, _timestamp)), _signature);
}
感谢您的帮助,
本
MekaVerse contract uses the OpenZeppelin ECDSA 实现,特别是它的 recover()
函数。 ECDSA 代表“椭圆曲线数字签名算法”,基本上,它允许使用私钥签署消息并在不提供私钥的情况下检查签名的有效性。
recover()
函数在这种情况下采用 2 个参数:bytes32
(32 字节的数组)hash
签名消息,以及 bytes
(动态长度字节数组)signature
。然后它根据 ECDSA 验证 hash
和 signature
是否匹配。如果是,它 returns 签名者地址。如果验证失败,它 returns 零地址 (0x0
).
请注意,签名是使用私钥对消息进行签名的结果 - 但它不是私钥。
您可以在 sign() function. If you're interested in the ECDSA (or cryptography in general) in more depth, the wiki page 的 web3 文档中了解有关签名消息的更多信息,其中显示了一些基本信息和指向其他来源的链接。
在 MekaVerse 的智能合约中,我可以看到这些行来启用白名单,但我不了解其背后的理论以及如何使用它。
function mint(uint256[] memory _tokensId, uint256 _timestamp, bytes memory _signature) public payable saleIsOpen {
uint256 total = totalToken();
require(_tokensId.length <= 2, "Max limit");
require(total + _tokensId.length <= MAX_ELEMENTS, "Max limit");
require(msg.value >= price(_tokensId.length), "Value below price");
address wallet = _msgSender();
address signerOwner = signatureWallet(wallet,_tokensId,_timestamp,_signature);
require(signerOwner == owner(), "Not authorized to mint");
require(block.timestamp >= _timestamp - 30, "Out of time");
for(uint8 i = 0; i < _tokensId.length; i++){
require(rawOwnerOf(_tokensId[i]) == address(0) && _tokensId[i] > 0 && _tokensId[i] <= MAX_ELEMENTS, "Token already minted");
_mintAnElement(wallet, _tokensId[i]);
}
}
function signatureWallet(address wallet, uint256[] memory _tokensId, uint256 _timestamp, bytes memory _signature) public view returns (address){
return ECDSA.recover(keccak256(abi.encode(wallet, _tokensId, _timestamp)), _signature);
}
我不明白的有趣部分在这里:
address signerOwner = signatureWallet(wallet,_tokensId,_timestamp,_signature);
require(signerOwner == owner(), "Not authorized to mint")
这里:
function signatureWallet(address wallet, uint256[] memory _tokensId, uint256 _timestamp, bytes memory _signature) public view returns (address){
return ECDSA.recover(keccak256(abi.encode(wallet, _tokensId, _timestamp)), _signature);
}
感谢您的帮助, 本
MekaVerse contract uses the OpenZeppelin ECDSA 实现,特别是它的 recover()
函数。 ECDSA 代表“椭圆曲线数字签名算法”,基本上,它允许使用私钥签署消息并在不提供私钥的情况下检查签名的有效性。
recover()
函数在这种情况下采用 2 个参数:bytes32
(32 字节的数组)hash
签名消息,以及 bytes
(动态长度字节数组)signature
。然后它根据 ECDSA 验证 hash
和 signature
是否匹配。如果是,它 returns 签名者地址。如果验证失败,它 returns 零地址 (0x0
).
请注意,签名是使用私钥对消息进行签名的结果 - 但它不是私钥。
您可以在 sign() function. If you're interested in the ECDSA (or cryptography in general) in more depth, the wiki page 的 web3 文档中了解有关签名消息的更多信息,其中显示了一些基本信息和指向其他来源的链接。