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?

kaciloy
  • 1
  • 1
  • and why aren't you using abi.Unpack() ? it does all this job for you – Nulik Feb 05 '21 at 15:45
  • @Nulik which library is that? – kaciloy Feb 05 '21 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: https://ethereum.stackexchange.com/questions/29809/how-to-decode-input-data-with-abi-using-golang – Nulik Feb 05 '21 at 19:24

2 Answers2

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)

I.p37.G047
  • 11
  • 1
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; }

0xit
  • 1