0Pricing
Blockchain Smart Contracts with Solidity · Lezione

Implementazione di un token ERC-20

Sviluppi ed esegua il deployment di un token conforme a ERC-20, incluse le funzioni transfer, approve e allowance.

Implementazione di un token ERC-20 è una lezione Blockchain Smart Contracts with Solidity gratuita su CoddyKit. Questa è la lezione 2 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento Blockchain Smart Contracts with Solidity, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso Blockchain Smart Contracts with Solidity include 4 lezioni in totale.

Parti di questa lezione non sono ancora state tradotte e vengono mostrate in inglese.

Build Your Own ERC-20 Token

Welcome! In this lesson, you'll learn to implement your very own ERC-20 compliant token. We'll cover the essential functions and variables that make up this widely used standard.

By the end, you'll have a working understanding of how these tokens operate at a fundamental level on the Ethereum blockchain.

Token Identity: Name, Symbol, Decimals

Every ERC-20 token needs basic identifying information: a name, a symbol, and decimals. These are often public state variables.

  • name: The full name of your token (e.g., "MyCoddyToken").
  • symbol: A short ticker symbol (e.g., "MCT").
  • decimals: How many decimal places the token can be divided into (commonly 18, like Ether).

Let's start our contract with these properties:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract MyToken {
  string public name = "MyCoddyToken";
  string public symbol = "MCT";
  uint8 public decimals = 18; // Common for ERC-20
}

Total Supply & Initial Minting

The totalSupply variable keeps track of all existing tokens. We also need a way to store each user's balance, typically using a mapping.

The constructor is a special function that runs only once when the contract is deployed. We use it to set the initial totalSupply and assign all initial tokens to the deployer's address.

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract MyToken {
  string public name = "MyCoddyToken";
  string public symbol = "MCT";
  uint8 public decimals = 18;

  uint256 public totalSupply; // Total tokens in existence
  mapping(address => uint256) private _balances; // User balances

  constructor(uint256 initialSupply) {
    totalSupply = initialSupply;
    _balances[msg.sender] = initialSupply; // Mints to deployer
  }
}

Checking Balances: `balanceOf`

The balanceOf function allows anyone to query the token balance of a specific address. It's a view function, meaning it doesn't change the contract's state and costs no gas to call off-chain.

We retrieve the balance from our _balances mapping.

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract MyToken {
  string public name = "MyCoddyToken";
  string public symbol = "MCT";
  uint8 public decimals = 18;

  uint256 public totalSupply;
  mapping(address => uint256) private _balances;

  constructor(uint256 initialSupply) {
    totalSupply = initialSupply;
    _balances[msg.sender] = initialSupply;
  }

  function balanceOf(address account) public view returns (uint256) {
    return _balances[account];
  }
}

Direct Transfers: `transfer`

The transfer function enables a token holder to send tokens directly to another address. It's a core function of the ERC-20 standard.

Before transferring, we must ensure the sender has sufficient balance. After the transfer, we emit a Transfer event, which is vital for blockchain explorers and dApps to track token movements.

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract MyToken {
  string public name = "MyCoddyToken";
  string public symbol = "MCT";
  uint8 public decimals = 18;

  uint256 public totalSupply;
  mapping(address => uint256) private _balances;

  // ERC-20 events
  event Transfer(address indexed from, address indexed to, uint256 value);
  event Approval(address indexed owner, address indexed spender, uint256 value);

  constructor(uint256 initialSupply) {
    totalSupply = initialSupply;
    _balances[msg.sender] = initialSupply;
    emit Transfer(address(0), msg.sender, initialSupply); // Minting event
  }

  function balanceOf(address account) public view returns (uint256) {
    return _balances[account];
  }

  function transfer(address recipient, uint256 amount) public returns (bool) {
    require(_balances[msg.sender] >= amount, "Insufficient balance");

    _balances[msg.sender] -= amount;
    _balances[recipient] += amount;
    emit Transfer(msg.sender, recipient, amount);
    return true;
  }
}

Delegated Spending: `approve`

The approve function allows a token holder (the owner) to grant another address (the spender) permission to spend a certain amount of their tokens on their behalf.

