30.第一部分

版权声明:忠于祖国,忠于人民 https://blog.csdn.net/boss2967/article/details/83278359

01.remix的使用

  • vm:单机版,用于测试,迅速返回,默认有5个账户,每个默认100ETH
  • injected web3: 这个实力负责真正连接以太坊环境
  • web3 provider:有开发者自己定义的:Ganch或者geth自己搭建的私有网络

02.以太坊交互的特点

  • 发送交易(send)
    • 花钱
    • 需要15秒左右进行确认后才能返回(真实网络)
  • 获取数据(call)
    • 免费
    • 迅速返回

03.智能合约

  1. 合约
pragma solidity ^0.4.24;

contract Inbox{ 
    string public message; 
    // var message string //go
    
    //func Inbox(sr1 string, num uint128) {}  //go
    function Inbox()payable {
        //构造函数完成对类,合约的初始化工作
        message = "HELLO WORLD!";
    }
    
    function setMessage(string newMessage) public{
        message = newMessage;
    }
    
    //func getMessage() string {} //go
    function getMessage() public constant returns(string, string){
        //return message;
        return (message, "hello"); //元组
    }
}
  1. 合约地址+bytecode+abi就可以唯一控制一个合约,通过web3就可以调用了

04.数据类型

01.值类型(memory,默认就是memory)
  • 值类型是指变量在传递过程中是将数值完整的拷贝一份,在赋值给新的变量,这种方式需要开辟的内存空间,效率较低,两个变量完全独立,修改一个不会影响另外一个。
    值类型包含:
    • 布尔(Booleans)
    • 整型(Integer)
    • 地址(Address)
    • 定长字节数组(fixed byte arrags)
    • 有理数和整型(Rational and Integer Literals,String literals)
    • 枚举类型(Enums)
    • 函数(Function Types)
