Solidity Basics
1. Data Types and Variables
Solidity, like other programming languages, has a variety of data types and variables used to store and manipulate data. Understanding these basics is crucial for writing smart contracts.
Primitive Data Types:
uint
: Unsigned integer (positive only).int
: Signed integer (can be positive or negative).bool
: Boolean value (true
orfalse
).address
: Represents a 20-byte Ethereum address.bytes
: Dynamically-sized byte array.string
: Dynamically-sized UTF-8 encoded string.
uint256 myNumber = 42; bool isActive = true; address myAddress = 0x1234567890abcdef1234567890abcdef12345678; string myString = "Hello, Solidity!";
2. Functions
Functions in Solidity are similar to functions in other programming languages. They define a piece of code that can be called and executed.
Basic Function Syntax:
function multiply(uint256 a, uint256 b) public pure returns (uint256) { return a * b; }
public
: The function can be called both internally and externally.pure
: Indicates that the function does not read or modify the state.
3. Visibility Specifiers
Visibility specifiers control how and where functions and state variables can be accessed.
Types of Visibility:
public
: Accessible externally and internally.private
: Accessible only within the contract that defines it.internal
: Accessible within the contract and contracts deriving from it.external
: Accessible only from outside the contract.
4. Modifiers
Modifiers are used to change the behavior of functions. They allow you to add preconditions to functions.
Example of a Modifier:
modifier onlyOwner() { require(msg.sender == owner, "Not the contract owner"); _; } function changeOwner(address newOwner) public onlyOwner { owner = newOwner; }
_
: The placeholder for the function's body.
5. Custom Modifiers
You can create custom modifiers to enforce specific rules within your contract.
Example:
modifier isAdult(uint256 age) { require(age >= 18, "Not an adult"); _; } function enterBar(uint256 age) public isAdult(age) { // code for entering the bar }
6. Constructors
Constructors are special functions that are executed only once when a contract is deployed. They are typically used to initialize contract state.
Example:
contract MyContract { address public owner; constructor() { owner = msg.sender; } }
7. Global Variables
Solidity provides several global variables that can be accessed within contracts.
Examples:
msg.sender
: The address of the caller.msg.value
: The amount of Ether sent with the transaction.block.timestamp
: The current block's timestamp.block.number
: The current block number.
8. Operators
Solidity supports standard operators like arithmetic, comparison, and logical operators.
Examples:
Arithmetic:
+
,-
,*
,/
,%
Comparison:
==
,!=
,>
,<
,>=
,<=
Logical:
&&
,||
,!
9. Conditionals
Conditionals are used to perform different actions based on different conditions.
Example:
function checkNumber(uint256 num) public pure returns (string memory) { if (num > 10) { return "Greater than 10"; } else { return "10 or less"; } }
10. Arrays
Arrays in Solidity can be of fixed or dynamic size.
Example:
uint256[] public numbers; function addNumber(uint256 num) public { numbers.push(num); }
11. Mappings
Mappings are key-value pairs where each unique key is mapped to a single value.
Example:
mapping(address => uint256) public balances; function updateBalance(address user, uint256 newBalance) public { balances[user] = newBalance; }
12. Structs
Structs allow you to create more complex data types by grouping multiple variables.
Example:
struct User { string name; uint256 age; } User public user; function setUser(string memory name, uint256 age) public { user = User(name, age); }
13. Events
Events are used to log information on the blockchain, which can be listened to by off-chain applications.
Example:
event UserCreated(address indexed userAddress, string name); function createUser(string memory name) public { emit UserCreated(msg.sender, name); }
14. Ether and Payments
Solidity allows contracts to handle Ether, the native currency of Ethereum.
Example:
function sendEther(address payable recipient) public payable { recipient.transfer(msg.value); }
15. Errors
Solidity allows you to define custom errors to save gas and improve readability.
Example:
error NotEnoughFunds(uint256 available, uint256 required); function withdraw(uint256 amount) public { if (amount > address(this).balance) { revert NotEnoughFunds(address(this).balance, amount); } }
16. Inheritance
Solidity supports inheritance, allowing you to create new contracts based on existing ones.
Example:
contract Parent { function sayHello() public pure returns (string memory) { return "Hello from Parent"; } } contract Child is Parent { function sayHelloFromChild() public pure returns (string memory) { return "Hello from Child"; } }
17. Calling Other Contracts
You can call functions from other contracts using either call
or interface-based method calls.
Example:
contract ExternalContract { function externalFunction() public pure returns (string memory) { return "Called from another contract"; } } contract MyContract { ExternalContract externalContract; constructor(address _externalContractAddress) { externalContract = ExternalContract(_externalContractAddress); } function callExternalFunction() public view returns (string memory) { return externalContract.externalFunction(); } }
18. Interfaces
Interfaces define the functions that must be implemented by a contract but do not contain any implementation themselves.
Example:
interface IERC20 { function totalSupply() external view returns (uint256); function balanceOf(address account) external view returns (uint256); function transfer(address recipient, uint256 amount) external returns (bool); } contract MyToken is IERC20 { // Implement the functions defined in the interface }
Last updated