В чем разница между транзакцией и звонком? В некоторых интерфейсах я могу взаимодействовать с контрактами через звонки или через транзакции. В чем разница между ними и могут ли контракты также выполнять транзакции и вызовы?
Вызов — это локальный вызов контрактной функции, которая ничего не транслирует и не публикует в блокчейне.
Это операция только для чтения, и она не будет потреблять эфир. Он имитирует то, что должно произойти в транзакции, но отбрасывает все изменения состояния, когда это делается.
Это синхронно, и возвращаемое значение функции контракта возвращается немедленно.
Его 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 случая, и первые 3 были рассмотрены выше :
прямой вызов контрактной функции, созданный вызовом
прямой вызов функции контракта, созданный с помощью sendTransaction
контракт вызов функции контракта, созданный вызовом
4. вызов контракта функции контракта, созданный с помощью sendTransaction
Хотя Case4 звучит так, будто контракт может «также выполнять транзакции», поскольку он находится внутри транзакции, определение транзакции — это данные, подписанные внешним субъектом. Таким образом, Case4 не является транзакцией.
Из желтой газеты :
Транзакция : часть данных, подписанная внешним субъектом. Он представляет либо сообщение, либо новый автономный объект. Транзакции записываются в каждый блок блокчейна.
Ранее выше было указано, что события должны использоваться для получения возвращаемого значения функции контракта, созданной с помощью sendTransaction. Это относится и верно для Case2. В случае Case4 контракт напрямую получает возвращаемое значение функции контракта и может его использовать. Вот как это написано жирным шрифтом в «Желтой книге»:
Message Call : акт передачи сообщения от одного Пользователя к другому. Если целевая учетная запись связана с непустым кодом EVM, то виртуальная машина будет запущена с состоянием указанного объекта и обработанным сообщением. Если отправитель сообщения является автономным объектом, то вызов передает любые данные, возвращенные из операции виртуальной машины.
Из этих определений из «Желтой книги» видно, что Case4 — это Message Call внутри транзакции (таким образом, изменяется состояние), нет вложенности транзакций и что единица активности в блокчейне Ethereum находится внутри одной транзакции. который может содержать несколько вызовов сообщений .
Обновление: поскольку вызов функции может быть неоднозначным (это eth_call или eth_sendTransaction?), есть предложение для eth_simulateTransaction .
balanceOf
метода Erc20. Так что в этом случае токен-контракт фактически вызывается моим смарт-контрактом. Будет ли это стоить газа, как указано, даже если весь процесс доступен только для чтения?view
или pure
, никогда не потребует оплаты газа. Вы правы, что простой способ сказать, что весь процесс, который доступен только для чтения, не будет стоить газа. Обратите внимание, что gas по-прежнему используется view
функциями .call
операция? Другими словами, если происходит call
сбой где-то посередине, происходит ли откат?eth_call
ничего не сохраняет: «откат» — это поведение по умолчанию.Разница между вызовом и транзакцией заключается в следующем:
транзакции создаются вашим клиентом, подписываются и транслируются в сеть. В конечном итоге они изменят состояние блокчейна, например, манипулируя балансами или значениями в смарт-контрактах.
вызовы — это транзакции, выполняемые локально на локальном компьютере пользователя, который самостоятельно оценивает результат. Они доступны только для чтения и работают быстро. Они никак не могут изменить блокчейн, потому что никогда не отправляются в сеть. Некоторые примеры "только для чтения/пробный запуск/практика".
Звонки полезны для отладки смарт-контрактов, поскольку они не требуют комиссий за транзакции или газа.
constant
модификатор в свою функцию, и это сработало)
Константин Ван
call
в этом вопросе нет ни опкода EVMCALL
, ни Solidity<address>.call()
, которые вносят изменения в состояния контракта, а Web3.js APIweb3.eth.call()
, который не вносит никаких изменений в состояние.