--- title: 'Solidity WTF 103 32 單元 代幣水龍頭' lang: zh-tw --- Solidity WTF 103 32 單元 代幣水龍頭 === :::info :date: 2024/10/11 ::: [TOC] # 代幣水龍頭 ## 簡介 當你需要一些代幣進行一些測試,或是去進行交互,就會需要一些免費的代幣水龍頭。 ## code > 初始化合約時,會需要把ERC20的代幣合約傳進去 > requestTokens function 先確定使用未領過水,接這聲明IERC20的合約變數,並進行blanceOf查看是否有足夠代幣能發送,且使用IERC20來轉帳,在轉帳完成後標記已領取。 ```javascript= // SPDX-License-Identifier: MIT pragma solidity ^0.8.21; import "../ERC20/IERC20.sol"; contract Token { uint256 public amountAllowed = 100; // 每次請求的代幣數量 address public tokenContract; // ERC20 代幣合約地址 mapping(address => bool) public requestedAddress; // 存儲已請求代幣的地址 event SendToken(address indexed Receiver, uint256 indexed Amount); // 代幣發送事件 /// @dev 合約的建構函數,設置ERC20代幣合約地址 /// @param _tokenContract 要使用的ERC20代幣合約地址 constructor(address _tokenContract) { tokenContract = _tokenContract; // 初始化代幣合約地址 } /// @dev 請求代幣的函數 function requestTokens() external { // 確保請求者尚未請求過代幣 require(!requestedAddress[msg.sender]); IERC20 token = IERC20(tokenContract); // 聲明IERC20合約變數 // 確保合約中有足夠的代幣可以發送 require(token.balanceOf(address(this)) >= amountAllowed, "Faucet Empty!"); // 轉帳指定數量的代幣到請求者地址 token.transfer(msg.sender, amountAllowed); requestedAddress[msg.sender] = true; // 標記為已請求過代幣 emit SendToken(msg.sender, amountAllowed); // 發出代幣發送事件 } } ``` :::success 此領水`Demo`,是在假設有人前來領取免費代幣進行測試或交互的情況,有些設定像是已請求代幣的`mapping`,應該會在一天後自動取消,比較符合現在市面上的`24H`領水規定。 :::