首页 > 其他分享 >Solidity基本语法学习3

Solidity基本语法学习3

时间:2023-12-09 16:12:08浏览次数:28  
标签:function 学习 return text Solidity 语法 returns uint public

文档: https://solidity-by-example.org/
视频教程: https://www.youtube.com/watch?v=xv9OmztShIw&list=PLO5VPQH6OWdVQwpQfw9rZ67O6Pjfo6q-p

说明:

本文内容: Enum, struct, data location, function, View and Pure Function, Error

Enum(枚举)

Solidity支持枚举,这对model choicekeep track of stack很有用。
枚举可以在contract之外声明。
跟其它编程语言类似, 枚举类默认都可以用数字替代, Solidity默认是用的uint8.

// SPDX-License-Identifier: MIT
pragma solidity ^0.8;
enum Status { Single, Married }
// SPDX-License-Identifier: MIT
pragma solidity ^0.8;
import "./EnumDeclaration.sol";
contract Enum {
    // 对应了0, 1, 2, 3
    enum Season { Spring, Summer, Autumn, Winter }
    
    Season public season;
    Status public status;
    function get() public view returns (Season){
        return season;
    } 
    function set(Season s) public {
        season = s;
    }
    function updateToWinter() public {
        season = Season.Winter;
    }
    function deleteToDefault() public {
        delete season; // 恢复成默认值: Spring, 也可以说是0
    }
    function getStatus() public view returns (Status){
        return status;
    }
    function setStatus(Status _status) public {
        status = _status;
    }
}

img

struct

这位更是重量级, 终于能自定义类型了.
可以通过创建struct来定义自己的类型。它们对于将相关数据分组很有用。
struct可以在contract外部声明,并在另一个contract中导入。

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

struct MyTodoStruct{
    string text;
    bool completed;
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.8;
import "./MyTodo.sol";
// 跟enum一样, 都可以通过外部引入. 
contract Todos {
    struct Todo {
        string text;
        bool completed;
    }

    Todo[] public todos;

    function create(string calldata _text) public {
        // 3 ways to initialize a struct
        // - calling it like  a function
        todos.push(Todo(_text,false));

        //  key value mapping
        todos.push(Todo({text: _text, completed: false}));

        // initialize an empty struct and then update it
        Todo memory todo;
        todo.text = _text;
        // todo.completed initialied tofalse

        todos.push(todo);
    }

    // Solidity automatically created a getter for 'todos' so
    // you don't actually need this function.
    function get(uint _index) public view returns(string memory text, bool completed){
        Todo storage todo = todos[_index];
        return (todo.text, todo.completed);
    }

    function updateText(uint _index,  string calldata _text) public {
        Todo storage todo = todos[_index];
        todo.text = _text;
    }

    function toggleCompleted(uint _index) public {
        Todo storage todo = todos[_index];
        todo.completed = !todo.completed;
    }
}

Data Locations - Storage, Memory and Calldata

变量声明为storagememorycalldata,以显式指定数据的位置。

