1

I wrote a small contract that is supposed to generate an address from a given publicKey.

pragma solidity ^0.8.0;

contract GenerateAddress {
    bytes public publicKey = "6d7bac197da6e91f506db699a1844efc93b9bf5508bacb6870a98fc2137c4330741f94af61aa635a44f9059ff2082737d43cfb376124ae8772250b85f656aa1d";

    function generateAddress() public view returns (address addr) {
        bytes32 publicKeyHash = keccak256(publicKey);
        addr = address(bytes20(publicKeyHash));
        return addr;
    }

}

The public key in question was generated from this page: Ethereum Address Generator (Been using it for years to get some test addresses etc.)

Generate ETH address

So I hard-coded the publicKey I got from there to test my simple contract.

However the address I got is 0x70191eCc889463533ea48C3A666e7eE0692a0087 while the Ethereum Address Generator returns 0xdf92c554c0078eec90937d7a5944976ef31d602c as valid address (For the same public key)

Basically, I get different address for identical publicKey and I would like to understand what am I doing wrong.

2 Answers 2

1

addr = address(bytes20(publicKeyHash)); is taking the first 20 bytes - for an address you need the last 20

also, solidity is taking publicKey as a string and converting it to bytes (using utf-8 encoding). you need to save it as a hexadecimal number (or convert it to bytes first, then hardcode it)

Edit: the answer here explains it in full - Compute address of public key string in Solidity

3

In your smart contract there are some issues:

  • When you're calculating the account hash you must pass your public key like hexedecimal value. In your case, you're executing this operation with the literal value.
  • For calculating account address, you must take the 20 bytes == 40 characters from the ending of hash public key value (in your case publicKeyHash). With this statement, address(bytes20(publicKeyHash)); you're taking 40 characters from the variable beginning.

To fix this issues, I modified your smart contract in this way and put some notes:

pragma solidity ^0.8.0;

contract GenerateAddress {
    // NOTE: With hex before the value, Solidity compiler takes this value in hexadecimal value
    bytes public publicKey = hex"6d7bac197da6e91f506db699a1844efc93b9bf5508bacb6870a98fc2137c4330741f94af61aa635a44f9059ff2082737d43cfb376124ae8772250b85f656aa1d";

    function generateAddress() public view returns (address addr) {
        bytes32 publicKeyHash = keccak256(publicKey);
        // NOTE: I take the last 40 characters from the end of publicKeyHash variable 
        //       and convert them into address.
        addr = address(uint160(uint256(publicKeyHash)));
        return addr;
    }
}
3
  • Thanks, I already solved this issue, but I got caught up on something else, so I forgot to answer to accept an answer. Your explanation is good, but some details/numbers are off, so I will edit your answer to fix it. Hope that is ok with you.
    – Sky
    Commented Jan 11, 2023 at 13:42
  • 1
    Sure, we should always improve answers to make them helpful to other users that they have the same issue or doubt Commented Jan 11, 2023 at 15:10
  • hex"" != bytes("")
    – liquan.eth
    Commented Apr 17, 2023 at 13:36

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.