【以太坊开发-03】Solidity基础语法(上)

【以太坊开发-03】Solidity基础语法(上),第1张

⼀、Solidity概述

特点:

1.⽐较简单,没有多线程的概念
2. 类似javaScript
3. 不成熟,有⼀写bug

中文文档:https://solidity-cn.readthedocs.io/zh/develop/
参考文档:https://www.tryblockchain.org/

1.1 访问可见性private、public

介绍:

1.private 修饰的函数为私有的,只有合约内部可以调用
2.Public修饰的函数为共有的,合约内外都可以调用
3.public/private可以修饰状态变量
4.什么是状态变量:定义在合约之内,但是在函数之外的变量,我们叫做 状态变量 ,这些变量是会上传到区块链上保存
注意:状态变量默认是私有的

1.2 View,Constant,Pure介绍

介绍:

1.如果函数中没有用到状态变量:(既没有读也没有写),就修饰为pure
2. 如果读了,但是没写,修饰为view、constant
3. 如果写了,那么不修饰即可
注意:在constant/view 修饰函数的函数中,如果去修改了状态变量,编译器不会报错,但是赋值不会成功(坑!!!!)

代码:
pragma solidity ^0.4.24;

contract  Test {
    //状态变量
    //类型不匹配时需要显示转换类型
    //返回值需要使用returns描述
    
    
    
    //public/private 可以修饰状态变量
    //状态变量默认是私有的
    uint256 public ui = 100;
    
    int8 private i10 = 10;
    
    
    // 1. 如果函数中没有用到状态变量:(既没有读也没有写),就修饰为pure
    // 2. 如果读了,但是没写,修饰为view、constant
    // 3. 如果写了,那么不修饰即可
    
    function add() public constant returns(uint256) {
        return ui + uint256(i10);
    }
    
    function test() public pure returns(string) {
        return "hello";
    }
    
    function setValue(uint256 num) public {
        ui = num;
    }
    
    //在constant/view 修饰函数的函数中,如果去修改了状态变量,编译器不会报错,但是赋值不会成功(坑!!!!)
    function setValue1(uint256 num) public constant {
        ui = num;
    }
    
    function isEqueal() public view returns(bool) {
        return ui == uint256(i10);
    }

}
二、数据类型分类
值类型(值传递)引⽤类型(指针传递)
2.1 值类型

值类型 是指变量在传递过程中是将数值完整的拷⻉⼀份,再赋值给新的变量,这种⽅式需要开辟新的内存空间,效率较低,两个变量完全独⽴,修改⼀个不会影响另外⼀个。

值类型 包含

布尔(Booleans)整型(Integer)地址(Address)定⻓字节数组(fixed byte arrays)有理数和整型(Rational and Integer Literals,String literals)枚举类型(Enums)函数(Function Types)

注意:

