Solidity - 基本类型、函数等内容

基本类型

基本类型 说明 示例
string 字符串,UTF8编码 "Hello World","世界"
bool 布尔类型 true,false

int

( int8,int16,int24... int256 )

有符号整数(负数,0,正数)

从8位开始到256位,每次步长8位

int = int256

-100,0,2980

uint

(uint8,uint16,uint24... uint256 )

无符号整数(0,正数)

从8位开始到256位,每次步长8位

uint = uint256

0,1016
address 地址,表示外部账户或合约账户,可用来转账

0x35eb43fxxxx78c905dc148f21

例:基本类型示例

pragma solidity^0.6.0;

contract demo{
    string public name;
    int8 public age;
    int32 salary;
    bytes32 public authHash;

    constructor(string memory _name,int8 _age, int32 _salary) public{
        name = _name;
        age =_age;
        salary = _salary;
        authHash = keccak256(abi.encode(_name,_age,_salary));
    }
}

若使用0.8.7版本,则会出现2个警告提示:

Solidity - 基本类型、函数等内容_第1张图片

解决:(1)警告一:在首行增加SPDX许可标识符;(2)constructor去除修饰符public

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

contract demo{
    string public name;
    int8 public age;
    int32 salary;
    bytes32 public authHash;

    constructor(string memory _name,int8 _age, int32 _salary) {
        name = _name;
        age =_age;
        salary = _salary;
        authHash = keccak256(abi.encode(_name,_age,_salary));
    }

}

内建对象

block 区块信息

内建对象 类型 说明
block.coinbase address 当前块的矿工地址
block.difficulty uint 当前块的难度系数
block.gaslimit uint 当前块gas的上限
block.number uint 当前块的编号
blockhash bytes32 返回指定块的哈希值
block.timestamp uint 当前块的时间戳,等于now

msg 调用时数据

内建对象 类型 说明
msg.data bytes 完整的calldata
msg.gas uint 剩余的gas量
msg.sender address 消息发送方(调用者)地址
msg.sig bytes4 calldata的前四个字节(即函数标识符)
msg.value uint 所发送的消息中以太的数量(单位wei)

例:生成一个随机数。 

pragma solidity^0.6.0;

contract random{
    address public sender;
    bytes32 public block_hash;
    uint256 public time;
    uint256 public random_num;

    constructor() public {
        sender = msg.sender;
        block_hash = blockhash(0);
        time = block.timestamp;
        random_num = uint256(keccak256(abi.encode(sender,block_hash,time))) % 100;

    }

}

函数

定义:function func_name(paramlist...) modifiers returns (returnlist...)

定义内容 说明
function 函数声明的关键字
func_name 自定义函数名
paramlist 参数列表,可以有0或多个参数;格式:参数类型 参数名称
modifiers 函数修饰符
returns 返回值关键字
returnlist 返回值类型列表,可以同时返回多个值,不超过7个

例:求1到100自然数之和。 

pragma solidity^0.6.0;

contract sum{

    function addFrom1to100() public view returns(int16) { 
        int16 sum;             
        int8  i;  
        for (i=1; i <101; i++) {
            sum += i;
        }
        return sum;
    }
}

例:比较两个字符串是否相等

pragma solidity^0.6.1;

contract compareString{

    function compareStr(string memory a, string memory b) public pure returns(bool) {
        bytes32 a_hash = keccak256(abi.encode(a));
        bytes32 b_hash = keccak256(abi.encode(b));

        return a_hash == b_hash;
    }
}

编译部署后如下图所示: 

Solidity - 基本类型、函数等内容_第2张图片

特殊修饰符

修饰符 分类 说明
public 调用控制类 都可以调用该函数,和private互斥
private 调用控制类 只有该合约可以调用,和public互斥,子类不可继承
external 调用控制类 外部函数,外部正常访问,内部不可以调用,子类可继承
internal 调用控制类 内部函数,内部正常访问,外部不可以访问,子类可继承
view 状态变量访问控制类 合约不修改状态变量
constant 状态变量访问控制类 合约不修改状态变量,与view一样,目前已废除
pure 状态变量访问控制类 合约不修改状态变量,也不读取状态变量,如上面例子 “比较两个字符串是否相等” 的例子
payable         资金控制类 涉及以太币转移,即可支付的
自定义修饰 自定义控制类 支持自定义修饰符号modifier

例:函数修饰案例

pragma solidity^0.6.0;

contract functionModifier{

    //状态变量
    uint16 count;

    //设置状态变量,使用外部函数修饰符external
    function setCount(uint16 _count) external {
        count = _count;
    }

    //获取状态变量,使用修饰符view
    function getCount() public view returns(uint16) {
        return count;
    }

    //充值,使用支付修饰符payable
    //通过 设置value的值 给合约账户充值
    function deposit() public payable {
        
    }

    //查询合约账户余额,使用view修饰符
    function getContractAccountBalance() public view returns (uint256){
        return address(this).balance;  //this为本合约对象
    }
}

Solidity - 基本类型、函数等内容_第3张图片

以上在Remix可以看到不同修饰符对就的颜色也不一样:

红色:产生资金交易,消耗gas,使用修饰符payable;

桔色:修改状态变量,消耗gas,使用修饰符external;

蓝色:不修改状态变量,使用修饰符view

例:充值&提现

pragma solidity^0.6.0;

