0

I'm having some trouble converting negative numbers in the log data of an Ethereum transaction. In this transaction, log index 192, topic 3 is listed as "0xffffffffffffffffffffffffffffffffffffffffffffffdb9a1221071741566a". Etherscan screenshot

Ethtx converts that hex value into a decimal of -671.4275583814931. Ethtx screenshot

I'm struggling to replicate the conversion of the hexadecimal value to a negative decimal value. So far:

  1. I can't find any functions in the Ethers.js and Web3.js libraries that convert to the right amount.
  2. Even just using an online tool, the hex value yields an output of 115792089237316195423570985008687907853269984665640564038786156449531636569706, which isn't correct.

Are there any libraries that would convert this hex value into the correct negative decimal?

3
  • and why aren't you using abi.Unpack() ? it does all this job for you
    – Nulik
    Feb 5, 2021 at 15:45
  • @Nulik which library is that?
    – kaciloy
    Feb 5, 2021 at 18:56
  • it is not a library, but a standard way to decode objects in ethereum, every language has its own Unpack , here is golangs: ethereum.stackexchange.com/questions/29809/…
    – Nulik
    Feb 5, 2021 at 19:24

2 Answers 2

1

The large number you got from the hex conversion is right. However, you have to account for integer overflow in solidity.

The original value in the transaction log is of type int256. If you cast 115792089237316195423570985008687907853269984665640564038786156449531636569706 into an int256 type you get -671427558381493070230. Then using 18 decimals the result is -671.427558381493070230.

In Python you can get an int256 with the following code:

large_number = 115792089237316195423570985008687907853269984665640564038786156449531636569706

size = 256
sign = 1 << size - 1

number_int256  = (large_number & sign-1) - (large_number & sign)
0

try this not sure it can help you

function twosComplementHexToDecimal(hexValue) {
  // Check if the hex value starts with '0xf'
  if (!hexValue.startsWith('0xf')) {
    return Number(hexValue);
  }

  // Convert hex to binary
  const binaryValue = BigInt(hexValue).toString(2);

  // Apply two's complement
  const flippedBinary = binaryValue
    .split('')
    .map(bit => (bit === '0' ? '1' : '0'))
    .join('');
  const twoComplementBinary = (BigInt(`0b${flippedBinary}`) + BigInt(1)).toString(2);

  // Convert binary to decimal
  const decimalValue = parseInt(twoComplementBinary, 2);

  return decimalValue;
}

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.