# Solidity Basics

### **1. Data Types and Variables** <a href="#id-1.-data-types-and-variables" id="id-1.-data-types-and-variables"></a>

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` or `false`).
  * **`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** <a href="#id-2.-functions" id="id-2.-functions"></a>

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** <a href="#id-3.-visibility-specifiers" id="id-3.-visibility-specifiers"></a>

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** <a href="#id-4.-modifiers" id="id-4.-modifiers"></a>

Modifiers are used to change the behavior of functions. They allow you to add preconditions to functions.

* **Example of a Modifier:**

  ```solidity
  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** <a href="#id-5.-custom-modifiers" id="id-5.-custom-modifiers"></a>

You can create custom modifiers to enforce specific rules within your contract.

* **Example:**

  ```solidity
  modifier isAdult(uint256 age) {
      require(age >= 18, "Not an adult");
      _;
  }

  function enterBar(uint256 age) public isAdult(age) {
      // code for entering the bar
  }
  ```

### **6. Constructors** <a href="#id-6.-constructors" id="id-6.-constructors"></a>

Constructors are special functions that are executed only once when a contract is deployed. They are typically used to initialize contract state.

* **Example:**

  ```solidity
  contract MyContract {
      address public owner;

      constructor() {
          owner = msg.sender;
      }
  }
  ```

### **7. Global Variables** <a href="#id-7.-global-variables" id="id-7.-global-variables"></a>

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** <a href="#id-8.-operators" id="id-8.-operators"></a>

Solidity supports standard operators like arithmetic, comparison, and logical operators.

* **Examples:**
  * **Arithmetic:** `+`, `-`, `*`, `/`, `%`
  * **Comparison:** `==`, `!=`, `>`, `<`, `>=`, `<=`
  * **Logical:** `&&`, `||`, `!`

### **9. Conditionals** <a href="#id-9.-conditionals" id="id-9.-conditionals"></a>

Conditionals are used to perform different actions based on different conditions.

* **Example:**

  ```solidity
  function checkNumber(uint256 num) public pure returns (string memory) {
      if (num > 10) {
          return "Greater than 10";
      } else {
          return "10 or less";
      }
  }
  ```

### **10. Arrays** <a href="#id-10.-arrays" id="id-10.-arrays"></a>

Arrays in Solidity can be of fixed or dynamic size.

* **Example:**

  ```solidity
  uint256[] public numbers;

  function addNumber(uint256 num) public {
      numbers.push(num);
  }
  ```

### **11. Mappings** <a href="#id-11.-mappings" id="id-11.-mappings"></a>

Mappings are key-value pairs where each unique key is mapped to a single value.

* **Example:**

  ```solidity
  mapping(address => uint256) public balances;

  function updateBalance(address user, uint256 newBalance) public {
      balances[user] = newBalance;
  }
  ```

### **12. Structs** <a href="#id-12.-structs" id="id-12.-structs"></a>

Structs allow you to create more complex data types by grouping multiple variables.

* **Example:**

  ```solidity
  struct User {
      string name;
      uint256 age;
  }

  User public user;

  function setUser(string memory name, uint256 age) public {
      user = User(name, age);
  }
  ```

### **13. Events** <a href="#id-13.-events" id="id-13.-events"></a>

Events are used to log information on the blockchain, which can be listened to by off-chain applications.

* **Example:**

  ```solidity
  event UserCreated(address indexed userAddress, string name);

  function createUser(string memory name) public {
      emit UserCreated(msg.sender, name);
  }
  ```

### **14. Ether and Payments** <a href="#id-14.-ether-and-payments" id="id-14.-ether-and-payments"></a>

Solidity allows contracts to handle Ether, the native currency of Ethereum.

* **Example:**

  ```solidity
  function sendEther(address payable recipient) public payable {
      recipient.transfer(msg.value);
  }
  ```

### **15. Errors** <a href="#id-15.-errors" id="id-15.-errors"></a>

Solidity allows you to define custom errors to save gas and improve readability.

* **Example:**

  ```solidity
  error NotEnoughFunds(uint256 available, uint256 required);

  function withdraw(uint256 amount) public {
      if (amount > address(this).balance) {
          revert NotEnoughFunds(address(this).balance, amount);
      }
  }
  ```

### **16. Inheritance** <a href="#id-16.-inheritance" id="id-16.-inheritance"></a>

Solidity supports inheritance, allowing you to create new contracts based on existing ones.

* **Example:**

  ```solidity
  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** <a href="#id-17.-calling-other-contracts" id="id-17.-calling-other-contracts"></a>

You can call functions from other contracts using either `call` or interface-based method calls.

* **Example:**

  ```solidity
  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** <a href="#id-18.-interfaces" id="id-18.-interfaces"></a>

Interfaces define the functions that must be implemented by a contract but do not contain any implementation themselves.

* **Example:**

  ```solidity
  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
  }
  ```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://abc-71.gitbook.io/curriculum/week-2/solidity-basics.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