整型分为有符号整型int和⽆符号整型uint(没有负数) 以8位为区间,⽀持int8,int16,int24 ⾄ int256,uint同理。 int默认为int256,uint默认为uint256。函数类型也就是我们所说的函数,本身也是⼀个特殊的变量,它可以 当做变量赋值 , 当做函数参数传 递 , 当做返回值 。函数声明:函数名,函数签名(返回值,参数类型,修饰符
2.2 引用类型

solidity没有指针,对于复杂的结构进⾏⾼效传递⽅式(相当于指针)是使⽤关键字 storage 进⾏修饰。
复杂类型,占⽤空间较⼤的。在拷⻉时占⽤空间较⼤。所以考虑通过引⽤传递。

引⽤类型 包含

字符串(string)不定⻓字节数组(bytes)数组(Array)结构体(Structs) 三、几个重要的关键字

3.1 payable
pragma solidity ^0.4.24;
contract  Test {
    
    string public str ;
    
    //修饰为payable的函数才可以接收转账
    //不指定payable无法接收
    function test1(string src) public payable {
        str = src;
    }
    
    function test2(string src) public {
        str = src;
    }
    
    function getbalance() public view returns(uint256) {
        //this代表当前合约本身
        //balance方法==获取当前合约的余额==
        return this.balance;
    }
}
storageVsMemory关键字

复杂类型,不同于之前 值类型 ,占的空间更⼤,超过256字节,因为拷⻉它们占⽤更多的空间,如数组(arrays) 和 数据结构(struct) ,他们在Solidity中有⼀个额外的属性,即数据的存储位置: memory 和 storage 。

- 内存(memory) 数据不是永久存在的,存放在内存中,越过作⽤域后⽆法访问,等待被回收。被memory修饰的变量是直接拷⻉,即与上述的值类型传递⽅式相同。 - 存储 (storage) 数据永久保存在。被storage修饰的变量是引⽤传递,相当于只传地址,新旧两个变量指向同⼀⽚内存空间,效率较⾼,两个变量有关联,修改⼀个,另外⼀个同样被修改。只有引⽤类型的变量才可以显示的声明为 storage 。 - 状态变量

状态变量总是stroage类型的,⽆法更改

- 局部变量

默认是storage类型(仅限数据结构或数组,string),但是可以声明为memory类

pragma solidity ^0.4.24;


contract  Test {
    string public name = "lily";
    uint256 public num = 10;
    
    
    
    function call1() public {
        setName(name);    
    }
    
    
    //对于引用类型数据,作为函数参数时,默认是memory类型(值传递)
    //function setName(string input) private {
    function setName(string memory input) private {
        num = 20;
        bytes(input)[0] = "L";
    }
    
    function call2() public {
        setName2(name);
    }
    
    //2. 如果想引用传递,那么需要明确指定为stroage类型
    function setName2(string storage input) private {
        num = 30;
        bytes(input)[0] = "L";
    }
    
    //如果局部变量是string,数组,结构体类型数据,默认情况下是storage类型
    function localTest() public {
        //string tmp = name;
        string storage tmp = name;
        num = 40;
        bytes(tmp)[0] = "L";
    }
    
    function localTest1() public {
        
        //也可以明确设置为memory类型
        string memory tmp = name;
        num = 50;
        bytes(tmp)[0] = "L";
    }
}
四、匿名函数、地址、余额、转账 4.1匿名函数

⼀个合约可以有且只有⼀个匿名函数,此函数不能有参数,也不能有任何返回值,当我们企图去执⾏⼀个合约上没有的函数时,那么合约就会执⾏这个匿名函数。
当合约在只收到以太币的时候,也会调⽤这个匿名函数,⽽且⼀般情况下会消耗很少的gas,所以当你接收到以太币后,想要执⾏⼀些 *** 作的话,你尽可以把你想要的 *** 作写到这个匿名函数⾥,因为这样做成本⾮常便宜。

//如果想向合约转账,在合约中添加如下函数即可
function() payable {
 //函数体什么都不填
}
4.2 地址

以太坊地址的⻓度,⼤⼩ 20个字节 ,20 * 8 = 160位 ,所以可以⽤⼀个 uint160 编码。地址是所有合约的基础,所有的合约都会继承地址对象,通过合约的地址串,调⽤合约内的函数。
*** 作:

4.3 余额

返回指定地址的余额

pragma solidity ^0.4.24;
contract Test {
 address public addr1 =
0x0014723a09acff6d2a60dcdf7aa4aff308fddc160c;

 function add() public view returns(uint160) {
 return uint160(addr1) + 10;
 }
 
 //1. 匿名函数:没有函数名,没有参数,没有返回值的函数,就是匿名函数
 //2. 当调⽤⼀个不存在的⽅法时,合约会默认的去调⽤匿名函数
 //3. 匿名函数⼀般⽤来给合约转账,因为费⽤低
 function () public payable {
 
 }
 
 function getBalance() public view returns(uint256) {
 return addr1.balance;
 }

 function getContractBalance() public view returns(uint256) {
 //this代表当前合约本身
 //balance⽅法,获取当前合约的余额
 return address(this).balance;
 } 
}

注意:如果只是想返回当前合约账户的余额,可以使⽤ this 指针, this 表示合约⾃身的地址。

4.4 转账(send,transfer)

send和transfer函数提供了由合约向其他地址转账的功能。

pragma solidity ^0.4.24;


contract  Test {


    address public addr0 = 0x00ca35b7d915458ef540ade6068dfe2f44e8fa733c;
    address public addr1 = 0x0014723a09acff6d2a60dcdf7aa4aff308fddc160c;
    
    
    //1. 匿名函数:没有函数名,没有参数,没有返回值的函数,就是匿名函数
    //2. 当调用一个不存在的方法时,合约会默认的去调用匿名函数
    //3. 匿名函数一般用来给合约转账,因为费用低
    function () public  payable {
        
    }
    
    function getBalance() public view returns(uint256) {
        return addr1.balance;
    }
    
    function getContractBalance() public view returns(uint256) {
        return address(this).balance;
    }
    
    //由合约向addr1 转账10以太币
    function transferTest() public {
        //1. 转账的时候单位是wei
        //2. 1 ether = 10 ^18 wei (10的18次方)
        //3. 向谁转钱,就用谁调用tranfer函数
        //4. 花费的是合约的钱
        //5. 如果金额不足,transfer函数会抛出异常
        addr1.transfer(10 * 10 **18);
    }
    
    //send转账与tranfer使用方式一致,但是如果转账金额不足,不会抛出异常,而是会返回false
    function sendTest() public {
        addr1.send(10 * 10 **18);
    }
}

注意:向谁转账,就用谁调用tranfer函数。比如合约要给我的地址myAddress转账一个以太币,就myAddress.transfer((1 * 10 **18))

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zaji/2992313.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-09-23
下一篇 2022-09-23

发表评论

登录后才能评论

评论列表(0条)

保存