contract depositAndWithdraw{

    //充值,从调用者账户向合约账户充值
    function deposit() public payable{

    }

    //提现,从合约账户向调用者账户转账
    function withdraw(uint256 _amount) public payable{
        msg.sender.transfer(_amount);
    }

    //查询合约余额
    function getContractAccountBalance() public view returns(uint256) {
        return address(this).balance;
    }

    //查询调用者账户余额
    function getSenderAccountBalance() public view returns (uint256) {
        return msg.sender.balance;
    }

}

使用0.8.7版本编写遇到错误:TypeError: "send" and "transfer" are only available for objects of type "address payable", not "address".

Solidity - 基本类型、函数等内容_第4张图片 需要将其改写为如下:

    //提现,从合约账户向调用者账户转账
    function withdraw(uint256 _amount) public payable{
        payable(msg.sender).transfer(_amount);
    }

复合类型

类型 说明
T[N] 定长数组,N为数组长度
T[] 动态数组,使用push推入
struct 结构体
mapping(T1=>T2) 映射表
bytesN 字节数组,N为1~32整数

例:数组类型案例

pragma solidity^0.6.0;

contract array{
    //定长数组
    string[3] public names;

    //动态数组
    int8[] public ages;

    constructor() public {
        names[2] = "tracy";
        ages.push(25);
    }

    //获取数组长度
    function getLength() public view returns(uint256,uint256) {
        //使用数组变量名.length获取长度
        return (names.length,ages.length);
    }

    //定长数组转换变长数组
    function arrayToslice() public view returns (string[] memory) {
        //定义一个变长数组,将定长数组值copy
        string[] memory _names = new string[] (names.length);
        for (uint256 i = 0; i < names.length; i++) {
            _names[i] = names[i];
        } 
        return _names;
    }
}

Solidity - 基本类型、函数等内容_第5张图片

例:mapping类型案例

pragma solidity^0.6.0;

contract mappingEx{

    //定义一个mapping,key表示地址,value表示地址对应的用户名
    mapping(address=>string) public addr_name;

    constructor() public {
        //调用者账户地址对应的用户初始化
        addr_name[msg.sender] = "tracy";
    }

    //设置地址对应的用户名
    function setName(string memory _name) public {
        addr_name[msg.sender] = _name;
    }

    //根据地址获取用户名
    function getName(address _addr) public view returns (string memory) {
        return addr_name[_addr];
    }

}

Solidity - 基本类型、函数等内容_第6张图片

值传递&引用传递

memory 值传递

storage 引用传递

例:自定义结构体类型与值/引用传递案例

pragma solidity^0.6.1;

//定义一个结构体
struct User{
    string name;
    int8 age;
}

contract structEx{
    //定义状态变量,结构体类型
    User public user;

    constructor() public {
        user.name = "Tracy";
        user.age = 25;
    }
    
    //设置结构体变量中的属性值(使用memory)
    function setName_memory(string memory _name) public{
        User memory user_memory = user;
        user_memory.name = _name;
    }

    //设置结构体变量中的属性值(使用storage)
    function setAge_storage(int8 _age) external {
        User storage user_storage = user;
        user_storage.age = _age;
    }
}

Solidity - 基本类型、函数等内容_第7张图片

使用0.8.7版本时,提示警告信息:

Solidity - 基本类型、函数等内容_第8张图片

需要在函数后面加上修饰符view

    //设置结构体变量中的属性值(使用memory)
    function setName_memory(string memory _name) public view{
        User memory user_memory = user;
        user_memory.name = _name;
    }

断言

断言用于条件不成立时回退之前的操作。

function assert(bool cond_expr);

对用户惩罚,扣光所有gas。用于内部变量判断,pure函数或检测系统错误。

function require(bool cond_expr, string msg);

相对温和,退还剩余的gas。用于业务逻辑判断。

例:断言案例

pragma solidity^0.6.0;

contract assertEx{
    function deposit(uint256 _amount) public payable {
        //充值判断
        require(msg.value == _amount, "msg.value 必须等于_amount参数值");
        assert(_amount > 0);
    }
}

Solidity - 基本类型、函数等内容_第9张图片

当执行assert时,扣光所有gas

Solidity - 基本类型、函数等内容_第10张图片

使用0.8.7版本时,报错如下:

Solidity - 基本类型、函数等内容_第11张图片 需要去除require函数的第2个参数

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

contract assertEx{
    function deposit(uint256 _amount) public payable {
        //充值判断
        require(msg.value == _amount);
        assert(_amount > 0);
    }
}

自定义修饰符modifier

modifier modifier_name(){

        require(bool cond_expr, "error message");

        //...

        _; //占位符号,标识modifier的结束

}

//减少重复代码产生

例:自定义修饰符案例 - 只有管理员才能访问

pragma solidity^0.6.0;

contract modifierEx{
    //定义的一个地址状态变量
    address public admin;
    string name;

    //初始化状态变量为调用者,即部署合约的账户地址
    constructor() public {
        admin = msg.sender;
    }

    //自定义修饰符,只有部署合约的账户地址才能访问
    modifier onlyadmin{
        require(msg.sender == admin, "只有部署合约的用户才能访问此函数");
        _;
    }

    //此函数只有部署合约的用户才能访问
    function setValue() external onlyadmin {
        name = "tracy";
    }
}

Solidity - 基本类型、函数等内容_第12张图片

更多信息可参见官网文档:Solidity — Solidity develop 文档

你可能感兴趣的:(智能合约,智能合约)