solidity入门(2)

类型


状态类型:Solidity 提供了几种基本类型,并且基本类型可以用来组合出复杂类型。

注意:“undefined”或“null”值的概念在Solidity中不存在。
 

值类型:

  • 布尔类型

bool:true 和 false 

  • 整型

int:有符号的不同位数的整形变量 (int8,int256) 一般int认为是256位

uint:无符号的不同位数的整型变量 ( uint8,uint256)一般uint认为是256位

Solidity中的整数是有取值范围的。 例如 uint32 类型的取值范围是 0 2^32-1;如果数值为2^32,会落到取值范围以外,进行溢出,故而通过失败异常进行调用回退。

  • 定长浮点型

fixed:有符号的定长浮点型,一般fixed默认为fixed128x18r

ufixed:无符号的定长浮点型,一般ufixed默认为ufixed128x18

在关键字ufixedMxN和fixedMxN中,M表示该类型占用的位数,N表示可用的小数位数

M必须能够整除8,并且从8到256位

N必须介于0-80之间,包括0和80

  • 地址类型Address

两种类型:

address:保存一个20字节的值(以太坊地址的大小)160位

address payable:可支付地址,与 address 相同,不过有成员函数 transfer 和 send 。

其实address payable可以接受以太币的地址,而一个普通的 address 则不能。

类型转化:

address payable 到 address 的转换 ,使用    payable(<address>)

address 允许和 uint160、 整型字面常量、bytes20 及合约类型相互转换。

//只能通过 payable(...) 表达式把 address 类型和合约类型转换为 address payable。 只有能接收以太币的合约类型,才能够进行此转换。例如合约要么有 receive 或可支付的回退函数。

1.<address>.balance (uint256)
    //以 Wei 为单位的 查询地址类型 Address 的余额。  

2.<address payable>.transfer(uint256 amount)
    //向 地址类型payable Address 发送数量为 amount 的 Wei。失败时抛出异常,使用固定(不可调节)的 2300 gas 的矿工费。  

    /*如果 x 是一个合约地址,它的代码(更具体来说是, 如果有receive函数, 执行 receive 接收以太函数, 或者存在fallback函数,执行 Fallback 回退函数 函数)会跟 transfer 函数调用一起执行(这是 EVM 的一个特性,无法阻止)。 如果在执行过程中用光了 gas 或者因为任何原因执行失败,以太币Ether 交易会被打回,当前的合约也会在终止的同时抛出异常。*/
  
    address x = 0x123;
    address myAddress = this;
    if (x.balance < 10 && myAddress.balance >= 10) x.transfer(10);


3.<address payable>.send(uint256 amount) returns (bool)
    //向 地址类型 Address 发送数量为 amount 的 Wei,失败时返回 false,发送 2300 gas 的矿工费用,不可调节。当前的合约不会因为异常而终止


4.<address>.code (bytes memory)
    //在 地址类型 Address 上的代码(可以为空)

5.<address>.codehash (bytes32)
    //`address`的codehash

//以下三类是为了与不符合应用二进制接口的合约交互
6.<address>.call(bytes memory) returns (bool, bytes memory)
    //用给定的有效载荷(payload)发出低级 CALL 调用,返回成功状态及返回数据,发送所有可用 gas,也可以调节 gas。

bytes memory payload = abi.encodeWithSignature("register(string)", "MyName");
(bool success, bytes memory returnData) = address(nameReg).call(payload);
require(success);


7.<address>.delegatecall(bytes memory) returns (bool, bytes memory)
    //用给定的有效载荷 发出低级 DELEGATECALL 调用 ,返回成功状态并返回数据,发送所有可用 gas,也可以调节 gas。 发出低级函数 DELEGATECALL,失败时返回 false,发送所有可用 gas,可调节。

8.<address>.staticcall(bytes memory) returns (bool, bytes memory)
    //用给定的有效载荷 发出低级 STATICCALL 调用 ,返回成功状态并返回数据,发送所有可用 gas,也可以调节 gas。

  • 合约类型

