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는 sandbox 처리된 solc + geth EVM에 연결된 Monaco 에디터를 제공하므로, 컨트랙트를 작성하고 Run을 누르면 on-chain에서 일어날 일을 그대로 확인할 수 있습니다: console.log 출력, emit된 event, 그리고 storage 변수의 최종 상태까지 — 배포도, gas 지불도, wallet도 필요 없습니다.

Solidity는 시작할 때 알아 두면 좋을 몇 가지 특징이 있습니다. Storage는 기본적으로 영구적입니다 — state 변수에 할당한 값은 계속 남고, 함수 안에 있는 값은 호출이 끝나면 사라집니다. Event는 컨트랙트가 바깥 세상(프런트엔드, 인덱서, The Graph)과 대화하는 방식입니다 — gas를 소비하고 트랜잭션 로그에 기록되며 indexed 파라미터로 필터링할 수 있습니다. 그리고 모든 external 함수는 입력을 stdin이 아니라 ABI encoding으로 받습니다 — 그래서 playground는 main(...) 파라미터에 바로 연결되는 타입이 지정된 Args 패널을 제공합니다.

이 Solidity playground가 잘하는 것

  • 트랜스파일러 시뮬레이션이 아니라 실제 solc + EVM 실행. console.log는 forge-std를 사용하고, emit / storage 경로는 실제 EVM 시맨틱 — opcode, gas, 전부 — 을 거칩니다.
  • Events 탭은 실행 중의 모든 emit을 보여주며, indexed 파라미터는 구분되게 표시되므로 프런트엔드나 subgraph가 받을 내용을 그대로 볼 수 있습니다.
  • Storage 탭은 컨트랙트가 건드린 모든 state 변수의 최종 값을 보여줍니다 — mapping 항목(예: balances[0xabc...])까지 포함해서요. 쓰지 않은 변수는 나타나지 않습니다.
  • 타입이 지정된 Args 패널이 파라메트릭한 main(uint256 n, string memory name, ...)에 값을 전달합니다. Runner는 함수 시그니처를 보고 ABI 인코딩하므로 42uint256이 되고 "hello"string이 됩니다.

Solidity playground에서 만들 수 있는 것

  • Counter / increment-decrement 컨트랙트로 state 변수가 호출 사이에 어떻게 유지되는지 학습 — count에 쓰고, 실행한 다음, Storage 탭에 나타나는 모습을 확인해 보세요.
  • 토큰 흐름 패턴 — Transfer(from indexed, to indexed, value)를 emit하면, indexed와 indexed가 아닌 필드가 Events 탭에서 다르게 렌더링되는 것을 볼 수 있습니다. 실제 EVM 로그 토픽에서 보이는 그대로의 모습입니다.
  • require / revert 실패 케이스 — 잘못된 입력에서 실패하는 guard를 작성하면, mainnet에서 실패한 트랜잭션에 gas를 태우는 대신 revert 메시지가 stdout으로 올라오는 것을 볼 수 있습니다.

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 트랜잭션도, 실제 ETH로 내는 gas도, wallet 서명도 없습니다. Run을 누르면 runner는 새 in-memory 체인에 컨트랙트를 배포하고, 제공한 args로 main(...)을 호출한 다음 그 한 번의 호출에서 발생한 stdout, event, storage를 보여줍니다. Run이 끝나면 모두 폐기됩니다.
컨트랙트에 입력값을 어떻게 전달하나요?
컨트랙트에 원하는 타입의 파라미터를 가진 main(...) 함수를 만들어 주세요 — 예를 들어 function main(uint256 n) external이나 function main(string memory name, uint256 age, bool active) external view처럼요. 그리고 에디터 아래 Args 패널에 값을 입력하면 됩니다. Runner는 함수 시그니처를 보고 커맨드라인의 cast call이 하는 것과 같은 방식으로 문자열을 적절한 타입으로 ABI 인코딩합니다. address 인자는 0x..., bool은 true 또는 false, uint는 10진수 값을 입력하세요.
Output, Events, Storage 탭의 차이가 뭔가요?
Output은 forge-std/console.solconsole.log(...)로 stdout에 쓴 내용과, revert / require 오류 메시지를 보여줍니다. Events는 실행 중 컨트랙트가 emit한 모든 event를 순서대로, 각 파라미터의 값과 함께 보여줍니다(그리고 indexed 파라미터에는 작은 "indexed" 표시가 붙습니다 — 이들은 EVM 로그 토픽에 들어가고 The Graph 같은 도구로 필터링할 수 있는 필드입니다). Storage는 쓰기가 발생한 state 변수의 실행 후 값을 보여주며, 개별 mapping 항목도 포함됩니다 — 건드리지 않은 변수는 목록에서 빠집니다.
어떤 Solidity 튜토리얼에는 왜 main()이 없나요?
실제 체인에서 Solidity 컨트랙트에는 단일한 진입점이 없습니다 — 클라이언트는 4바이트 selector로 식별되는, 원하는 public 함수를 호출합니다. Playground는 실행할 명확한 대상과 인자를 둘 자리를 마련하기 위한 관례로 main()을 사용합니다. Playground 밖에서는 컨트랙트가 보통 여러 함수(mint, transfer, withdraw 등)를 노출하고, 프런트엔드나 cast / ethers / viem 같은 도구가 어떤 함수를 호출할지 결정합니다.