Solidity语言学习笔记————26、回退函数

本文介绍了智能合约中的回退函数概念及其重要性。回退函数在没有其他匹配函数时执行,并在接收Ether时触发。文章强调了标记为payable的重要性及如何避免超出2300gas限制。

回退函数(Fallback Function)

一个合约可以有一个匿名函数。此函数不能有参数,不能返回任何值。如果没有其他函数与给定的函数标识符匹配,或者如果根本没有提供数据,将执行一个合约的调用。

此外,每当合同接收没有数据的纯Ether时,会执行回退函数。此外,为了接收Ether,回退函数必须标记为payable。如果没有这样的函数,合约不能通过常规transactions接收Ether。

在这种情况下,函数调用通常只有2300gas可用,所以使回退函数尽可能便宜是很重要的。注意,调用回退函数的事务与内部调用相比,所需的gas要高得多,因为每个事务都收取额外的21000gas或更多的用于签名检查之类。

以下操作将比回退函数消耗更多的gas

  • 写入storage
  • 创建合约
  • 调用一个消耗大量gas的外部函数
  • 发送Ether

请彻底测试回退函数,以确保在部署合约之前执行消耗小于2300gas

注解
虽然回退函数不能有参数,仍然可以使用msg.data来检索检索调用的任何payload
警告
直接接收Ether的合约(没有函数调用,即使用sendtransfer),不定义回退函数将抛出异常并返回Ether(这与Solidity v0.4.0之不同)。因此,如果您希望合约接收Ether,则必须实现回退函数。
警告
没有payable回退函数的合约可以作为一个coinbase transaction的接收者来接收Ether(又名挖矿奖励)或selfdestruct的目的地。合约不能对这样的Ether转账作出反应,因此也不能拒绝它们。这是EVM和Solidity的设计选择。这也意味着,this.balance可以高于合约中实现的一些手工记账的总和(即有一个计数器在回退函数中更新)。
pragma solidity ^0.4.0;

contract Test {
    // This function is called for all messages sent to
    // this contract (there is no other function).
    // Sending Ether to this contract will cause an exception,
    // because the fallback function does not have the `payable`
    // modifier.
    function() public { x = 1; }
    uint x;
}


// This contract keeps all Ether sent to it with no way
// to get it back.
contract Sink {
    function() public payable { }
}

contract Caller {
    function callTest(Test test) public {
        test.call(0xabcdef01); // hash does not exist
        // results in test.x becoming == 1.

        // The following will not compile, but even
        // if someone sends ether to that contract,
        // the transaction will fail and reject the
        // Ether.
        //test.send(2 ether);
    }
}


Solidity是用于编写智能合约的编程语言,在区块链开发中应用广泛,而Web.js(如web3.js)则是用于与区块链进行交互的JavaScript库,二者在区块链前端开发中紧密相关。 在岗位方面,Solidity开发主要负责智能合约的开发,从业者除了要了解相关的Solidity语法知识,还需要接触各种dapp,该岗位在上海、深圳、北京较多,其他省份基本没有;而web3.js开发与传统的web2前端开发工程师类似,学习基础的前端知识,多了解一个web3的库即可,主要开发前端js代码,通过js进行合约交互和绘制合约界面,EVM开发岗位较多,需要了解EVM底层原理 [^1]。 从技术应用层面看,对于前端开发者而言,Web2应用的开发主要依赖于传统的Web技术,如HTML、CSS、JavaScript等;而Web3应用的开发,如涉及Solidity应用前端,需要掌握更多的区块链技术、去中心化技术以及智能合约编程等方面的知识,同时也需要更加注重用户隐私和安全等方面的考虑 [^3]。 在使用web3.js与Solidity合约交互时,web3可通过contract调用部署的合约,这里的合约通常是用Solidity语言编写的。web3本身也有一些api可以直接和区块链交互。不过,不同区块链上即便为同一种代币,也是不互相关联的,可看成是两个数据库的数据。并且不同版本的web3方法可能不一样,文档有些又不全,需要类比和阅读源码,多次测试 [^2]。 以一个web3博客系统为例,其涉及的技术栈包括Next.js、Polygon、Solidity、The Graph、IPFS、Hardhat等,其中Hardhat是Ethereum开发环境,web3modal可方便快速地连接钱包等 [^4]。 以下是一个简单的使用web3.js调用Solidity合约的示例代码: ```javascript const Web3 = require('web3'); // 假设已经部署的合约地址和ABI const contractAddress = 'YOUR_CONTRACT_ADDRESS'; const contractABI = [/* 合约ABI */]; // 初始化web3实例 const web3 = new Web3('YOUR_PROVIDER_URL'); // 获取合约实例 const contract = new web3.eth.Contract(contractABI, contractAddress); // 调用合约的某个方法 contract.methods.someFunction().call() .then(result => { console.log('合约方法调用结果:', result); }) .catch(error => { console.error('调用合约方法时出错:', error); }); ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值