每一个合约定义都有他自己的类型。

合约和 address 的数据表示是相同的

合约不支持任何运算符。

合约类型的成员是合约的外部函数及 public 的 状态变量。

  • 定长字节数组

关键字有:bytes1, bytes2, bytes3, …, bytes32。其实字节的意思

可以将 byte[] 当作字节数组使用,但这种方式非常浪费存储空间,准确来说,是在传入调用时,每个元素会浪费 31 字节。 更好地做法是使用 bytes

成员变量:.length  表示这个字节数组的长度(只读).

  • 变长字节数组

bytes:

变长字节数组,它并不是值类型。

string:

变长 UTF-8 编码字符串类型。并不是值类型。

  • 地址字面常量

比如像 0xdCad3a6d3569DF655070DEd06cb7A1b2Ccd1D3AF 这样的通过了地址校验和测试的十六进制字面常量会作为 address 类型。 而没有通过校验测试, 长度在 39 到 41 个数字之间的十六进制字面常量,会产生一个错误,您可以在零前面添加(对于整数类型)或在零后面添加(对于bytesNN类型)以消除错误。

  • 有理数和整数字面常量

整数字面常量由范围在 0-9 的一串数字组成,表现成十进制。 例如,69 表示数字 69。 Solidity 中是没有八进制的,因此前置 0 是无效的。

  • 字符串字面常量及其类型

字符串字面常量是指由双引号或单引号引起来的字符串

和整数字面常量一样,字符串字面常量的类型也可以发生改变,但它们可以隐式地转换成 bytes1,……,bytes32,如果合适的话,还可以转换成 bytes 以及 string

 bytes32 samevar = "stringliteral" 
//字符串字面常量在赋值给 bytes32 时被解释为原始的字节形式。


//此外,字符串字面常量支持下面的转义字符:

\<newline> (转义实际换行)
\\ (反斜杠)
\' (单引号)
\" (双引号)
\b (退格)
\f (换页)
\n (换行符)
\r (回车)
\t (标签 tab)
\v (垂直标签)
\xNN (十六进制转义,见下文)    // \xNN 表示一个 16 进制值,最终转换成合适的字节,而 \uNNNN 表示 Unicode 编码值,最终会转换为 UTF-8 的序列。
\uNNNN (unicode 转义,见下文)

 

  • Unicode字面常量

常规字符串文字只能包含ASCII,而Unicode文字(以关键字unicode为前缀)可以包含任何有效的UTF-8序列。 它们还支持与转义序列完全相同的字符作为常规字符串文字。

string memory a = unicode"Hello 😃";

 

  • 十六进制字面常量

十六进制字面常量以关键字 hex 打头,后面紧跟着用单引号或双引号引起来的字符串(例如,hex"001122FF" )。 字符串的内容必须是一个十六进制的字符串,它们的值将使用二进制表示。

用空格分隔的多个十六进制字面常量被合并为一个字面常量: hex"00112233" hex"44556677" 等同于 hex"0011223344556677"

  • 枚举类型

枚举是在Solidity中创建用户定义类型的一种方法。 它们是显示所有整型相互转换,但不允许隐式转换。 从整型显式转换枚举,会在运行时检查整数时候在枚举范围内,否则会导致异常。 枚举需要至少一个成员,默认值是第一个成员,枚举不能多于 256 个成员。

  • 函数类型

1.两类

  • 内部(internal) 函数类型。  只能在当前合约内被调用,因为它们不能在当前合约上下文的外部被执行。 调用一个内部函数是通过跳转到它的入口标签来实现的。一般函数默认的就是内部函数类型。
  • 外部(external) 函数类型。外部函数由一个地址和一个函数签名组成,可以通过外部函数调用传递或者返回。

2.类型转化

  • pure 函数可以转换为 view 和 non-payable 函数
  • view 函数可以转换为 non-payable 函数
  • payable 函数可以转换为 non-payable 函数

