如何正确使用ECDSA.sol模块?
how to use the ECDSA.sol module correctly?
我有这个使用 ECDSA 库的合约。
import "./ECDSA.sol";
struct Signature {
uint8 v;
bytes32 r;
bytes32 s;
}
function make(Signature memory sign) public returns(bool)
我试图理解在这种情况下我必须使用的参数。我能看到它是一个元组类型值,但我无法弄清楚 v、r、s 是什么样子。从我的地址哪里可以得到这些值?
v
、r
和 s
参数是使用私钥对消息进行签名的结果。签名有65个字节,分为3个部分:
65 byte array (of type bytes
in Solidity) arranged the following way: [[v (1)], [r (32)], [s (32)]].
来源:OpenZeppelin
链下签名(因为您使用的是私钥)。
注意评论中的地址,我们稍后会在链上进行验证。
const signature = await web3.eth.accounts.sign(
'Hello world',
// below is private key to the address `0x0647EcF0D64F65AdA7991A44cF5E7361fd131643`
'02ed07b6d5f2e29907962d2bfde8f46f03c46e79d5f2ded0b1e0c27fa82f1384'
);
console.log(signature);
输出
{
message: 'Hello world',
messageHash: '0x8144a6fa26be252b86456491fbcd43c1de7e022241845ffea1c3df066f7cfede',
v: '0x1c',
r: '0x285e6fbb504b57dca3ceacc851a7bfa37743c79b5c53fb184f4cc0b10ebff6ad',
s: '0x245f558fa13540029f0ee2dc0bd73264cf04f28ba9c2520ad63ddb1f2e7e9b24',
signature: '0x285e6fbb504b57dca3ceacc851a7bfa37743c79b5c53fb184f4cc0b10ebff6ad245f558fa13540029f0ee2dc0bd73264cf04f28ba9c2520ad63ddb1f2e7e9b241c'
}
注意v
是signature
的最后一个字节,r
是前半部分,s
是后半部分(不包括最后一个字节)。
链上验证
pragma solidity ^0.8;
import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/cryptography/ECDSA.sol";
contract MyContract {
function foo() external pure returns (bool) {
address recovered = ECDSA.recover(
0x8144a6fa26be252b86456491fbcd43c1de7e022241845ffea1c3df066f7cfede, // messageHash
0x1c, // v
0x285e6fbb504b57dca3ceacc851a7bfa37743c79b5c53fb184f4cc0b10ebff6ad, // r
0x245f558fa13540029f0ee2dc0bd73264cf04f28ba9c2520ad63ddb1f2e7e9b24 // s
);
return recovered == address(0x0647EcF0D64F65AdA7991A44cF5E7361fd131643);
}
}
我有这个使用 ECDSA 库的合约。
import "./ECDSA.sol";
struct Signature {
uint8 v;
bytes32 r;
bytes32 s;
}
function make(Signature memory sign) public returns(bool)
我试图理解在这种情况下我必须使用的参数。我能看到它是一个元组类型值,但我无法弄清楚 v、r、s 是什么样子。从我的地址哪里可以得到这些值?
v
、r
和 s
参数是使用私钥对消息进行签名的结果。签名有65个字节,分为3个部分:
65 byte array (of type
bytes
in Solidity) arranged the following way: [[v (1)], [r (32)], [s (32)]].
来源:OpenZeppelin
链下签名(因为您使用的是私钥)。
注意评论中的地址,我们稍后会在链上进行验证。
const signature = await web3.eth.accounts.sign(
'Hello world',
// below is private key to the address `0x0647EcF0D64F65AdA7991A44cF5E7361fd131643`
'02ed07b6d5f2e29907962d2bfde8f46f03c46e79d5f2ded0b1e0c27fa82f1384'
);
console.log(signature);
输出
{
message: 'Hello world',
messageHash: '0x8144a6fa26be252b86456491fbcd43c1de7e022241845ffea1c3df066f7cfede',
v: '0x1c',
r: '0x285e6fbb504b57dca3ceacc851a7bfa37743c79b5c53fb184f4cc0b10ebff6ad',
s: '0x245f558fa13540029f0ee2dc0bd73264cf04f28ba9c2520ad63ddb1f2e7e9b24',
signature: '0x285e6fbb504b57dca3ceacc851a7bfa37743c79b5c53fb184f4cc0b10ebff6ad245f558fa13540029f0ee2dc0bd73264cf04f28ba9c2520ad63ddb1f2e7e9b241c'
}
注意v
是signature
的最后一个字节,r
是前半部分,s
是后半部分(不包括最后一个字节)。
链上验证
pragma solidity ^0.8;
import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/cryptography/ECDSA.sol";
contract MyContract {
function foo() external pure returns (bool) {
address recovered = ECDSA.recover(
0x8144a6fa26be252b86456491fbcd43c1de7e022241845ffea1c3df066f7cfede, // messageHash
0x1c, // v
0x285e6fbb504b57dca3ceacc851a7bfa37743c79b5c53fb184f4cc0b10ebff6ad, // r
0x245f558fa13540029f0ee2dc0bd73264cf04f28ba9c2520ad63ddb1f2e7e9b24 // s
);
return recovered == address(0x0647EcF0D64F65AdA7991A44cF5E7361fd131643);
}
}