# Public Key
Recall that an address is the last 20 bytes of the keccak-256 hash of the address’s public key.
To complete this challenge, find the public key for the owner's account.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.11;
contract PublicKey {
bool public isComplete;
address public owner;
constructor(address _owner) {
owner = _owner;
}
function authenticate(bytes memory publicKey) public {
// Compute the publicKey's keccak256 hash.
uint256 publicKeyHash = uint256(keccak256(publicKey));
// Check the lower 20 bytes of the hash.
require(address(uint160(publicKeyHash)) == owner, "public key does not match");
isComplete = true;
}
}
TIP
On this web page, we have loaded the ethers (opens new window) library.
The ethers library has a method called ethers.utils.recoverPublicKey
(opens new window)
which takes a digest, signature
.
The signature
object should contain:
{
r: "0xdead...",
s: "0xbeef...",
v: "0x1"
}
and the digest
should be a keccak256 digest signed by the private-key of the
public-key we want to recover.
How can we get a digest signed by the owner and a corresponding signature?
Hint:
DETAILS
In the geth console, you can get a full transaction with its signature with:
eth.getRawTransaction("0x...") > "0x02..."
And in ethers, you can get just the RLP-encoded data of a transaction before signing with:
tx = ethers.utils.parseTransaction("0x02...") ethers.utils.serializeTransaction(tx) > "0x02f89082053981fb847735940084..."
Once you have a public key, you can verify what address it resolves to with:
ethers.utils.computeAddress("...PUBLIC_KEY") > "0x015aA9fC32E280A70B639ECdC6203B917d9bfCdf"