# Types, visibility and safe arithmetic

## 01 — Bài toán
Thiết kế một Smart Contract có thể được nhiều địa chỉ gọi mà không cần tin cậy một backend quản lý state.

## 02 — Vấn đề
Code chạy trong EVM, mỗi state write tiêu tốn gas và giao dịch có thể bị gọi từ bất kỳ địa chỉ nào. Java `private` không tương đương với bí mật on-chain.

## 03 — Giải pháp
Áp dụng các primitive Solidity đúng ngữ cảnh, xác minh preconditions, cập nhật state nhất quán và kiểm thử trường hợp thất bại.

## 04 — Lý thuyết
State types (`uint256`, `address`), visibility (`public`, `external`), `pure` versus state-changing calls and Solidity 0.8 checked arithmetic.

**So sánh Java:** contract giống một stateful service được nhân bản theo đồng thuận; `msg.sender` tương tự authenticated caller nhưng không tự đảm bảo user identity; storage tồn tại trên chain, không giống Java heap.

**Dependency:** M04 EVM; M05 bài trước nếu có.

# 05 — Hands-on lab: Types, visibility and safe arithmetic

## Chuẩn bị
- Foundry (forge, cast, anvil); Solidity 0.8.24
- Chạy hoàn toàn local, không dùng mainnet funds

## Thực hiện
1. Đọc `theory.md` và `solution/src/Lab.sol`, xác định state, invariants và external calls.
2. Tự triển khai `starter/src/Lab.sol` trước khi xem solution.
3. Viết các test trong `starter/test/Lab.t.sol`.
4. `cd solution && forge build && forge test -vvv`
5. `forge test --gas-report` để quan sát chi phí.
6. `forge test -vvvv` nếu test fail, đọc call trace và revert reason.

## Các test trong reference
- `testInitialState`
- `testIncrement`
- `testPure`
- `testZeroReverts`
- `testReset`

## Expected output
`forge build` thành công, tất cả các test trên PASS. Đây là kết quả **dự kiến**, chưa được xác minh trong môi trường đóng gói vì không có forge/solc.

## Troubleshooting
- `forge: command not found`: cài Foundry chính thức.
- Compiler download error: kiểm tra network và solc_version.
- Assertion failure: chạy `forge test -vvvv` để xem trace.

# 07 — Exercises

1. Implement contract và test từ đầu trong `starter/`, không copy solution.
2. Add `decrement` with underflow protection and a revert test.
3. Bổ sung ít nhất một negative test (revert) và một edge case.
4. Viết giải thích vì sao state thay đổi hoặc revert; so sánh với Java service.

**Acceptance criteria:** `forge build` pass; toàn bộ test pass; không sử dụng tài sản mainnet; README ghi các invariants và assumptions.

# 08 — Interview

**Q1: Vì sao contract cần kiểm tra `msg.sender`?** Bởi mọi địa chỉ đều có thể gửi transaction; quyền phải được enforce on-chain, không thể chỉ dựa vào API gateway.

**Q2: `view` và `pure` khác nhau thế nào?** `view` có thể đọc state nhưng không sửa state; `pure` không đọc hoặc sửa state contract.

**Q3: Revert ảnh hưởng gì?** State updates trong phạm vi bị revert được rollback, nhưng gas đã tiêu thụ không được hoàn lại hoàn toàn.

**Q4: Types, visibility and safe arithmetic có rủi ro gì?** Kiểm tra access control, arithmetic bounds, external calls, assumptions về người gọi và accounting invariants.
