solidity(智能合约)零基础教学(3)

这篇具有很好参考价值的文章主要介绍了solidity(智能合约)零基础教学(3)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言:前面我们将了solidity的一些常用方法,接下来我们来讲一下,我们编写合约经常要用的一些功能;

一,modifier修饰符

在Solidity合约中,修饰符(modifier)是一种用于修改函数行为的特殊函数。通过使用修饰符,我们可以在执行函数之前、之后或中途对函数进行某些操作或检查。我们通常会和异常一起使用;

详细代码如下:

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

contract text{
    //案例一:
      address public owner;//初始值为0X000000000...

      constructor(){
          //定义一个构造函数,初始值为合约部署者的地址
          owner = msg.sender;
      }

    //定义一个修饰符,这个修饰符的意思是只能是合约部署者才能执行,其他地址的用户执行会抛出异常
      modifier Onlyowner(){
          require(msg.sender==owner, "you are not owner");
          _;//这行代表我们要引用方法的语句,写在什么位置,就在什么地方去执行
      }

    //定义一个修饰符,这个修饰符的意思是合约不能为空,否者抛出异常
      modifier Vali(address add){
          require(add != address(0) , "Not valid address");
          _;
      }

    //方法中,后面接着就是我们的修饰符
      function modifowner(address newowner)public Onlyowner Vali(newowner){ 
          owner = newowner;
      }



    //案例二:
    uint public x =10;
    bool public locked; //初始值为false
    
    //定义一个修饰符,这个修饰符的作用是,执行期间抛出异常,就不会执行。防止死循环
    //我们可以看到“_;”在中间,我们首先会把locked 赋值为真,再执行被调用的方法,又会把locked重新赋值为假
    modifier noReentrancy{
        require(!locked, "No reentrancy");
        locked = true;
        _;
        locked = false;
    }

    function decrement(uint i)public noReentrancy{
        x -= i;
        if(i > 1){
            decrement(i-1);
        }
    }


}

2,Event事件

当我们写合约的时候,为了更好和前端交互,且减少更多gas的消耗,我们常常会用到事件来处理;他更是存储着我们的日志文件;

  1. 合约状态变化通知:当合约的状态发生重要变化时,可以使用 Event 来通知外部观察者。例如,当合约转移资产所有权,发生交易,或者某个权限被更改时,可以通过 Event 向外部发送通知。外部观察者可以监听合约中定义的 Event,并做出相应的处理或响应。

  2. DApp 触发和反应:在分布式应用程序中,Event 是 DApp 与合约之间的重要接口。DApp 可以监听合约中定义的 Event,以便触发某些操作或更新界面。当合约状态发生变化时,Event 可以通过 DApp 反馈给用户,提供实时的状态更新和交互。

  3. 历史记录和审计:Event 可以用于记录合约执行过程中的重要事件。通过记录 Event,可以在之后进行审计或查看历史记录。例如,在一个众筹合约中,可以使用 Event 记录每次捐款的细节,以便后续审计捐款阶段的数据。

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;
contract Event{

    //事件参数最多只能有3个,下面我们定义了两个参数的事件和一个参数的事件;
    event Log(address indexed  sender , string message);
    //在Solidity合约中,indexed 是一个用于声明事件参数的关键字。
    //使用 indexed 可以使得事件参数具有索引功能,从而提供更高效的事件过滤和查询。
    event AnotherLog();

    //这里我们定义了一个方法调用我们的事件
    function test() public {
        //emit要对应上面我们定义的事件 
        emit Log(msg.sender, "Hello World");
        emit Log(msg.sender, "Hello Event");

        emit AnotherLog();

    }
}

部署完合约以后,我们点击debug边上的下拉箭头,可以看到我们的日志信息

智能合约函数的修饰符,智能合约,区块链

3,调用其他合约

创建两个contract合约或者是使用import引用其它合约中的数据;类似于java一样,需要实例化,也就是new一个对象出来;

这段代码我们就沿用上面写的程序;主要是下面的contract;

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

contract Event{

    //事件参数最多只能有3个,下面我们定义了两个参数的事件和一个参数的事件;
    event Log(address indexed  sender , string message);
    //在Solidity合约中,indexed 是一个用于声明事件参数的关键字。
    //使用 indexed 可以使得事件参数具有索引功能,从而提供更高效的事件过滤和查询。
    event AnotherLog();

    //这里我们定义了一个方法调用我们的事件
    function test() public {
        //emit要对应上面我们定义的事件 
        emit Log(msg.sender, "Hello World");
        emit Log(msg.sender, "Hello Event");

        emit AnotherLog();

    }
}

