В чем разница между транзакцией и звонком?

В чем разница между транзакцией и звонком? В некоторых интерфейсах я могу взаимодействовать с контрактами через звонки или через транзакции. В чем разница между ними и могут ли контракты также выполнять транзакции и вызовы?

ПРИМЕЧАНИЕ , чтобы избежать путаницы: callв этом вопросе нет ни опкода EVM CALL , ни Solidity <address>.call() , которые вносят изменения в состояния контракта, а Web3.js API web3.eth.call(), который не вносит никаких изменений в состояние.

Ответы (2)

Вызов

Вызов — это локальный вызов контрактной функции, которая ничего не транслирует и не публикует в блокчейне.

Это операция только для чтения, и она не будет потреблять эфир. Он имитирует то, что должно произойти в транзакции, но отбрасывает все изменения состояния, когда это делается.

Это синхронно, и возвращаемое значение функции контракта возвращается немедленно.

Его API web3.js называется web3.eth.call и используется для функций Solidity view, pure,constant .

Его базовый JSON-RPC — eth_call.

Сделка

Транзакция транслируется в сеть, обрабатывается майнерами и, если она действительна, публикуется в блокчейне.

Это операция записи, которая повлияет на другие учетные записи, обновит состояние блокчейна и потребит эфир (если только майнер не примет его с нулевой ценой газа).

Он асинхронный, потому что возможно, что ни один майнер не включит транзакцию в блок (например, цена газа для транзакции может быть слишком низкой). Поскольку это асинхронно, немедленным возвращаемым значением транзакции всегда является хэш транзакции. Чтобы получить «возвращаемое значение» транзакции в функцию, необходимо использовать события (если только это не Case4, обсуждаемый ниже). Пример для ethers.js: прослушивание событий контракта с помощью ethers.js?

Его API web3.js называется web3.eth.sendTransaction и используется, если функция Solidity не отмечена constant.

Его базовый JSON-RPC — eth_sendTransaction.

sendTransaction будет использоваться, когда потребуется глагол, так как он понятнее, чем просто транзакция.

Рекомендация сначала позвонить, а затем отправить транзакцию

Поскольку sendTransaction стоит эфира, рекомендуется « прощупать почву», выполнив сначала вызов перед sendTransaction. Это бесплатный способ отладки и оценки возможных проблем с sendTransaction, например, если возникнет исключение Out of Gas.

Этот «пробный прогон» обычно работает хорошо, но в некоторых случаях имейте в виду, что вызов является оценочным, например, функция контракта, которая возвращает предыдущий хэш блока, будет возвращать разные результаты в зависимости от того, когда был выполнен вызов и когда транзакция была завершена. собственно добыто.

Наконец, обратите внимание, что даже если вызов не потребляет никакого эфира, иногда может быть необходимо указать фактическое количество газа для вызова : газ по умолчанию для вызова в таких клиентах, как Geth, все еще может быть недостаточным и все еще может привести к Out газа.

Случай 4: могут ли контракты создавать транзакции?

Существует 4 случая вызова контрактной функции.

Вот 4 случая, и первые 3 были рассмотрены выше :

  1. прямой вызов контрактной функции, созданный вызовом

  2. прямой вызов функции контракта, созданный с помощью sendTransaction

  3. контракт вызов функции контракта, созданный вызовом

4. вызов контракта функции контракта, созданный с помощью sendTransaction

Хотя Case4 звучит так, будто контракт может «также выполнять транзакции», поскольку он находится внутри транзакции, определение транзакции — это данные, подписанные внешним субъектом. Таким образом, Case4 не является транзакцией.

Из желтой газеты :

Транзакция : часть данных, подписанная внешним субъектом. Он представляет либо сообщение, либо новый автономный объект. Транзакции записываются в каждый блок блокчейна.

Ранее выше было указано, что события должны использоваться для получения возвращаемого значения функции контракта, созданной с помощью sendTransaction. Это относится и верно для Case2. В случае Case4 контракт напрямую получает возвращаемое значение функции контракта и может его использовать. Вот как это написано жирным шрифтом в «Желтой книге»:

Message Call : акт передачи сообщения от одного Пользователя к другому. Если целевая учетная запись связана с непустым кодом EVM, то виртуальная машина будет запущена с состоянием указанного объекта и обработанным сообщением. Если отправитель сообщения является автономным объектом, то вызов передает любые данные, возвращенные из операции виртуальной машины.

Из этих определений из «Желтой книги» видно, что Case4 — это Message Call внутри транзакции (таким образом, изменяется состояние), нет вложенности транзакций и что единица активности в блокчейне Ethereum находится внутри одной транзакции. который может содержать несколько вызовов сообщений .

Обновление: поскольку вызов функции может быть неоднозначным (это eth_call или eth_sendTransaction?), есть предложение для eth_simulateTransaction .

Я бы просто добавил некоторые окончательные разъяснения / выводы о потенциальной двусмысленности между вызовом web3 () и вызовом сообщения () между двумя контрактами? Синтаксис будет выглядеть очень похожим, и, таким образом, можно увидеть, что если контракт вызывает другой контракт, он работает аналогично вызову web3, что не так. Он не имитирует его в этой среде. Это приводит к изменению состояния.
Спасибо, проголосовал и смог настроить самый последний абзац.
Я назначаю этот ответ тегом вики для вызова контракта. Не стесняйтесь просматривать и вносить свой вклад в вики и отрывок .
Изменится ли что-нибудь из этого с появлением «Абстракции» в Метрополисе?
Я вижу сообщение о вызове функции представления в Remix, в котором говорится: «(Стоимость применяется только при вызове по контракту)». У меня есть функция проверки баланса адресов, которая вызывает внешний токен-контракт с помощью balanceOfметода Erc20. Так что в этом случае токен-контракт фактически вызывается моим смарт-контрактом. Будет ли это стоить газа, как указано, даже если весь процесс доступен только для чтения?
@GViz Транзакция, которая вызывает функцию viewили pure, никогда не потребует оплаты газа. Вы правы, что простой способ сказать, что весь процесс, который доступен только для чтения, не будет стоить газа. Обратите внимание, что gas по-прежнему используется viewфункциями .
@eth отличный момент, газ используется временно, но не оплачивается, при запуске функций просмотра, чтобы предотвратить выполнение произвольно больших подпрограмм (например, бесконечных циклов).
атомарная callоперация? Другими словами, если происходит callсбой где-то посередине, происходит ли откат?
@user1870400 user1870400 eth_callничего не сохраняет: «откат» — это поведение по умолчанию.
@eth, когда обновления состояния записываются (сохраняются) в хранилище? насколько я понимаю, читая кодовую базу, похоже, что обновления состояния записываются в хранилище, когда блок добавляется в блокчейн, до тех пор, пока не будет занята вся память. это правильно?

Разница между вызовом и транзакцией заключается в следующем:

  • транзакции создаются вашим клиентом, подписываются и транслируются в сеть. В конечном итоге они изменят состояние блокчейна, например, манипулируя балансами или значениями в смарт-контрактах.

  • вызовы — это транзакции, выполняемые локально на локальном компьютере пользователя, который самостоятельно оценивает результат. Они доступны только для чтения и работают быстро. Они никак не могут изменить блокчейн, потому что никогда не отправляются в сеть. Некоторые примеры "только для чтения/пробный запуск/практика".

Звонки полезны для отладки смарт-контрактов, поскольку они не требуют комиссий за транзакции или газа.

Искал какое-то время; это, наконец, объяснило это для меня (я просто добавил constantмодификатор в свою функцию, и это сработало)