I have to bitpack two uint128 values into a uint256, then get back the two original uint128s.

To encode the values I'm using:

function encode256(uint128 a, uint128 b) pure public returns (uint256) {
    return uint256(bytes32(abi.encodePacked(a, b)));

For: a=1, b=16 we get a=0x00000000000000000000000000000001 b=0x00000000000000000000000000000010 which leads to 0x0000000000000000000000000000000100000000000000000000000000000010 which cast to uint256 is 340282366920938463463374607431768211472.

The issue is decoding it back to the originals. To unravel the encoded uint256 back to the two uint128 I wrote the following code:

let hex = numberToHex("340282366920938463463374607431768211472") //1 /16
hex = padRight(hex, 64)
hex = hex.replace('0x','') 
const half = Math.ceil(hex.length / 2);    
const firstHalf = hex.slice(0, half)
const secondHalf = hex.slice(half)

But the two numbers coming out are a=10000000000000000000000000000001, b=00000000000000000000000000000000.

I'm not sure how the encoding is happening and wondering where I am going wrong in the encoding or decoding process?

1 Answer 1


You are padding right. You need to actually pad left:

hex = padLeft(hex, 64)

If you convert 340282366920938463463374607431768211472 to hex, it would be: 100000000000000000000000000000010. If we left pad it, it will be: 0000000000000000000000000000000100000000000000000000000000000010.

When slicing the first part, it will be: 00000000000000000000000000000001. When slicing the second part, it will be: 00000000000000000000000000000010.

Which is what you want.

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.