How to generate 32 bytes number from address and string

// SPDX-License-Identifier: MIT
pragma solidity 0.8.13;

contract Sample {
	function get() external pure returns(bytes12, bytes32) {
		string memory str = '1';
		address addr = 0x63cDDcF737f3AD13492e8fa59C2D923C9cFAEf14;
		bytes12 temp = bytes12(keccak256(abi.encodePacked(str)));
		bytes32 result = bytes32(abi.encodePacked(addr, temp));
		return (temp, result);
	}
}

In the above contract, I am getting 12 bytes from the keccak value of string '1'. Then packing 20 bytes address addr and previous 12 bytes. getting the following output,


truffle(develop)> await contract.get()
Result {
  '0': '0xc89efdaa54c0f20c7adf6128',
  '1': '0x63cddcf737f3ad13492e8fa59c2d923c9cfaef14310000000000000000000000'
}

I have expected the following output (20 bytes address + 12 bytes keccak str),

{
  '0': '0xc89efdaa54c0f20c7adf6128',
  '1': '0x63cddcf737f3ad13492e8fa59c2d923c9cfaef14c89efdaa54c0f20c7adf6128'
}

What is wrong in the above code.

I think you can just use the bytes.contact to achieve your target, such as:

function get() external pure returns(bytes12, bytes32) {
		string memory str = '1';
		address addr = 0x63cDDcF737f3AD13492e8fa59C2D923C9cFAEf14;
		bytes12 temp = bytes12(keccak256(abi.encodePacked(str)));

        bytes memory result = bytes.concat(bytes20(uint160(addr)),temp);
		return (temp, bytes32(result));
	}

@Skyge Thanks. but I want to understand what is wrong in my logic.

On remix and foundry , I get the same output as later.

  • 0:bytes12: 0xc89efdaa54c0f20c7adf6128

  • 1:bytes32: 0x63cddcf737f3ad13492e8fa59c2d923c9cfaef14c89efdaa54c0f20c7adf6128

I tried on the Remix, and get the same result as Jagadish_K said.