contract constructorsolidity{
    //这里我们调用上面的合约,
    Event public eve;

    function Creat() public {
        eve = new Event();
    } 
}

智能合约函数的修饰符,智能合约,区块链

 运行的时候,我们选择下面的合约部署;至此我们简单的调用其他合约就成功了;

接下里介绍第二种方法使用import调用。当使用import关键字导入合约时,需要提供合约文件的路径。路径可以是绝对路径,也可以是相对路径。绝对路径是相对于项目根目录或源文件的根目录,而相对路径是相对于当前合约文件的路径。

我们可以清晰的看到,代码量减少了很多,提高了代码的可复用性;

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

//用import引用外部sol文件
import "./three.sol";

contract constructorsolidity{
    //这里我们调用上面的合约,创建一个Event对象;
    Event public eve;

    //给eve对象实例化;这样就拥有里面的数据了;
    function Creat() public {
        eve = new Event();
    }
    
    
}

当我们想引用别的合约的数据的时候,用 . 来引用就行了。

4,继承is标签

在Solidity中,合约之间可以通过继承来建立关系。一个合约可以继承另一个合约,并继承合约的属性(状态变量)和方法(函数)。被继承的合约称为父合约或基合约,继承它的合约称为子合约或派生合约。

通过继承,子合约可以继承父合约的属性和方法,从而拥有父合约的行为和功能。这样做可以实现代码的重用和模块化,提高代码的可读性、可维护性和可扩展性。

在Solidity中,使用is关键字来声明继承关系。例如,定义一个名为ChildContract的子合约继承自ParentContract的父合约,可以使用如下语法:

contract ParentContract {
    // 父合约的属性和方法
}

contract ChildContract is ParentContract {
    // 子合约的属性和方法
}

子合约继承父合约后,可以访问父合约的属性和方法。子合约也可以重写父合约的方法,并且可以使用super关键字来调用父合约的方法。

需要注意的是,Solidity中只支持单继承,即一个合约只能继承一个父合约。但是一个合约可以被多个合约继承,从而形成更复杂的继承关系。

继承是Solidity中实现代码重用和模块化的重要机制。通过继承,可以在合约中扩展已有的功能和属性,避免重复编写代码,提高代码的复用性和可维护性。

5,编写第一个Dapp(捐款系统)

代码的解释我在文档有注释,先说一些,界面使用问题吧!

选择多个账户,这里每个账户都有100以太坊;

智能合约函数的修饰符,智能合约,区块链

 文章来源地址https://www.toymoban.com/news/detail-843747.html

更换货币符号

智能合约函数的修饰符,智能合约,区块链

直接转账到我们的目标账户

 智能合约函数的修饰符,智能合约,区块链

 

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;
contract FundMe{

    //部署一个用户地址,用immutable,减少gas的消耗
    address immutable public ower ;
    address[] public funder;
    mapping (address => uint) public map;
    constructor(){
        ower = msg.sender;
    }

    //有payable意思是,可以往里面存以太坊
    function Fund()public payable {
        //设置一个异常,捐款不能小于一个以太坊
        require(msg.value >= 1e17, "The amount is too small, please enter a suitable amount");
        //把我捐款的地址放到地址数组中,方便后续查找,有那些人捐款过
        funder.push(msg.sender);
        //把金额放到mapping中,方便查询用户存款的金额
        map[msg.sender] = msg.value;
    }

    function count() public view returns(uint){
        return funder.length;
    }

    //设置,只允许部署合约者,提款
    modifier onlyOwer{
        require(msg.sender == ower, "not adderss contract!");
        _;
    }

    //直接转钱过来的两个功能,及时只转账,也会记录转账人的地址和金额
    receive() external payable {
        Fund();
    }

    fallback() external  payable {
        Fund();
    }

    function withdraw() public onlyOwer {
        
        //方法一,已经淘汰了的,偏向与底层代码,定义一个bool类型的值,获得账户的地址,将账户提现到自己账户上;
        // bool sendSuccess = payable(msg.sender).send(address(this).balance);
        // require(sendSuccess, "transation failed");

        //方法二,差不多也被淘汰了,只有少部分人在用
        // payable(msg.sender).transfer(address(this).balance);


        //方法三,现在用的比较多的方法,他的限制比较少,第二种方法,他会有很多限制
        (bool callSuccess,) = payable(msg.sender).call{value:address(this).balance}("");
        require(callSuccess, "fail transaction");

        //当把账户提款到自己账号上时,把捐款地址,金额全部清空;
        for(uint i = 0 ;  i < funder.length ; i++){
            map[funder[i]] = 0;
        }
        //赋值一个新的空mapping数组
        funder = new address[](0); 
    }
}