  • storage变量是一个状态变量(存储在区块链上)
  • memory变量在内存中,当函数被调用时它才存在
  • calldata 包含函数参数的特殊数据位置. Calldata arrays are read-only.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

contract DataLocations {
    uint[] public arr;
    mapping(uint => address) map;
    struct MyStruct {
        uint foo;
    }
    mapping(uint => MyStruct) myStructs;

    function f() public {
        // call _f with state variables
        _f(arr, map, myStructs[1]);

        // get a struct from a mapping
        MyStruct storage myStruct = myStructs[1];
        // create a struct in memory
        MyStruct memory myMemStruct = MyStruct(0);
    }

    function _f(
        uint[] storage _arr,
        mapping(uint => address) storage _map,
        MyStruct storage _myStruct
    ) internal {
        // do something with storage variables
        
    }

    // You can return memory variables
    function g(uint[] memory _arr) public pure returns (uint[] memory) {
        // do something with memory array
        for(uint i = 0; i < _arr.length; i++){
            unchecked{_arr[i] -= 1;}
        }
        return _arr;
    }

    uint[] public _arrh;
    function h(uint[] calldata _arr) external {
        // do something with calldata array
        // 修改的时候:TypeError: Calldata arrays are read-only.
        for(uint i = 0; i < _arr.length; i++){
            _arrh.push(_arr[i]);
        }
    }
}

注意输入数组的方式. ["1","2","3"]或者[1,2,3]才行
img

Function

有几种方法可以从函数返回输出。
公共(public, external)函数不能接受某些数据类型(比如map)作为输入或输出

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

contract Function {
    //  Functions canreturn  multiple values.
    function returnMany() public pure returns(uint, bool, uint){
        return (1, true, 2);
    }

    // Return values can be named.
    function named() public pure returns(uint x, bool b, uint y){
        return (1, true, 2);
    }

    // Return values can  be assigned to their name.
    // In this case the return statement can be omitted. 
    function assigned() public pure returns(uint x, bool b, uint y){
        x = 1;
        b = true;
        y = 2;
    }

    // Use destructuring assignment when calling another
    // function that returns multiple values.
    function destructuringAssignments() 
        public
        pure 
        returns(uint, bool, uint, uint,  uint){
            (uint i,bool b,uint j)= returnMany();

            // values can be left out.
            (uint x, , uint y) = (4,5,6);
            return (i,b,j,x,y);
        }

    // Cannot use map for either input or output

    // Can use array for input
    function arrayInput(uint[] memory _arr) public {}

    // Can use array for output
    uint[] public arr;

    function arrayOutput() public view returns(uint[] memory){
        return arr;
    }

}

contract XYZ {
    function someFunWithManyInput(
        uint x,
        uint y,
        uint z,
        address a,
        bool b,
        string memory c
    ) public pure returns (uint) {}

    function callFunc() external pure returns(uint) {
        return someFunWithManyInput(1, 2, 3, address(0), true, "c");
    }

    function callFuncWithKeyValue() external pure returns (uint){
        return 
            someFunWithManyInput({a: address(0),  b: true, c: "c", x: 1, y: 2, z: 3});
    }
}

View and Pure

Getter类型的函数可以声明为viewpure

  • view函数声明状态不会被改变
  • pure函数声明不改变或读取状态变量。

Remix IDE会告诉你什么时候用哪个关键词.

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

contract ViewAndPure {
    uint public x = 1;

    // Promise not to modify the state.
    function addToX(uint y) public view returns (uint) {
        return x + y;
    }

    // Promise not to modify or read from the state.
    function add(uint i, uint j) public pure returns (uint) {
        return i + j;
    }
}

Error

error将撤销在transaction期间对state所做的所有更改。
可以通过调用require、revert或assert抛出错误。

  • require用于在执行之前验证输入和条件。
  • revert类似于require。有关详细信息,请参阅下面的代码。
  • assert用于检查不应该为false的代码。断言失败可能意味着存在错误。

使用自定义错误(custom error, 0.8版本新特性)来节省燃气。

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

contract Error {
    function testRequire(uint _i) public pure {
        // Require should be used to validate conditions such as:
        // - inputs
        // - conditions before execution
        // - return values from calls to other functions
        require(_i > 10, "input must be greater than 10");
    }

    function testRevert(uint _i) public pure {
        // Revert is useful when the condition to check is complex.
        // This code does the exact same thing as the example above
        if(_i <= 10){
            revert("input must be greater than 10");
        }
    }

    uint public num;

    function testAssert() public view {
        // Assert should only be used to test for internal errors,
        // and to check invariants.

        // Here we assert that num is always equal to 0
        // since it is impossible to update the value of num
        assert(num == 0);
    }

    error InsufficientBalance(uint balance, uint withdrawAmonut);

    function testCustomError(uint _withdrawAmount) public view {

        uint bal = address(this).balance;
        if(bal < _withdrawAmount){
            // 测试可以用0和1去看输出的区别
            revert InsufficientBalance({balance: bal, withdrawAmonut: _withdrawAmount});
        }
    }
}

标签:function,学习,return,text,Solidity,语法,returns,uint,public
From: https://www.cnblogs.com/joey-redfield/p/17891087.html

相关文章