02.引用类型(storage, memory)
  • solidity没有指针,对于复杂的结构进行高效传递方式是使用关键字storage进行修饰。
  • 复杂类型,占用空间较大的。在拷贝时占用空间较大。所以考虑通过引用传递。
  • 常见的引用类型有:
    • 字符串(string
    • 不定长字节数组(bytes)
    • 数组(Array)
    • 结构体(Structs)

05.基础语法

01.view,constant,pure讲解
  • 如果一个函数里面,访问了状态变量,但是没有修改,我们使用view或者constant修饰
  • 如果访问了,而且修改了,那么就不能constant和view,否则会报错
  • 如果没有使用过状态变量,我们要修饰为pure(函数内引用的状态变量没有改变)
  • 如果你修饰为constant,但是你在函数中修改了,效果是:不会报错,正常执行,但是值不会改变
pragma solidity ^0.4.24;


contract test1 {
    
    int8 public i8 = 100; //成员变量就是状态变量
    int i256 = 256;
    
    //表示不会修改函数内的状态变量
    //为了明确语义,一般要加上constant(view两者完全相同)
    function add() private constant returns(int) {
        return i8 + i256;
    }
    
    //public 表示所有的人都可以看到的,而且可以调用
    //private表示所有人都可以看到,但是无法调用
    function mins() constant returns(uint256) {
        return  uint256(i256 - i8);
    }
   
   function isEqual(int a, int b) public pure returns(bool) {
       return a == b;
   }
   
    function setValue(int8 num) {
        i8 = num;
    }
    
    function setValue1(int8 num) constant {
        i8 = num;
    }
}
02.地址
  • 余额
pragma solidity ^0.4.24;


contract test1 {
    function getBalance(address _addr) public view returns (uint256) {
        //使用balance成员获取当前地址的余额
        return _addr.balance;
    } 
    
    //地址是160位数字,可以使用uint160来转换
    address add1 = 0x00ca35b7d915458ef540ade6068dfe2f44e8fa733c;
    uint160 u160 = uint160(add1);
    
    function add() public view returns(uint160) {
        return u160 + 1;
    }
}
  • 转账(transger,send)
pragma solidity ^0.4.24;


contract test1 {
 
    constructor() public payable {//表示可以去转账
        
    }
    
    // 1ehter = 10^18 wei //以太坊
    // 1btc = 10^8 sat //比特币
    // 我们合约中都是wei单位
    // this是合约的地址
    function getContractBalance() public view returns (uint256) {
        return address(this).balance;
    }
 
    function transferTo1(address receiver) public {
        //转账的单位是wei
        //给谁转,就用谁调用transfe
        // 如果转账失败,抛异常
        receiver.transfer(1);
    }
    
    function transferTo2(address receiver) public {
        receiver.transfer(address(this).balance);
    }
    
    //Send在转账失败时,不会抛出异常而是返回false,需要程序员自己校验
    //一般不使用send
    function sendTo(address receiver) public returns(bool) {
        //转账的单位是wei
        //给谁转,就用谁调用transfe
        // 如果转账失败,抛异常
        bool res = receiver.send(1);
        return res;
    }
}
03.固定长度数组bytes1
pragma solidity ^0.4.24;


contract test1 {
    
    // - 长度可以读取 length
    // - 长度不可以修改
    // - 可以通过下标访问
    // - 内容不可修改  
    
    bytes1 public b1 = "h";
    
    bytes2 public b2 = "he";

    bytes10 public b10 = "helloworld";
    
    function getLen() public view returns(uint128){
        //b1.lenght = 10;
        //b1[0] = "H";
        return b1.length;
    }
    
    function getByIndex(uint i) public view returns(byte) {
        return b10[i];
    }
}
4.匿名函数
pragma solidity ^0.4.24;


contract test1 {


    uint128 public num;
    
    constructor() public  {//如果构造函数中为指定payable关键字,那么创建合约时不允许转账
        
    }
    
    //任何函数,只要指定了payable关键字,这个合约就可以接受转账,调用时,也可以转0
    function giveMoney() public payable {
        
    }
    
    //一般用于给合约转账
    function ()payable {
        
    }
    
    function setValue(uint128 _num) public {
        num = _num;
    }
    
    function getBalance() public view returns(uint) {
        return address(this).balance;
    }
}
05.bytes
pragma solidity ^0.4.24;

// - 动态字节数组
// - 引用类型(说明可以使用storage来修饰,进行引用传递,指针的效果)
// - 支持下标索引
// - 支持length、push方法(push会帮助分配空间的)
// - 可以修改
// - 以十六进制格式赋值
//格外注意:对于bytes,如果不使用下标访问,那么可以不用先申请空间,
//直接赋值即可,或者push

contract test1 {
    bytes public name1 = new bytes(1);
    bytes public name2;

    function getName1Length() public view returns(uint256) {
        return name1.length;
    }
    
    function setName1Len(uint len) public {
        name1.length = len;
    }
    
    function setName2Len(uint len) public {
        name2.length = len;
    }
    
    function getName2ByIndex(uint i) public view returns(byte){
        return name2[i];
    }
    
    function pushValueToName2(byte src) public {
        name2.push(src);
    }

    function setValueToName2(string src) public {
        name2 = bytes(src);
    }
}
06.string
pragma solidity ^0.4.24;

// - 动态尺寸的UTF-8编码字符串,是特殊的可变字节数组
// - 引用类型
// - 不支持下标索引
// - 不支持length、push方法
// - 可以修改(需通过bytes转换)


contract test1 {
    string public name = "banzhang";
    
    function setValue() public {
        //name[0] ="B";
        bytes(name)[0] ="B";
    }
    
    function getLen() public view returns(uint256){
        //return name.length;
        return bytes(name).length;
    }
    
    function setLen() public returns(uint256) {
        bytes(name).length = 20;
    }
}
07.storageVSmemory
pragma solidity ^0.4.24;


contract test1 {
    
    string public name = "banzhang";
    uint public num = 10;
    
    function call1() public {
        setValue1(name);
    }

    function setValue1(string memory _name) public  {
        //name[0] ="B";
        bytes(_name)[0] ="B";
        num = 1000;
    }

    function call2() public {
        setValue2(name);
    }

    function setValue2(string storage _name) private  {
        //name[0] ="B";
        bytes(_name)[0] ="B";
        num = 1000;
    }

    function localTest() public {
        //String作为局部变量时,默认是storageleixing,但是可以指定为memory
        // string tmp = name;
        string memory tmp = name;
        
        bytes(tmp)[0] = "B";
    }
}
08.bytesStringBytes1相互转化
pragma solidity ^0.4.20;


contract Test {
    
    bytes10 public b10 = 0x68656c6c6f776f726c64;     //helloworld
    //bytes bs10 = b10; //无法直接转换
    
  
    bytes public bs10 = new bytes(b10.length);
    
    //1. 固定字节数组转动态字节数组
    function fixedBytesToBytes() public{
        for (uint i = 0; i< b10.length; i++){
            bs10[i] = b10[i];
        }
    }
    
    

    //2.string转动态字节数组
    string  greeting = "helloworld";
    bytes public b1;
    function StringToBytes() public {
        b1 = bytes(greeting);
    }
    
    //3. 动态字节数组转string
    string public str3;
    function BytesToString() public {
        fixedBytesToBytes();
        str3 = string(bs10);
    }

    //4. fixed bytes to String,error
    function FiexBytesToString(){
        //string tmp = string(b10);
    }
}
09.自定义数组-定长数组
pragma solidity ^0.4.20;


// - 类型T,长度K的数组定义为T[K],例如:uint [5] numbers,  byte [10] names;
// - 内容可变
// - 长度不可变,不支持push
// - 支持length方法


contract Test {
    uint [10]nums = [1,2,3,4,5,6,7,8,9,10];
    
    uint public sum;
    
    
    function getSum() public returns(uint) {
        for (uint i = 0; i< nums.length; i++) {
            sum += nums[i];
        }
        
        return sum;
    }
    
    
    //==================
    bytes10 helloworldFixed = 0x68656c6c6f776f726c64;
    
    byte [10] byteArray = [byte(0x68), 0x65, 0x6c, 0x6c, 0x6f, 0x77, 0x6f, 0x72, 0x6c, 0x64];
    function setValue() public {
        byteArray[0] = 0x69;
    }
    
    bytes public res;
    function appendArray() public returns (string) {
        for (uint i = 0; i< byteArray.length; i++) {
            res.push(byteArray[i]);
        }
        return string(res);
    }
}
10.自定义数组-不定长数组
pragma solidity ^0.4.0;

contract C {
    
    //创建方式一:字面量形式
    uint [] public c = [uint(1), 2, 3];
    function h() public {
        c.push(4);
    }
    
    //创建方式二:new 关键字	
    //a. storage类型数组,状态变量,最初为空,下标访问时越界
    uint[] public b;
    
    //复杂类型在局部是引用
    function g(){
        b = new uint[](7);
        //可以修改数组的长度
        b.length = 10;
        b[9] = 100;
        b.push(101);
    }
    
    //b. memory类型数组
    function f() public returns (uint[]){
        uint[] memory a = new uint[](7);
        
        //不能修改长度
        //Error: Expression has to be an lvalue.
        //a.length = 100;
        //a.push(10);
            
         for (uint i = 0; i< a.length; i++){
             a[i] = i;
         }

        return a;
    }
}
11.结构体
pragma solidity ^0.4.5;

contract Test {
    //定义结构之后无分号,与枚举一致
    struct Student {
        string name;
        uint age;
        uint score;
        string sex;
    }
    
    //两种赋值方式
    Student public stu1 = Student("lily", 18, 90, "girl");
    Student public stu2 = Student({name:"Jim", age:20, score:80, sex:"boy"});

    Student[] public Students;
    
    function assign() public {
        stu1.name = "Lily";
        Students.push(stu1);
        Students.push(stu2);
    }
}
12.mapping映射
pragma solidity ^0.4.20;


contract test {
    //id -> name
    mapping(uint => string) public id_names;
    
    constructor()  public{
        id_names[0x01] = "lily";
        id_names[0x02] = "Jim";
        id_names[0x02] = "Lily";
    }
    
    function getNameById(uint id)  public returns (string){
        //加上storage如何赋值?
        string memory name = id_names[id];
        return name;
    }
    
    function setNameById(uint id)  public returns (string){
        // mapping(uint => string) memory id_name = id_names;
        // var ids = id_names;
        id_names[id] = "Hello";
    }
    
    
    // function getMapLength() public returns (uint){
    //     return id_names.length;
    // }
    
}

猜你喜欢

转载自blog.csdn.net/boss2967/article/details/83278359