What are payable functions in Solidity?

Learn about Payable functions in Solidity, their importance in handling Ether deposits, and how to create and use them in smart contracts.

Target

With this guide, you should be able to:

  • Understand the purpose and usage of payable functions in Solidity
  • Learn how to send Ether to a smart contract
  • Writing payable functions in Solidity
  • Create revocable payable functions with conditions
  • Implement custom logic in payable functions
  • Understanding message calls and their relevance in the Ethereum Virtual Machine (EVM)

Payable function

In Solidity, a payable function is a function that allows a smart contract to accept ether. They help developers manage incoming ether and take actions when received. For example, a simple payable function can collect ether donations for a fundraiser. Here is a basic code example:

pragma solidity ^0.8.0;

contract Fundraiser {
    function donate() external payable {
        // Ether is received and stored in the contract's balance
        // You can perform any other actions with the Ether received here - for example, sending it to some other address etc.
    }
}

In this example, when donatethe function is called, it takes the Ether sent by the donor and adds it to the contract's balance.

The keyword payableallows someone to send ether to the contract and run code to process this deposit.

This code may log the event, modify storage to record the deposit, or even reverse the transaction if it chooses to do so.

When developers explicitly mark a smart contract with a payable type , they are saying "I want to send ether to this function". To understand why this is important, imagine how bad it would be if someone sent ether into a contract, but the developer didn't write code to handle that event. In that case, the ether may be permanently locked, or unable to be withdrawn by its intended recipient.

How to send ether to a smart contract

Sending ether is a native function of the Ethereum Virtual Machine (EVM). This is unlike any other transfer in the EVM, which requires developers to write custom logic to handle the transfer (e.g. NFT or ERC20).

当有人向智能合约发送以太币时,他们通过交易本身的“value”字段进行操作。让我们看看JSON格式的交易内容:

{
    
    
    "to""0x5baf84167cad405ce7b2e8458af73975f9489291",
    "value""0xb1a2bc2ec50000"// 1 ether 
    "data""0xd0e30db0" // deposit() 
    // ... other properties
}

此交易将1个以太币发送到地址0x5baf84167cad405ce7b2e8458af73975f9489291。如果此地址是一个智能合约,它将尝试解析calldata(data)以确定此用户试图调用哪个智能合约函数(在这种情况下是***deposit()***)。

根据函数支付或非支付的情况,将发生以下两种情况之一:

  1. 如果函数是一个可支付函数,那么它将运行逻辑。
  2. 如果函数不可支付,则交易将恢复并返回资金,减去交易的燃气成本。

什么是 Solidity 可支付函数的示例?

这是一个使用Solidity的基本可支付函数示例,其中包括“deposit”函数:

function deposit() payable external {
    // no need to write anything here!
}

注意,在这种情况下,我们没有在 deposit 函数主体中编写任何代码。编写一个可支付的函数就足以接收以太币,您可能不需要编写任何逻辑。

例如,如果这是一个可支付的智能合约,由慈善机构控制,接受加密货币捐款,也许用户只需调用 deposit ,慈善机构最终就能够将这些捐款提取到他们选择的地址。在这种情况下,编写一个 receive 函数可能更好:

receive() external payable {
    
    
    // this built-in function doesn't require any calldata,
    // it will get called if the data field is empty and 
    // the value field is not empty.
    // this allows the smart contract to receive ether just like a 
    // regular user account controlled by a private key would.
}

什么是一个Solidity可支付函数的反转示例?

一个可付款的智能合约函数可以回滚。这是一个可回滚的可付款函数示例,它使用两个require语句来验证msg.valuebalances[msg.sender]

mapping(address => uint) balances;

function deposit() payable external {
    // deposit sizes are restricted to 1 ether
    require(msg.value == 1 ether);
    // an address cannot deposit twice
    require(balances[msg.sender] == 0);
    balances[msg.sender] += msg.value;
}

如果任何一个require语句不为真,则交易将回滚并发送者将收回他们的资金。

为什么我们要在可支付函数中编写逻辑?

如果我们有一个智能合约,需要跟踪谁存入了哪些以太币,我们可以在存储中跟踪它:

mapping(address => uint) balances;

function deposit() payable external {
    // record the value sent 
    // to the address that sent it
    balances[msg.sender] += msg.value;
}

这里的msg.value对应着我们在“如何发送以太币”部分看到的交易中编码的value字段。作为Solidity开发人员,我们可以利用消息值来记录存款并将其映射到该交易地址的某些内部余额。

为什么叫做msg.value?

在以太坊虚拟机(EVM)中,与智能合约的交互被称为“消息调用”。这适用于用户直接调用智能合约的情况,也适用于智能合约调用另一个智能合约的情况(内部交易)。

可支付的Solidity函数

简而言之,一个可支付的函数是一个可以接收以太币的函数。它为开发者提供了回应以太币存款进行记录或任何其他必要逻辑的机会。

本文由 mdnice 多平台发布

Guess you like

Origin blog.csdn.net/weixin_40156487/article/details/130857509