到了这里,关于solidity(智能合约)零基础教学(3)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 区块链智能合约solidity的中的一些关键字

    目  录 pragma mapping msg对象 block对象 contract constructor struct 数据地址 地址类型 address payable revert 以下场景使用 revert() : require 以下场景使用 require() : assert 以下场景使用 assert(): 访问权限 internal public private external function returns return view pure constant event emit modifier pragma   

    2024年01月16日
    浏览(49)
  • 【区块链-智能合约工程师】第三篇:Solidity进阶(一)

    学习资料地址:WTF学院 库合约一般都是一些好用的函数合集(库函数),为了提升solidity代码的复用性和减少gas而存在。他和普通合约主要有以下几点不同: 不能存在状态变量 不能够继承或被继承 不能接收以太币 不可以被销毁 String库 String库合约是将uint256(大正整数)类型

    2024年02月06日
    浏览(33)
  • 智能合约 Solidity – 构造函数

    构造函数是任何面向对象的编程语言中的一种特殊方法,每当初始化类的对象时都会调用它。Solidity 则完全不同,Solidity 在智能合约内部提供了一个构造函数声明,它只在合约部署时调用一次,用于初始化合约状态。如果没有明确定义的构造函数,则编译器会创建默认构造函

    2024年02月11日
    浏览(23)
  • 区块链web3智能合约Solidity学习资源整理

    Solidity 是一门面向合约的、为实现智能合约而创建的高级编程语言。这门语言受到了 C++,Python 和 Javascript 语言的影响,设计的目的是能在以太坊虚拟机(EVM)上运行。 Solidity中文官方文档: https://solidity-cn.readthedocs.io/zh/develop/ https://learnblockchain.cn/docs/solidity/index.html 在线rem

    2024年03月19日
    浏览(40)
  • solidity函数签名的实现-solidity实现智能合约教程(8)

    猛戳订阅学习专栏🍁🍁 👉 solidity系列合约源码+解析 👈 🍁🍁 函数选择器: solidity调用函数时,calldata的前4个字节为指定要调用的函数,这4个字节称为函数选择器。 以下面的代码为例。它通过地址addr的调用合约的transfer方法。 abi.encodeWithSignature(…)返回的前4个字节是函数

    2024年02月16日
    浏览(21)
  • Solidity智能合约开发 — 3.2-合约的fallback和函数重载

    每个智能合约有且仅有一个未命名的函数,称为fallback函数,没有参数且没有返回值,可见性必须是 external,且可以是 virtual的(即可以被重载),也可以有修改器 modifier。 fallback执行条件: 如果在一个合约的调用中,没有其他函数与给定的函数标识符匹配时(或没有提供调用

    2024年02月09日
    浏览(40)
  • 《NFT区块链进阶指南二》Etherscan验证Solidity智能合约(Remix插件验证)

    前置参考文档:https://blog.csdn.net/sinat_34104446/article/details/130557703 合约验证是上传合约源代码到etherscan过程,在智能合约项目中,通常都是提供源码验证,增加项目信任度 验证合约后可以直接在etherscan上执行获取和设置方法,方便日常的管理员维护 以下使用remix进行验证并使用

    2024年02月05日
    浏览(48)
  • 以太坊智能合约开发:Solidity语言中的构造函数

    Solidity语言中关于构造函数的定义: 构造函数是使用 constructor 声明的一个可选函数; 构造函数只在合约部署时调用一次,并用于初始化合约的状态变量; 如果没有显式定义的构造函数,则由编译器创建默认构造函数。 构造函数声明语法如下: 其中: ** constructor :

    2024年02月01日
    浏览(33)
  • 基于以太坊的智能合约开发Solidity(基础篇)

    参考教程:基于以太坊的智能合约开发教程【Solidity】_哔哩哔哩_bilibili (1)程序编译完成后,需要在虚拟机上运行,将合约部署好后便可执行刚刚编写的函数。(注意, 合约一旦部署,就会永久存在于区块链上,且不可篡改 ,不过可以销毁) (2)执行完成后,可以得到以

    2024年02月04日
    浏览(35)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包