Солидность Вычитания msg.значение или адрес(это).баланс

#reactjs #ethereum #solidity

Вопрос:

Я упрощаю это, но давайте предположим, что у меня есть платная функция под названием myFunction. После совершения транзакции (через React) Я хочу обновить свойство number структуры в контракте под названием MyStruct, используя базовую математику. Допустим, я хочу рассчитать его как 1 минус остаток по новому контракту.

 function myFunction() public payable {
  myStruct.number = 1 - address(this).balance;
}
 

Если я отправлю 0,01 ETH в эту функцию по новому контракту с балансом 0, номер структуры отобразится как 15792089237316195423570985008687907853269984665640564039457574007913129639937

Я ни за что на свете не могу понять, почему. Если я буду заниматься элементарной математикой без использования адреса(этого).баланс или msg.значение, тогда все в порядке и отображается правильно. Но каждый раз, когда я пытаюсь привлечь кого-либо из них, я получаю эти дикие результаты.

Помощь была бы очень признательна!

Ответ №1:

Я думаю myStruct.number , это uint А. объявляя uint, вы объявляете 256-разрядное значение int, которое принимает только положительные числа.

когда вы отправляете 0,01 ETH на баланс контракта, вы фактически получаете 10000000000000000 WEI (вы должны помнить, что 1 ETH формируется 1e18 WEI).

зовущий

 address(this).balance
 

в результате вы получите 10000000000000000, поэтому вы пытаетесь сделать

1 — 10000000000000000

и поскольку uint принимает только положительные числа, вы получаете этот результат.

Я предлагаю вам использовать библиотеку SafeMath, чтобы избежать этих ошибок https://docs.openzeppelin.com/contracts/2.x/api/math

Комментарии:

1. Спасибо вам за объяснение. Было бы проще, если бы я каким — то образом перевел баланс в ETH в Solidity, чтобы сделать эту математику 1-0,01 = 0,99, что я и ожидал, что буду делать? Не уверены, что вы можете легко конвертировать между Wei и эфиром? Я знаю, что могу реагировать, но это не очень помогает, так как это происходит в рамках контрактного кодекса.

2. @JimParsnip посмотри на это docs.soliditylang.org/en/develop/… на solidity все основано на WEI, поэтому вы можете преобразовать 1 в 1e18, добавив «эфир» рядом с «1».

Ответ №2:

Эй, ты должен использовать библиотеку SafeMath. Солидность работает с переменными иначе, чем в других языках.

 using SafeMath for uint256;
 

Также импортируйте SafeMath.sol из библиотеки Openzeppelin, после чего вы сможете продолжить с гораздо более точными результатами.