This is crucial for interacting with decentralized applications (dApps) where you might want a smart contract to manage your tokens (e.g., for staking or trading). We track these approvals in an _allowances mapping.

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract MyToken {
  string public name = "MyCoddyToken";
  string public symbol = "MCT";
  uint8 public decimals = 18;

  uint256 public totalSupply;
  mapping(address => uint256) private _balances;
  mapping(address => mapping(address => uint256)) private _allowances; // New: owner => (spender => amount)

  event Transfer(address indexed from, address indexed to, uint256 value);
  event Approval(address indexed owner, address indexed spender, uint256 value);

  constructor(uint256 initialSupply) {
    totalSupply = initialSupply;
    _balances[msg.sender] = initialSupply;
    emit Transfer(address(0), msg.sender, initialSupply);
  }

  function balanceOf(address account) public view returns (uint256) {
    return _balances[account];
  }

  function transfer(address recipient, uint256 amount) public returns (bool) {
    require(_balances[msg.sender] >= amount, "Insufficient balance");
    _balances[msg.sender] -= amount;
    _balances[recipient] += amount;
    emit Transfer(msg.sender, recipient, amount);
    return true;
  }

  function approve(address spender, uint256 amount) public returns (bool) {
    _allowances[msg.sender][spender] = amount;
    emit Approval(msg.sender, spender, amount);
    return true;
  }
}

Checking Allowance: `allowance`

The allowance function lets you check how many tokens a specific spender is currently permitted to transfer from an owner's balance.

This is a view function, similar to balanceOf, and helps external applications understand the spending limits set by users.

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract MyToken {
  string public name = "MyCoddyToken";
  string public symbol = "MCT";
  uint8 public decimals = 18;

  uint256 public totalSupply;
  mapping(address => uint256) private _balances;
  mapping(address => mapping(address => uint256)) private _allowances;

  event Transfer(address indexed from, address indexed to, uint256 value);
  event Approval(address indexed owner, address indexed spender, uint256 value);

  constructor(uint256 initialSupply) {
    totalSupply = initialSupply;
    _balances[msg.sender] = initialSupply;
    emit Transfer(address(0), msg.sender, initialSupply);
  }

  function balanceOf(address account) public view returns (uint256) {
    return _balances[account];
  }

  function allowance(address owner, address spender) public view returns (uint256) {
    return _allowances[owner][spender];
  }

  function transfer(address recipient, uint256 amount) public returns (bool) {
    require(_balances[msg.sender] >= amount, "Insufficient balance");
    _balances[msg.sender] -= amount;
    _balances[recipient] += amount;
    emit Transfer(msg.sender, recipient, amount);
    return true;
  }

  function approve(address spender, uint256 amount) public returns (bool) {
    _allowances[msg.sender][spender] = amount;
    emit Approval(msg.sender, spender, amount);
    return true;
  }
}

Spending on Behalf: `transferFrom`

The transferFrom function is used by a spender (who has been approved) to move tokens from an owner's balance to a recipient.

It requires checks for both the sender's balance and the allowance granted. After a successful transfer, the allowance is reduced by the transferred amount.

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract MyToken {
  string public name = "MyCoddyToken";
  string public symbol = "MCT";
  uint8 public decimals = 18;

  uint256 public totalSupply;
  mapping(address => uint256) private _balances;
  mapping(address => mapping(address => uint256)) private _allowances;

  event Transfer(address indexed from, address indexed to, uint256 value);
  event Approval(address indexed owner, address indexed spender, uint256 value);

  constructor(uint256 initialSupply) {
    totalSupply = initialSupply;
    _balances[msg.sender] = initialSupply;
    emit Transfer(address(0), msg.sender, initialSupply);
  }

  function balanceOf(address account) public view returns (uint256) {
    return _balances[account];
  }

  function allowance(address owner, address spender) public view returns (uint256) {
    return _allowances[owner][spender];
  }

  function transfer(address recipient, uint256 amount) public returns (bool) {
    require(_balances[msg.sender] >= amount, "Insufficient balance");
    _balances[msg.sender] -= amount;
    _balances[recipient] += amount;
    emit Transfer(msg.sender, recipient, amount);
    return true;
  }

  function approve(address spender, uint256 amount) public returns (bool) {
    _allowances[msg.sender][spender] = amount;
    emit Approval(msg.sender, spender, amount);
    return true;
  }

  function transferFrom(
    address sender,
    address recipient,
    uint256 amount
  ) public returns (bool) {
    require(_balances[sender] >= amount, "Insufficient balance from sender");
    require(_allowances[sender][msg.sender] >= amount, "Insufficient allowance");

    _allowances[sender][msg.sender] -= amount;
    _balances[sender] -= amount;
    _balances[recipient] += amount;
    emit Transfer(sender, recipient, amount);
    return true;
  }
}

