📜  Solidity - 回退函数

📅  最后修改于: 2022-05-13 01:54:41.385000             🧑  作者: Mango

Solidity - 回退函数

如果没有其他函数与函数标识符匹配,或者函数调用没有提供数据,则执行 Solidity 回退函数。只能将一个未命名的函数分配给合约,并且只要合约收到没有任何数据的纯以太币,就会执行该函数。要接收 Ether 并将其添加到合约的总余额中,必须将回退函数标记为应付。如果没有这样的函数,合约就不能通过常规交易接收 Ether,并会抛出异常。

回退函数的属性:

  1. 没有名称或参数。
  2. 如果它没有被标记为payable ,合约将在收到没有数据的普通以太币时抛出异常。
  3. 不能返回任何东西。
  4. 每个合约可以定义一次。
  5. 如果调用者打算调用一个不可用的函数,它也会被执行
  6. 必须将其标记为外部。
  7. 当被另一个函数调用时,它被限制为 2300 gas。这是为了使这个函数调用尽可能便宜。

示例:在下面的示例中,创建合约以演示不同回退函数的不同条件。

Solidity
pragma solidity ^0.4.0;
  
// Creating a contract
contract GeeksForGeeks 
{
    // Declaring the state variable
    uint x; 
      
    // Mapping of addresses to their balances
    mapping(address => uint) balance; 
  
    // Creating a constructor 
    constructor() public
    {
        // Set x to default 
        // value of 10
        x=10; 
  
    }
  
    // Creating a function 
    function SetX(uint _x) public returns(bool)
    {
        // Set x to the 
        // value sent
        x=_x; 
        return true;
    }
      
    // This fallback function 
    // will keep all the Ether
    function() public payable
    {
        balance[msg.sender] += msg.value;
    }
} 
  
// Creating the sender contract
contract Sender 
{
  function transfer() public payable 
  {
      // Address of GeeksForGeeks contract
      address _receiver = 
              0xbcc0185441de06F0452D45AEd6Ad8b98017796fb;  
                
      // Transfers 100 Eth to above contract          
      _receiver.transfer(100); 
  }
}


输出:



回退功能

输出

解释:

1.Contract GeeksForGeeks:它有一个变量x,它在constructor()中被设置为默认值10。该合约有一个名为SetX(uint _x)的函数,它将函数值设置为函数调用期间发送的所需参数。下面的声明创建了称为 balance 的地址到值映射,该映射将地址映射到它们的余额。

mapping(address => uint) balance;

2. 合约发送方:这是一个完全独立且不相关的合约。它将以太币值发送到合约 GeeksForGeeks。合约不知道 GeeksForGeeks 合约的机制。发送没有任何消息且只有 Ether 的交易会导致错误。
下面的语句声明了一个地址类型的变量_receiver 。它明确存储合约 GeeksForGeeks 的地址。然后它使用address.transfer(value)将 Ether 转移到合约。

address _receiver = 0xbcc0185441de06F0452D45AEd6Ad8b98017796fb;  //Address of GeeksForGeeks contract
_receiver.transfer(100); 

3.函数()公开应付:

下面的函数是一个回退函数。它被宣布为应付,允许它接受转移价值。它在两种情况下被调用

  1. 合约只接收以太币,不接收数据。
  2. 即使帐户收到数据,也没有匹配的函数调用。

这有助于我们保护函数免于抛出错误。在这个程序中,合约 GeeksForGeeks 只接收 Ether,回退函数使用接收到的值添加到与发送地址相关的余额中。

function() public payable
    {
        balance[msg.sender] += msg.value;
    }