solidity基础语法与简单案例20221130

1、Todolist(日程表)练习

包括增删改查和使用地址获取结构体

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

contract Todolist{
    struct Todo{
        string text;
        bool complete;
    }

    Todo[] public todos;
    
    //构建能够从地址映射构建内容的mapping
    mapping(address=>Todo) public WhoOwnTodo;

    function create(string calldata _text) external{
        Todo memory todo;
        todo.text = _text;
        todo.complete = false;
        todos.push(todo);
        // todos.push(Todo({
        //     text:_text,
        //     complete:false
        // }));
        WhoOwnTodo[msg.sender] = todo;
    }
    function updateText(uint _index,string calldata _text) external{
        //如果仅需要修改结构体中的一个内容:
        todos[_index].text = _text;

        //如果需要修改结构体中的多个内容:        
        // Todo storage todo = todos[_index];
        // todo.text = _text;
        // todo.complete = true;
    }
    //根据索引获取数组
    function get(uint _index) external view returns(string memory,bool){
        
        //将todo装在storage中比装在内存memory中的gas更少。
        Todo storage todo = todos[_index];
        return (todo.text,todo.complete);
    }
    function change_complete(uint _index) external{
        todos[_index].complete = !todos[_index].complete;
    }
    function gettodo(address _addr) external view returns(Todo memory){
        return WhoOwnTodo[_addr];
    }
}

2、事件event

        是用于记录当前智能合约运行状态的方法,体现在区块链浏览器上以及交易记录的log,通过事件可以查询改变过的状态。

        包括构建事件和触发事件。

        事件是写入方法,不能标记为view和pure。

        Log:自定事件        

        IndexedLog:具有索引的事件,可以利用用户地址查询所有用户在区块链上发生过的事情。类似传统数据库的检索,有索引的变量最多只能有三个。

        Message:有from和to地址,该事件具有两个区块链地址。  

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

contract Event{
    //log是可自定义的事件
    event Log(string message,uint val);
    //据有索引的事件,当索引不同时,值也不同
    event IndexedLog(address indexed sender,uint val);

    function example() external{
        emit Log("foo",1234);
        emit IndexedLog(msg.sender,789);
    }

    //包含从A地址到B地址以及相关信息的事件
    event Message(address indexed _from,address indexed _to, string message);
    function sendMessage(address _to, string calldata message) external{
        emit Message(msg.sender, _to, message);
    }
}

3、继承

合约继承:B is A

合约方法覆写:virtual、override

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

//能够被覆写的函数能需要使用virtual修饰词
contract A{
    function foo() public virtual pure returns (string memory) {
        return"A";
    }

    function bar() public virtual pure returns (string memory) {
        return"A";
    }

    //more code
    function baz() public pure returns (string memory){
        return"A";
    }
}

//在覆写函数的时候需要使用override修饰词
contract B is A{
    function foo() public pure override returns (string memory){
        return"B";
    }
    function bar() public override virtual pure returns (string memory){
        return"B";
    }
}

contract C is B{
    function bar() public override pure returns (string memory){
        return"C";
    }
}

4、多线继承

多线继承是指:

        X

  /      |

Y       |       

  \       |

          Z

Y继承X,Z继承X和Y,这种多重继承关系。

在构建多线继承时,要先梳理继承关系,在新的函数继承时,将继承最少的函数放在最前面,继承最多的函数放在最后面。

并且要在override后添加继承的合约名称

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

contract X{
    function foo() public pure virtual returns(string memory){
        return "X";
    }
    function bar() public pure virtual returns(string memory){
        return "X";
    }
    function x() public pure returns(string memory){
        return "X";
    }
}

contract Y is X{
    function foo() public pure virtual override returns(string memory){
        return "Y";
    }
    function bar() public pure virtual override returns(string memory){
        return "Y";
    }
    function y() public pure returns(string memory){
        return "Y";
    }
}

contract Z is X,Y{
    function foo() public pure virtual override(X,Y) returns(string memory){
        return "Z";
    }
    function bar() public pure virtual override(X,Y) returns(string memory){
        return "Z";
    }

}

5、继承的构造函数

按照继承的顺序进行构造

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

contract A{
    string public name;

    constructor(string memory _name){
        name = _name;
    }
}

contract B{
    string public text;

    constructor(string memory _text){
        text = _text;
    }
}

//提前输入固定的内容进行子合约的构造函数设定
contract V is A("A"),B("B"){
}

//通过后续输入信息来传导构造函数
contract VV is A,B{
    constructor(string memory _name,string memory _text) A(_name) B(_text) {
    }
}

contract VVV is A("a"),B{
    constructor(string memory _text) B(_text){

    }
}

6、调用父合约已被重写的函数

可以使用子合约调用已经被重写了的函数。

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

contract E{
    event Log(string message);

    function foo() public virtual{
        emit Log("E.foo");
    }
    function bar() public virtual{
        emit Log("E.bar");
    }
}

contract F is E{
    function foo() public override{
        emit Log("F.foo");
        E.foo();
    }

    function bar() public override{
        emit Log("F.bar");
        super.bar();
    }
}

7、可视范围

private 仅内部合约可使用,外部和继承合约不可使用

internal 内部合约和继承合约可使用,外部不可使用

public 内部、继承和外部均可使用

external  内部、外部可使用,继承合约不可使用

8、不可变量

immutable:用于函数修饰词,该函数在构建合约时作为变量,以后变为不可修改的常量,用于减少gas。

9、支付ETH

payable:可向合约发布主币

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

contract Payable{
    address payable public owner;

    constructor(){
        owner = payable(msg.sender);
    }

    function deposit() external payable{}

    function getBalance() external view returns (uint) {
        return address(this).balance;
    }

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值