-
a**b=a^b
-
位运算(异或运算相同取0不同取1,移位运算是算数移位)
-
view函数不会修改状态,但会读取状态。如果存在下列语句,则被视为是修改了函数,编译器会抛出警告:
1)修改状态变量。(状态变量是全局变量或storage变量,即变量值永久保存在合约存储空间中的变量)
2)触发事件。
3)创建合约。
4)使用selfdestruct。
5)发送以太。
6)调用任何不是视图函数或纯函数的函数
7)使用底层调用(call函数)
8)使用包含某些操作码的内联程序集。 -
Pure(纯)函数不读取或修改状态。如果函数中存在以
读取状态变量。
1)访问 address(this).balance 或 [address].balance
2)访问任何区块、交易、msg等特殊变量(msg.sig 与 msg.data 允许读取)。
3)调用任何不是纯函数的函数。
4)使用包含特定操作码的内联程序集。 -
solidity不支持小数
-
定长字节数组:bytesX(X是一个整数)
1)32指32B
2)其长度和内容不可以修改
pragma solidity ^0.6.0;
contract simpleTest{
bytes4 public temp="tzy";
function getLength() public view returns(uint){
//可以获取定长字节数组长度
return temp.length;
}
/*function changeLength() public{
//不可以修改定长字节数组长度
temp.length=10;
}*/
function getByte() public view returns(bytes1){
//可以获取定长字节数组元素
return temp[0];
}
/*function changeByte() public{
//不可以修改定长字节数组元素
temp[0]="l";
}*/
}
4个字节定长字节数组,会在多余的分配空间后面自动填充0
- 动态字节数组
1)定义:bytes a=new bytes(2) ,表示
2)可以获取或者修改动态字节数组长度,任意位置字节的内容
3)在函数内定义bytes时默认时storage类型
pragma solidity ^0.4.0;
contract dynamic{
bytes public temp=new bytes(4);
//动态字节数组初始化只能在函数中
function init() public{
/* temp[0]=0x74;
temp[1]=0x7a;
temp[2]=0x79;*/
//初始化既可以使用字节码又可以直接初始化
temp="tzy";
}
function getLength() public view returns(uint){
return temp.length;
}
function changeLength() public{
temp.length=10;
}
function getByte() public view returns(bytes1){
return temp[0];
}
function changeByte() public{
temp[0]="l";
}
}
动态长度数组会自动匹配数据的大小:
修改长度和字节0后,显示结果如下:
- string
1)不能直接获取其长度或者内容
2)在solidity中,string的结尾没有’\0’
3)在solidity中,string没length属性,也不可以修改或者获取单个元素
pragma solidity ^0.6.0;
contract csdn{
string str="ustc.tzy";
function getStr() public view returns(bytes memory){
//可以强制将string类型转换为bytes类型再返回
return bytes(str);
}
function getLength() public view returns(uint){
//string没有length属性
//return str.length;
return bytes(str).length;
}
/*function changeLength() public{
str.length=10;
}*/
function getElement() public view returns(bytes1){
//string无法对单个元素进行操作
// return str[0];
//**注意强制类型转换的用法**
return bytes(str)[0];
}
function changeElemt() public{
//str[0]="q";
bytes(str)[0]="Q";
}
}
9.固定长度字节数组互相转换,固定长度数组转动态长度数组,动态长度数组转string
pragma solidity ^0.6.0;
contract csdn{
//3B定长字节数组
bytes3 name="tzy";
function getByets() public view returns(bytes3){
return name;
}
function transform() public view returns(bytes1){
//对其压缩为1B
return bytes1(name);
}
function transform1() public view returns(bytes16){
//对其扩充为16B
return bytes16(name);
}
//固定长度转换为可变长度用for循环
function fixed2dynamic() public view returns(bytes memory){
bytes memory temp=new bytes(name.length);
for(uint i=0;i<name.length;i++){
temp[i]=name[i];
}
return temp;
}
//可变长度数组转string直接强制转换
function dynamic2string() public view returns(string memory,bytes memory){
bytes memory temp=new bytes(3);
//下语句相当于string强制转换成可变长度数组
temp="tzy";
return (string(temp),temp);
}
}
三者的转换图如下:
-
在solidity中,1个字母或者字符占1B,1个汉字占3B
-
1ether=10^18 wei
-
固定长度数组(一维,二维)
1)无法修改长度但可以获取长度
2)可以修改元素 -
动态长度数组(一维,二维)
1)使用push方法加元素
2)可改变长度
pragma solidity ^0.4.0;
contract test{
uint[] public temp=[1,2,3];
uint[5] public temp1=[1,2,3];
function increase() public {
//用push方法给变长数组增加长度
temp.push(4);
}
function getInfo() public view returns(uint[],uint){
return (temp,temp.length);
}
function getInfo1() public view returns(uint[5],uint){
return (temp1,temp1.length);
}
function changeElement() public{
//两种都可以修改元素
temp1[0]=5;
temp[0]=5;
}
function changeLength() public{
//仅变长数组可以修改长度
temp.length=10;
}
}
多维数据的定义与非区块链语言类似。如,我们要创建一个长度为5的uint数组,每个元素又是一个变长数组。将被声明为uint[][5](注意,定义方式对比大多数语言来说是反的,使用下标访问元素时与其它语言一致)。
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
二维数组定义和其他语言不同uint temp[x][y],代表有y个元素,每个元素大小为x,相当于y行x列
pragma solidity ^0.4.0;
contract test{
uint[2][3] temp=[[1,2],[3,4],[5,6]];
uint[][] temp1;
function print() public view returns(uint[2][3]){
return temp;
}
function printElement() public view returns(uint){
return temp[0][1];
}
function getLength() public view returns(uint,uint){
//其结果将会是3和2
return (temp.length,temp[0].length);
}
function changeLength() public{
}
function changeElemnt() public{
temp[0][0]=100;
}
}
/*for(uint i=0;i<3;i++){
for(uint j=0;j<2;j++){
}
}*/
13.数组字面量
1)uint默认是uint256
2)address默认是uint160,以太网内合约账户的地址均为uint160
14.tansfer,send,call
//如果异常会转账失败,抛出异常(等价于requi(send()))(合约地址转账)
// 有gas限制,最大2300
[address payable].transfer(uint256 amount)
//如果异常会转账失败,仅会返回false,不会终止执行(合约地址转账)
// 有gas限制,最大2300
[address payable].send(uint256 amount) returns (bool)
如果异常会转账失败,仅会返回false,不会终止执行(调用合约的方法并转账)
// 没有gas限制
[address].call(bytes memory) returns (bool, bytes memory)
1)三个方法的共同点:addr.transfer(1 ether)、addr.send(1 ether)、addr.call.value(1 ether)的接收方都是addr
如果使用addr.transfer(1 ether)、addr.send(1 ether),addr合约中必须在同一合约内增加fallback回退函数!
如果使用addr.call.value(1 ether),那么被调用的方法必须添加payable修饰符,否则转账失败!