Solidity学习02 函数、存储位置、作用域、单位

函数输出

关键字
retuens:在函数名后面,定义返回值
return:在函数体中,将返回值返回

// SPDX-License-Identifier: MIT
pragma solidity 0.8.0;

contract MyContract {
    int public number = 2;

    // return返回
    function add(int _num) public view returns (int, int) {
        return (number + _num, number * _num);
    }

    // 命名式返回
    function addL2(int _num) public view returns (int res1, int res2) {
        res1 = number + _num;
        res2 = number * _num;
    }

    // 读取返回值后 使用解构赋值,获取返回值中需要的值
    function readReturn() public view {
        int _res1;
        int _res2;

        (_res1, _res2) = add(3);
        (_res1, ) = add(4);
    }
}

数据存储位置与Gas费

Data location can only be specified for array, struct or mapping types

不用存储位置消耗gas不一样。

storage 存储在链上。gas多。
memory 存储在内存中。gas少。
calldata 存储在内存中,但是变量不能修改。常用于函数参数。不消耗gas。
隐式默认数据位置 状态变量默认都存在storage。对于函数参数和返回变量,默认位置是calldata。对于函数内部的局部变量,默认位置是memory。

在 Solidity 中,calldata 数据位置并不存储在内存中。calldata 是一种特殊的数据位置,用于存储外部函数调用时传递的参数数据。它是一个只读的数据区域,存储在调用数据区域中,并且只能在函数执行期间访问。合约只能读取 calldata 中的数据,但不能修改它。因此,与内存不同,calldata 不会消耗合约的存储空间,并且在函数执行结束后会被销毁,不会在合约状态中留下任何痕迹。

赋值本质上是创建引用指向本体,因此修改本体或者是引用,变化可以被同步

contract MyContract1 {
    uint256[] public x = [1, 2, 3]; // 状态变量:数组 x

    //声明一个storage类型的变量指向storage的状态变量。修改后影响状态变量
    function fStorage() public {
        uint256[] storage xStorage = x;
        xStorage[0] = 100;
    }

    //声明一个memory类型的变量指向storage的状态变量。修改后,“不会”影响状态变量
    function fMemory() public view {
        uint256[] memory xStorage = x;
        xStorage[0] = 100;
    }

    // 在函数内部声明memory类型的成员变量a、b,b指向a,需要b后a的值就会变更
    function fMemoryL2() public view returns (uint256) {
        uint256[] memory xStorage = x;
        uint256[] memory xStorage2 = xStorage;
        xStorage2[0] = 100;
        return xStorage[0];
    }
}

变量的作用域

状态变量 数据存在链上。所有合约内的函数都可以访问。gas高。
局部变量 数据在内存中。只在函数执行过程中有效。gas低。
全局变量 都是预留的关键字。

部分全局变量
msg.sender:调用方
msg.data:请求数据
block.number:区块高度

eth单位

由于eth最小单位到小数点后18个零,方便起见,solidity中有3中eth单位
wei:1wei(最小单位)
gwei:1e9 wei
ether:1e18 wei(即1eth)

contract EthUnitContract {
    function TestEthUnit() public pure returns (bool) {
        bool a = 1 wei == 1;
        bool b = 1 gwei == 1e9;
        bool c = 1 ether == 1e18;
        return a && b && c;
    }
}

image

时间单位

由于合约可以规定一个操作必须在一定时间内完成。(这通常涉及使用时间戳和时间单位来跟踪时间,并设置一个截止日期。)
合约可以检查当前时间是否在规定的时间范围内,以确定是否执行某些操作。

pragma solidity ^0.8.0;

contract DeadlineExample {
    uint public deadline;

    constructor() {
        // 设置截止日期为一周后的时间戳
        deadline = block.timestamp + 1 weeks;
    }

    function performAction() public {
        require(block.timestamp <= deadline, "Action deadline has passed");
        // 在截止日期之前执行操作
        // 在此添加操作的代码
    }
}

上面的合约中,构造函数设置了一个截止日期,即当前时间加上一周的时间(以秒为单位)。在performAction函数中,使用require语句来检查当前时间是否在截止日期之前。如果超过了截止日期,合约将拒绝执行操作,并返回错误消息。

其中使用到了时间单位。
时间单位有以下几种:
seconds:1
minutes: 60 seconds = 60
hours: 60 minutes = 3600
days: 24 hours = 86400
weeks: 7 days = 604800

posted @ 2021-01-14 16:06  sorachannel  阅读(461)  评论(0)    收藏  举报