問題一覧に戻る
中級実践的な機能
問題72: Ecrecover
Solidityのecrecoverを学習します - 署名から署名者アドレスを復元します。EcrecoverはECDSA署名検証のための組み込み関数で、パスワードを保存せずに認証を行うのに不可欠です。メッセージハッシュと署名コンポーネント(v、r、s)を取り、署名者のアドレスを返します。これによりメタトランザクション、ガスレストランザクション、オフチェーン認証が可能になります。Ethereum署名メッセージプレフィックスは署名リプレイ攻撃を防ぎます。ecrecoverの理解はDeFiプロトコルでの安全な認証実装に重要です。
pragma solidity ^0.8.0;
contract SignatureVerify {
function verifySignature(
bytes32 messageHash,
uint8 v,
bytes32 r,
bytes32 s
) public pure returns (address) {
// 署名から署名者を復元
return (messageHash, v, r, s);
}
function checkSigner(
string memory message,
bytes memory signature,
address expectedSigner
) public pure returns (bool) {
// メッセージハッシュを作成
bytes32 hash = keccak256(abi.encodePacked(message));
// Ethereumプレフィックスを追加
bytes32 ethHash = keccak256(
abi.encodePacked("\x19Ethereum Signed Message:\n32", )
);
(uint8 v, bytes32 r, bytes32 s) = splitSignature(signature);
// 署名者アドレスを検証
return (ethHash, v, r, s) == expectedSigner;
}
function splitSignature(bytes memory sig)
private pure returns (uint8, bytes32, bytes32) {
require(sig.length == 65, "Invalid signature");
bytes32 r;
bytes32 s;
uint8 v;
assembly {
r := mload(add(sig, 32))
s := mload(add(sig, 64))
v := byte(0, mload(add(sig, 96)))
}
return (v, r, s);
}
}