Menu
Coddy logo textTech

Solidity Playground

Пишите, запускайте и делитесь фрагментами кода — без установки.

Contract.sol
Нажмите «Запустить», чтобы увидеть вывод здесь.
ArgsValues passed to your contract’s main(...) function. The runner ABI-encodes them based on the parameter types.
No arguments. Click "Add arg" to pass one.

Попробуйте Solidity в браузере

Solidity — язык смарт-контрактов Ethereum. Он исполняется на EVM — той же виртуальной машине, которая защищает сотни миллиардов долларов в mainnet и питает большинство L2. Этот playground даёт вам Monaco-редактор, подключённый к sandbox-ной связке solc + geth EVM, так что вы можете написать контракт, нажать Run и увидеть в точности, что произошло бы on-chain: вывод console.log, emit-нутые события и конечное состояние ваших storage-переменных — без деплоя, без оплаты gas и без использования wallet.

У Solidity есть несколько особенностей, которые стоит держать в голове на старте. Storage по умолчанию постоянный — всё, что вы присваиваете state-переменной, сохраняется; всё, что находится внутри функции, исчезает, как только вызов возвращается. События — это то, как контракты разговаривают с внешним миром (вашим фронтендом, индексером, The Graph) — они стоят gas, пишутся в логи транзакции и фильтруются по indexed-параметрам. И каждая external-функция получает входные данные через ABI encoding, а не через stdin — поэтому playground даёт вам типизированную панель Args, которая напрямую подключается к параметрам вашего main(...).

Что этот Solidity playground умеет хорошо

  • Настоящее исполнение solc + EVM, не симуляция через транспайлер. console.log идёт через forge-std, а пути emit / storage проходят настоящую семантику EVM — opcodes, gas, всё как есть.
  • Вкладка Events показывает каждый emit из вашего запуска, с indexed-параметрами, помеченными отдельно, так что вы видите ровно то, что получил бы фронтенд или subgraph.
  • Вкладка Storage показывает конечное значение каждой state-переменной, к которой обращался контракт, — включая записи в mapping (например, balances[0xabc...]). Переменные, в которые вы не писали, не появляются.
  • Типизированная панель Args передаёт значения в параметрический main(uint256 n, string memory name, ...). Runner ABI-кодирует их по сигнатуре функции, так что 42 становится uint256, а "hello"string.

Что можно построить в Solidity playground

  • Счётчики / increment-decrement-контракты, чтобы прочувствовать, как state-переменные сохраняются между вызовами — запишите в count, запустите и посмотрите, как значение появляется во вкладке Storage.
  • Паттерны передачи токенов — emit-ните Transfer(from indexed, to indexed, value) и увидите, как indexed и не-indexed поля рендерятся по-разному во вкладке Events, ровно так же, как они выглядят в реальных log topics EVM.
  • Случаи провала с require / revert — напишите guard, который падает на плохом входе, и увидите сообщение revert в stdout — вместо того чтобы сжечь gas на упавшей транзакции в mainnet.

Частые вопросы о Solidity

Что такое Solidity?
Solidity — самый распространённый язык смарт-контрактов для Ethereum и EVM-совместимых сетей (Polygon, Arbitrum, Optimism, Base и т. д.). Он компилируется в EVM-байткод — набор инструкций стек-машины, который выполняет каждый узел сети. Синтаксически он заимствует у JavaScript и C++, но семантика очень другая: storage дорогой и постоянный, каждый вызов меряется в gas, и нет async. Playground даёт вам sandbox-ную EVM, чтобы можно было практиковать язык, не касаясь реальной сети.
Нужен ли мне wallet или testnet ETH, чтобы это использовать?
Нет. Playground запускает ваш контракт внутри серверной EVM (того самого движка, что идёт с geth) в изолированном контейнере на каждый запрос. Никаких on-chain-транзакций, никакой оплаты gas настоящим ETH, никакой подписи wallet. Когда вы нажимаете Run, runner деплоит ваш контракт на свежесозданную in-memory-сеть, вызывает функцию main(...) с переданными args и показывает вам stdout, события и storage этого одного вызова. После Run всё выбрасывается.
Как передать входные данные в контракт?
Дайте контракту функцию main(...) с теми типизированными параметрами, которые вам нужны — function main(uint256 n) external или function main(string memory name, uint256 age, bool active) external view. Затем впишите значения в панель Args под редактором. Runner смотрит на сигнатуру функции и ABI-кодирует ваши строки в нужные типы — точно так же, как это делает cast call в командной строке. Для address пишите 0x...; для bool — true или false; для uint — десятичное значение.
В чём разница между вкладками Output, Events и Storage?
Output показывает то, что вы написали в stdout через console.log(...) из forge-std/console.sol, плюс сообщение об ошибке revert / require, если оно было. Events показывает каждое событие, которое контракт emit-нул во время запуска, по порядку, со значением каждого параметра (и небольшой пометкой "indexed" для indexed-параметров — это те, которые попадают в log topics EVM и могут фильтроваться инструментами вроде The Graph). Storage показывает значение после запуска для каждой state-переменной, в которую была запись, включая отдельные записи mapping — переменные, к которым вы не обращались, в списке не появляются.
Почему в некоторых туториалах по Solidity нет main()?
В реальной сети у Solidity-контрактов нет единой точки входа — клиенты вызывают любую public-функцию, идентифицируя её 4-байтовым селектором. Playground использует main() как соглашение, чтобы было очевидно, что запускать, и куда класть аргументы. Вне playground ваш контракт обычно выставляет несколько функций (mint, transfer, withdraw, ...), и ваш фронтенд или инструмент вроде cast / ethers / viem выбирает, какую вызвать.