Building with Solidity
Tools Within Smart Contracts
This lesson covers the built-in tools available inside Solidity smart contracts - global variables like msg.sender and block.timestamp, validation functions, error handling, events for external communication, and state management techniques that enable secure contract logic.
Tools Available Within Smart Contracts
Smart contracts on VeChain don’t run in isolation. Solidity provides a set of built-in tools that help contracts:
Track who called a function
Record when it happened
Validate actions
Emit logs
Manage gas and execution via VeChain’s transaction model
This lesson focuses on those internal tools that developers use inside a contract to write logic, enforce conditions, and connect with the outside world.
Global Variables (Built-in Tools)
Solidity gives you automatic access to a set of global variables that provide critical context during contract execution:
Tool | Description | Example Use |
| Address that called the function | Track who triggered the call |
| Amount of native token (VET) sent | Check if payment was sent |
| Time of current block | Enforce time delays or cooldowns |
| Originator of the full transaction | Rarely used; use |
These require no imports or setup. They’re always available in any function.
Example (used in your contract):
require(participants[msg.sender].timestamp == 0, "Already checked in");
Writing to State
Smart contracts store permanent data using state variables. When you change these, you are writing to the blockchain, which:
Requires a transaction
Consumes gas
Becomes part of the immutable ledger
Example:
participants[msg.sender] = Participant(name, block.timestamp);
Here, we store a user’s check-in info by updating a mapping. This change:
Persists forever (unless overwritten)
Can be read by anyone (if public or via view function)
require() – Guard Conditions
require() is the main tool for validating inputs or enforcing rules. If the condition is false, the function reverts, and no gas is spent beyond that point.
Example:
require(bytes(name).length > 0, "Name is required");
Use it for:
Input validation
Preventing re-entry or duplicates
Role checks (
onlyOwner,isRegistered, etc.)
Using Custom Errors Instead of Strings
Instead of hardcoded strings, custom errors reduce gas costs and make your contract easier to audit.
With this error, you can spot unauthorized access, reverted transaction, as well as the user who tried to access.
Try/Catch Pattern for Fallback Safety
Try/catch in Solidity is used to handle external or internal function calls that might fail. It allows you to catch and respond to errors gracefully, preventing contract execution from reverting entirely when something goes wrong.
emit + Events
Events let you signal external tools (like frontends, explorers, and analytics) that something happened. These are not stored as state but are recorded in the transaction logs.
Define an event:
event ParticipantCheckedIn(address indexed user, string name, uint256 timestamp);
Emitting the event:
emit ParticipantCheckedIn(msg.sender, name, block.timestamp);
Tools like VeChain Explorer or your frontend app can listen for these logs to update the UI or trigger notifications.
Tool | Purpose |
| Provide transaction context |
| Enforce logic and prevent invalid actions |
| Log actions for frontends and explorers |
Custom errors | Lower-gas reverts with structured metadata |
| Handle failed function calls gracefully |
State variables | Store persistent data on-chain |
Write functions | Update storage; require gas and transactions |
Clause | VeChain instruction wrapper for functions |
Fee delegation | Let another wallet pay for transaction gas |
Join our Telegram