友情提示:每一句话都非常重要,每一个点都是细节。再者本教程适合有一定编程基础的小伙伴快速入门
基本语法,整数溢出以及异常处理,字节数组,动态字节数组,字符串,字符串与字节数组的相互转换,帮助大家快速入门Solidity
这里直接给一段代码
pragma solidity ^0.4.16;
contract Helloworld {
string Myname = "张三";
function getName() public view returns(string) {
return Myname;
}
function setName(string newname) public {
Myname = newname;
}
function pureTest(string _name) public pure returns (string) {
return _name;
}
}
这里使用的编辑器是remix网页编辑器:点击进入remix编辑器
下面我们对这段代码进行分析
在java中,已经有很多的小我们大致了解,所以我们学习solidity只需要学习它与其他语言不同的地方
第一行的prama,是solidity的编译控制指令,那我们这行代码的意思是,源文件不允许被0.4.16以下,以及大于等于0.5.0版本的编译器所编译,简单来说,允许的范围就是左闭右开
0.4.16<=编译器版本<0.5.0
在此区间的编译器版本是可以编译的。
contract关键字,相当于java中的class,定义一个合约
view关键字,这个是Solidity特有的关键字,因为solidity最终是用在合约上,所以会有相关的功能,而view就是这些功能的其中一个,view只能用来修饰方法,而被修饰的方法不能修改状态变量,也就是在java中的类的属性,在这里这个状态变量就是Myname,在这里我们可以看到getName()方法并没有修改Myname的值
运行setName()方法,这个方法需要传入一个参数,我们在这里传入"李四",点击运行,之后再运行getName()重新获取值,结果如下
但是我们发现油费改变了,这说明了什么?
当我们继续点击getName()运行多次的时候,油费依旧不变,而当我们再次运行setName()方法的时候油费又会改变。
这说明了被view修饰的方法不会消耗油费,因为它不需要改变状态变量,所以view关键字还有节约油费的作用
pure关键字,被这个关键字修饰的方法不允许访问状态变量,所以也不需要花费油费。
bool,&& ,||,用法与java中完全一致,在这里不过多解释。
uint关键字,代表非负整型,默认是uint256,256是指256个比特位,
8bit=1byte
&:按位与,同时为1,得到1,有一个及以上为0,就是0
|:按位或,同时为0,得到0,有一个及以上为1,就是1
~:取反,0变成1,1变成0(只需要一串数字就可以)
^:按位异或,相同为0,不相同为1
<<:左移
.>>:右移
将上面的符号全部测试一遍,这里不给出结果,有兴趣的可以自己去运行一下
pragma solidity ^0.4.16;
contract BoolTest {
uint8 a = 4;
uint8 b = 2;
function plus() public view returns(uint8){
return a + b;
}
function minus() public view returns(uint8){
return a - b;
}
function multiply() public view returns(uint8){
return a * b;
}
function divide() public view returns(uint8){
return a / b;
}
function power() public view returns(uint8){
return a ** b;
}
function test1() public view returns(uint8){
return a&b;
}
function test2() public view returns(uint8){
return a|b;
}
function test3() public view returns(uint8){
return ~b;
}
function test4() public view returns(uint8){
return a^b;
}
function test5() public view returns(uint8){
return a<<1;
}
function test6() public view returns(uint8){
return a>>1;
}
}
function flow() public pure returns(uint8){
uint8 mm = 255;
return mm;
}
我们知道。8个比特位的数据范围是0~255,所以这个方法会返回一个mm的值,是255,运行结果没问题。
接下来我们修改一下代码,修改后的代码在下方
function flow() public pure returns(uint8){
uint8 mm = 255;
mm++;
return mm;
}
代码修改后,mm理应变成256,但是256已结超过了8个比特位的取值范围,所以会出现错误。运行结果:
可以看到,mm的值输出直接变成了0,为什么会有这种结果呢?
1 1 1 1 , 1 1 1 1
上面是我们的8个比特位,这个是255的二进制表示,当这个数加1的时候,最后一位加1,学过二进制的朋友都知道,依次从后往前满2进1,最后的结果是:
1, 0 0 0 0, 0 0 0 0
由于我们只能读取8个比特位,所以读取之后的值就是
0 0 0 0, 0 0 0 0
这个值就是0,所以m后8位读取变成了0。
为了验证我们的结论,我们再次修改代码:
function flow() public pure returns(uint8){
uint8 mm = 255;
mm++;
mm++;
return mm;
}
运行结果:
可以看到,当我们让mm在之前的基础上再加1之后,变成了
0 0 0 0, 0 0 0 1
所以mm的结果就是1,可以验证我们刚刚的结论是正确的。
function erroTest() public pure returns(int){
int a1 = 1;
int a2 = 0;
return a1/a2;
}
注意观察上面的函数,很明显我们看到上面的函数发生了错误,因为0不能做除数,那我们编译这个代码是能通过的,但是当我们调用这个函数的时候就会看到以下字段
这就是发生了一个异常。
注意:solidity目前不支持小数类型
我们还是先给一段代码
pragma solidity ^0.4.0;
contract BytesArray {
bytes1 public num1 = 0x7a;// 只有一个字节的数 二进制表示:0111 1010
bytes2 public num2 = 0x7a68;// 有两个字节的数 二进制表示:0111 1010 0110 1000
function getLength() public returns(uint256) {
return num1.length;// length属性不可修改
}
function getLength2() public returns(uint256) {
return num2.length;// length属性不可修改
}
}
function and() public returns(bytes2 n1,bytes2 n2,bytes2 n3, bytes2 n4, bytes2 n5,bytes2 n6){
return (num1&num2,num1|num2,~num1,num1^num2,num1<<1,num1>>1);
}
上代码:
pragma solidity ^0.4.0;
contract BytesArray {
bytes public name = new bytes(2);
function initName() public {
name[0] = 0x7a;
name[1] = 0x68;
}
function getLength() public returns(uint256){
return name.length;
}
function changeLength() public {
name.length = 5;
}
}
总结:动态字节数组能够修改数组的长度。
pragma solidity ^0.4.0;
contract StringTest {
string public name = "zhangsan";
function getLength() public returns(uint256){
return bytes(name).length;
}
function changeName() public {
bytes(name)[0] = 'L';
}
function getCName() public returns(bytes1){
return bytes(name)[0];
}
}