M04-L01 · Ethereum Virtual Machine

Bytecode and opcodes

Bytecode and opcodes

Bài toán

Muốn hiểu EVM thực thi logic và kiểm soát state thế nào, thay vì chỉ gọi Solidity như một Java method.

Vấn đề

Nếu hiểu sai execution context, gas hoặc ABI, backend và contract có thể trả kết quả sai, mất phí hoặc có lỗ hổng.

Giải pháp và lý thuyết

Compiler transforms Solidity into EVM bytecode; EVM executes opcodes deterministically. Bytecode includes a dispatcher for function selectors. Optimizer and compiler versions change generated code.

So sánh với Java

Java bytecode chạy trên JVM trong tiến trình của ứng dụng; EVM bytecode được các node thực thi theo quy tắc đồng thuận, có gas metering và trạng thái blockchain.

Lab — Bytecode and opcodes

Prerequisites

Steps

  1. cd solution
  2. forge build
  3. forge test -vvv
  4. forge test --gas-report
  5. Run forge inspect src/Lab.sol:OpcodeLab deployedBytecode and forge inspect src/Lab.sol:OpcodeLab opcodes; identify PUSH, ADD, GT, RETURN and explain optimizer differences.

Expected output

Troubleshooting

Exercises — Bytecode and opcodes

  1. Đọc solution/src/Lab.sol, tự viết lại contract vào starter/src/Lab.sol.
  2. Tự viết test tương ứng, không copy solution; chạy forge test.
  3. Thêm một negative test có require hoặc revert hợp lý và giải thích trace.
  4. Run forge inspect src/Lab.sol:OpcodeLab deployedBytecode and forge inspect src/Lab.sol:OpcodeLab opcodes; identify PUSH, ADD, GT, RETURN and explain optimizer differences.

Acceptance: Build thành công; tests pass; ghi chú vì sao EVM có hành vi như vậy.

Interview — Bytecode and opcodes

Q1. EVM khác JVM thế nào? EVM thực thi deterministic smart-contract bytecode có gas accounting và state được đồng thuận; JVM chạy ứng dụng trong một runtime riêng.

Q2. Vì sao cần inspect trace? Trace cho thấy external calls, revert, gas và execution context để debug lỗi không thấy được chỉ từ source.

Q3. Điều gì xảy ra khi transaction revert? State changes trong reverted execution bị rollback, nhưng gas đã dùng vẫn tiêu thụ; nếu lỗi ở subcall được catch thì outer execution có thể tiếp tục.