  • iptables 学习
    iptables一、图二、规则写法格式:iptables[-ttable]COMMANDchainCRETIRIA-jACTION-ttable:3个filternatmangleCOMMAND:定义如何对规则进行管理chain指定你接下来的规则到底是在哪个链上操作的,当定义策略的时候是可以省略的CRETIRIA:指定匹配标准-jA......
  • 2023-2024-1 20232301 《网络》第5周学习总结
    教材学习内容总结教材学习中的问题和解决过程问题1:对于基于语义的海量媒体内容特征快速提取与分类技术,书上暂未举出具体例子,使我在理解上稍有欠缺问题1解决方案:通过不断询问chatgpt,我得到了以具体的体育文章为实例的回答,如下:“当涉及到基于语义的海量媒体内容提取与分类技术......
  • 用 C/C++ 编写一个 C 语言的语法分析器程序
    任务描述本关任务:用C/C++编写一个C语言的语法分析器程序。相关知识为了完成本关任务,你需要掌握:1.DFANFA,2.C/C++编程语言基础。3.C语言的基本结构知识自动机在编译原理课堂上已经教授了大家相关知识。在完成本实训前,一定要先设计相关自动机,再开始相关功能的实现。切勿......
  • Redis学习记录第七天
        今天我们继续深入学习Redis,探讨了Redis的数据结构类型以及一些高级功能。首先,我们先来回顾一下Redis支持的数据结构类型:String(字符串):最基本的数据结构类型,可以存储字符串、数字等数据。Hash(哈希):键值对的集合,可以用于存储对象,支持添加、删除、获取单个或多个键值对。Lis......
  • 分布式学习记录,第三天
       在分布式学习的探索之旅中,我们继续深入学习并实践了分布式学习的核心概念和技巧。第三天,我们主要关注于分布式学习中的同步和异步策略,以及如何优化通信开销以进一步提高学习效率。    首先,我们讨论了分布式学习中的同步策略。同步策略是指在所有计算节点上同时进......
  • python+sklearn 机器学习代码备忘
    importsklearnfromsklearn.model_selectionimporttrain_test_splitfromsklearn.linear_modelimportLinearRegressionimportpandasaspdimportmatplotlib.pyplotaspltimportseabornassnsfromsklearnimportpreprocessingimportcsvimportnumpyas......
  • 2023-2024-1 20231424《计算机基础与程序设计》第11周学习总结
    2023-2024-120231424《计算机基础与程序设计》第11周学习总结作业信息作业属于的课程<班级链接>(2022-2023-1-计算机基础与程序设计)作业要求<作业要求>(2022-2023-1计算机基础与程序设计第一周作业)作业目标《计算机科学概论》第15,16章和《C语言程序设计》第10章......
  • 2023-2024-1 20232327《网络空间安全导论》第五周学习总结
    2023-2024-120232327《网络空间安全导论》第五周学习总结教材学习内容总结1.信息内容安全是研究利用计算机从包含海量信息并且迅速变化的网络中对特定安全主题相关信息进行自动获取、识别和分析的技术;2.网络爬虫是按照一定规则,自动抓取有互联网信息的程序或脚本;3.信息过滤是......
  • 人工智能基础笔记 · Part C 群体智能和强化学习
    C6群体智能核心思路:大自然中的一些社会系统尽管由简单的个体组成,却表现出智能的集体行为。称Agents为“智能体”。对问题的智能解决方案,自然地涌现于这些个体的自组织和交流之中。整个系统的行为是自下而上的,遵循简单规则的简单Agents生成复杂的结构/行为,且Agents不遵循......
  • 学习riscv(1)安装tinyriscv的工具链
    因为毕设是CPU的低功耗设计,所以开始看cpu,打算还是先从这个tinyriscv学起,昨天把环境下好了,第一步是用git去clone代码,这个首先要下载git,然后在目标文件夹鼠标右键,选择“opengitbushhere”,再输入项目的url,就可以了。方法不难。b站有详细教程接下来是安装工具,我用的是wind......