关于 payable 和 non-payable 的规则可能有点令人困惑,但实质上,如果一个函数是 payable ,这意味着它 也接受零以太的支付,因此它也是 non-payable 。 另一方面,non-payable 函数将拒绝发送给它的 以太币Ether , 所以 non-payable 函数不能转换为 payable 函数。(单向转化)

注意,当前合约的 public 函数既可以被当作内部函数也可以被当作外部函数使用。 如果想将一个函数当作内部函数使用,就用 f 调用,如果想将其当作外部函数,使用 this.f 。

3.成员方法

public(或 external)函数都有下面的成员:

// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.6.4  <0.9.0;

contract Example {
  function f() public payable returns (bytes4) {
    assert(this.f.address == address(this));
    return this.f.selector;
  }
  function g() public {
    this.f{gas: 10, value: 800}();
  }
}

运算:

  • ! (逻辑非)
  • && (逻辑与, “and” )
  • || (逻辑或, “or” )
  • == (等于)
  • != (不等于)
  • 比较运算符: <= , < , == , != , >= , > (返回布尔值)
  • 位运算符: & , | , ^ (异或), ~ (位取反)
  • 移位运算符: << (左移位) , >> (右移位)
  • 算数运算符: + , - , 一元运算负 - (仅针对有符号整型), * , / , % (取余或叫模运算) , ** (幂)
    • 加减乘和正常语法一样,不过会有溢出异常。整数除法总是产生整数。 在Solidity中,分数会取零。 
    • 模运算中, a%n 是在操作数 a 的除以 n 之后产生余数 r
  • 对于负数的除法,结果的正负号取决于被除数是否为正负号 
  • int256(5) % int256(2) == int256(1)
  • int256(5) % int256(-2) == int256(1)
  • int256(-5) % int256(2) == int256(-1)
  • int256(-5) % int256(-2) == int256(-1)

对于整形 X,可以使用 type(X).min 和 type(X).max 去获取这个类型的最小值与最大值。

位运算:位运算在数字的二进制补码表示上执行。 这意味着: ~int256(0)== int256(-1)

移位:

  • 不管 x 正还是负,x << y 相当于 x * 2 ** y
  • 如果 x 为正值,x >> y 相当于 x / 2 ** y
  • 如果 x 为负值,x >> y 相当于 (x + 1) / 2**y - 1 (与将 x 除以 2**y 同时向负无穷大四舍五入)。

### Solidity 编程语言基础教程 Solidity 是一种用于编写智能合约的面向对象高级编程语言,主要用于 Ethereum 平台上的开发工作[^1]。 #### 数据类型 Solidity 支持多种数据类型,包括布尔型 `bool`、整数类型 `int` 和无符号整数类型 `uint`、地址类型 `address` 以及字符串 `string`。每种类型的变量都有特定的作用范围和操作方法。 #### 函数定义 函数是实现业务逻辑的关键部分,在 Solidity 中可以通过如下方式声明一个简单的返回两个数值之和的函数: ```solidity function add(uint a, uint b) public pure returns (uint sum){ sum = a + b; } ``` 此代码片段展示了如何创建一个名为 `add` 的公共纯函数,它接受两个参数并返回它们相加的结果。 #### 合约结构体 合约可以被视作由状态变量、事件、函数组成的实体。下面是一个基本的合约例子: ```solidity pragma solidity ^0.8.0; contract SimpleStorage { // 定义存储的数据 uint storedData; function set(uint x) public { storedData = x; } function get() public view returns (uint) { return storedData; } } ``` 这段程序展示了一个简单储存功能的小合约,其中包含了设置 (`set`) 和获取 (`get`) 存储值的方法。 #### 部署与交互 要部署上述合约到区块链上,则需借助像 Remix IDE 这样的工具来编译源码,并通过 MetaMask 或其他钱包服务完成交易过程;之后就可以调用其公开接口来进行读写操作了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值