Full Minimal ERC-20 Implementation

Here's a complete, minimal ERC-20 token contract. While more advanced implementations (like OpenZeppelin's) include additional features and safety checks, this code covers all the core functions required by the standard.

You can deploy this contract to a testnet to create your own functional token!

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract MyToken {
  string public name = "MyCoddyToken";
  string public symbol = "MCT";
  uint8 public decimals = 18;

  uint256 public totalSupply;
  mapping(address => uint256) private _balances;
  mapping(address => mapping(address => uint256)) private _allowances;

  event Transfer(address indexed from, address indexed to, uint256 value);
  event Approval(address indexed owner, address indexed spender, uint256 value);

  constructor(uint256 initialSupply) {
    totalSupply = initialSupply;
    _balances[msg.sender] = initialSupply;
    emit Transfer(address(0), msg.sender, initialSupply);
  }

  function balanceOf(address account) public view returns (uint256) {
    return _balances[account];
  }

  function allowance(address owner, address spender) public view returns (uint256) {
    return _allowances[owner][spender];
  }

  function transfer(address recipient, uint256 amount) public returns (bool) {
    require(_balances[msg.sender] >= amount, "Insufficient balance");
    _balances[msg.sender] -= amount;
    _balances[recipient] += amount;
    emit Transfer(msg.sender, recipient, amount);
    return true;
  }

  function approve(address spender, uint256 amount) public returns (bool) {
    _allowances[msg.sender][spender] = amount;
    emit Approval(msg.sender, spender, amount);
    return true;
  }

  function transferFrom(
    address sender,
    address recipient,
    uint256 amount
  ) public returns (bool) {
    require(_balances[sender] >= amount, "Insufficient balance from sender");
    require(_allowances[sender][msg.sender] >= amount, "Insufficient allowance");

    _allowances[sender][msg.sender] -= amount;
    _balances[sender] -= amount;
    _balances[recipient] += amount;
    emit Transfer(sender, recipient, amount);
    return true;
  }
}

ERC-20 Core Functions Check

You've learned about the essential functions for an ERC-20 token. Now, let's test your knowledge!

Recap: Your Own Token

Congratulations! You've now implemented the core logic for an ERC-20 token. You learned how to define its properties, manage total supply and individual balances, and enable both direct and delegated token transfers.

Understanding these fundamental building blocks is key to working with any token on the Ethereum blockchain. Next, you might explore how to integrate with existing ERC-20 libraries or add more advanced features!

Domande Frequenti

La lezione «Implementazione di un token ERC-20» è gratuita?

Sì — il testo completo di «Implementazione di un token ERC-20» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso Blockchain Smart Contracts with Solidity, passa a CoddyKit PRO. Il corso Blockchain Smart Contracts with Solidity include 4 lezioni in totale.

Cosa imparerò in «Implementazione di un token ERC-20»?

Sviluppi ed esegua il deployment di un token conforme a ERC-20, incluse le funzioni transfer, approve e allowance. Eserciti Blockchain Smart Contracts with Solidity con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.

Ho bisogno di esperienza per iniziare Blockchain Smart Contracts with Solidity?

Non è richiesta alcuna esperienza precedente. Blockchain Smart Contracts with Solidity su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 2 di 4.

Quanto tempo richiede la lezione «Implementazione di un token ERC-20»?

La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.

Posso scrivere ed eseguire codice in questa lezione Blockchain Smart Contracts with Solidity?

Sì. Ogni lezione Blockchain Smart Contracts with Solidity include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.

Tutte le lezioni di questo corso

  1. Standard per token fungibili ERC-20
  2. Implementazione di un token ERC-20
  3. Token non fungibili ERC-721 (NFT)
  4. Standard multi-token ERC-1155
← Torna a Blockchain Smart Contracts with Solidity