天天看点

【智能合约】Solidity 基础知识 | 以太坊智能合约编程语言

目录

注意事项

编译器选择

一些说明

1. 变量

1.1 状态变量

1.2 局部变量

2. 数据类型

2.1 值类型

2.1.1 布尔类型(Booleans):

2.1.2 整型(Integers):

2.1.3 定长浮点型(Fixed Point Numbers):

2.1.4 定长字节数组(Fixed-size byte arrays)

2.1.5 有理数和整型常量(Rational and Integer Literals)

2.1.6 枚举(Enums)

2.1.7 函数类型(Function Types)

修饰符

函数定义

函数返回值

构造函数

2.1.8 地址类型(Address)

基础知识

转账

2.2 引用类型

2.2.1 字符串

2.2.2 数组

2.2.3 结构体:

2.2.4 mapping:映射,

2.2.5 storage和memory

bytes1、bytes、string相互转换

最后

【智能合约】Solidity 基础知识 | 以太坊智能合约编程语言

Solidity是一种智能合约高级语言,运行在Ethereum虚拟机(EVM)之上。Solidity是以太坊的首选语言,它内置了Serpent的所有特性,它的语法接近于Javascript,是一种面向对象的语言,这降低了学习门槛,易于被掌握和使用,因为JavaScript是Web开发者的常用语言。因此,Solidity充分利用了现有数以百万程序员已掌握JavaScript这一现状。

以太坊智能合约编程语言,语法简单,但是有不成熟不完善,有bug,没有多线程

使用的是Remix IDE编译器 下载地址 —> Remix IDE下载地址

这个编译器对中文很不友好!吐槽一下!

一个 contract 里面就是一个合约,没有main函数,只要合约部署就可以运行

一定要有头部版本号申明:pragma solidity 0.4.24;

每一行结尾得有分号(;)结束

注释:中文必须在外面写好然后拷贝,不能直接在里面写中文注释!对中文很不友好!

【智能合约】Solidity 基础知识 | 以太坊智能合约编程语言
定义在合约之内,但是在函数之外的变量,叫做状态变量,这些变量会上传到区块链保存的,默认是私有的,可以使用public和private修饰

pragma solidity 0.4.24; 
contract HelloWorld{
    string public name;   // 这个就是状态变量,使用public修饰
    function hello(string memory text) public pure returns(string memory) {
        return text;
    }
}      

在合约之内,在函数之内,局部变量不能使用public

pragma solidity 0.4.24;
contract Hello{
    function hello(string memory text) public pure returns(string memory) {
        string name = "FanOne";   // 这个就是局部变量
        return text;
    }
}      

状态变量默认是私有的,可以使用public修饰

true或false,默认是false

!逻辑非

&& 逻辑与

|| 逻辑或

== 等于

!=不等于

pragma solidity 0.4.24;
contract DataType {
    // bool public ok = true;
    bool public ok;  // def is false
    function test() returns(string){
        if (ok) {
            return "this is true";
        }else {
            return "this is false";
        }
    }
}      

int/uint: 表示有符号和无符号不同位数整数

以8位为区间,有int8,int16,int24,…,int256,int默认是int256,uint同理

int8 num;
int256 total = 120;      

举例:两个数相加的结果

pragma solidity 0.4.24;
contract Add {
  int8 i1 = 10;
  int16 i2 = 11;
  function add() returns (int8){
      return i1 + int8(i2); // 类型强转
  }      

fixed/ufixed: 表示有符号和无符号的固定位浮点数

还不完全支持,它可以用来声明变量,但不可以用来赋值

关键字有:bytes1, bytes2, bytes3, …, bytes32。

byte 代表 bytes1。bytes1存储1个字节,即8位,bytes2存储2个字节,步长为1字节递增

.length:表示这个字节数组的长度(只读),返回的是定长字节数组类型的长度,而不是值的长度

长度不能修改

可以通过下标获取

元素值不可修改,只读

pragma solidity 0.4.24;
contract TestBytes {
    bytes1 public b0;  // 字节:0x00
    bytes1 public b1 = "f";  // 0x66
    bytes2 public b2 = "fa";  // 0x6661
    bytes6 public b6 = "fanone";  
    bytes32 public b32 = "FanOne";
    function getLen() returns(int256){
        return b32.length;
    }
    function getByIndex() returns(bytes1){
        return b1[0];
    }
}      
【智能合约】Solidity 基础知识 | 以太坊智能合约编程语言

表达式中直接出现的数字常量:

整数,小数,科学计数都支持(9e30:6*200^10)

自定义类型

至少要有一个元素,默认位uint8,不要忘了花括号

enum Gender {
  Male, 
  FeMale 
 }      

// Gender为自定义类型,设置默认值

Gender default = Gender.Male       

状态变量:默认是private

函数:默认是public

public:公有,拥有以太坊的账户都可以调用,可以修饰状态变量

private:私有,只有合约内部可以调用,可以修饰状态变量

view / constant:函数会读取但是不会修改任何合约的状态变量

pure:函数不适用任何合约的状态变量

payable:调用函数需要付钱,钱付给了智能合约的账户

returns:返回值函数声明中使用

external:仅合约外部可以调用,合约内部需要使用this调用

internal:仅合约内部和继承的合约可以调用

修饰符在returns声明的前面,可以有多个修饰符

view、constant、pure的区别:都是针对状态变量的

函数中访问了状态变量,但是没有修改,使用view或者constant

如果没有使用状态变量,则使用pure修饰

如果即访问了状态变量,又修改了,则不要修饰即可。

注意坑:constant修饰的函数中,修改了状态变量,编译器不会报错,但是运行是修改不成功的。

payable

想要转钱,修饰符必须是payable

payable的修饰符,转的钱到合约中了

function setMoney(string str) public payable returns(string) {
    return str;
}      

署的时候,交易金额给个值,会发现金额减少了,钱到了合约,注意交易金额的单位,用ether,不然看不到大的变化

获取合约中的钱

function getMoney() public view returns(uint256){
     return this.balance;
}      

this代表当前合约本身,balance获取当前合约的余额

function 函数名称(可选参数) 修饰符 返回值{

函数体

}

例:

function Add(a int8) public view returns(int8){
    return a
}      

使用returns指定返回的类型

返回值声明一定要放在最后

多个返回值使用元组:使用括号括起来()

进入合约就执行,一般设置一些初始化后不变的数据

constractor() public {
    owner = msg.sender;
}      

public:共有,可以修饰函数,可以修饰状态变量

provate:私有,可以修饰函数,可以修饰状态变量

view/constant:用了状态变量,但是没有修改状态变量,只能修饰函数

pure:没有使用状态变量,只能修饰函数

payable:只能修饰函数,转账的话必须使用payable,钱从账户过来,钱到合约

returns:在函数最后,返回值

状态变量在函数中修改了,就不要使用(view\constant\pure)修饰符

地址是所有合约的基础,所有合约都继承地址对象

通过合约的地址串,调用合约内的函数,本质是uint160,可以进行加减,需要强转

balance:获取余额

transfer:转账,推荐使用,谁调用就是给谁转

send:转账,不安全,不推荐使用,合约余额不够需要自己手动处理,不会报错

call:合约内部调用合约,调用底层代码,别用

callcode:调用底层代码,别用

delegatecall:调用底层代码,别用

this指合约本身

address(this),直接使用this会有warning      

账户–>账户:不支持

账户–合约:paybable

合约–账户:transfer,谁调用就是给谁转

合约–合约 看高级用法

换算:1ether = 10**18wei (10^18),单位默认是wei

pragma solidity 0.4.24;
contract TransferDemo {
    uint256 public a;
    function constractGetMoney() public payable{
       
    }
    function getConstractBalance() public {
        a = address(this).balance;
    }
    address to_addr = 0xCA35b7d915458EF540aDe6068dFe2F44E8fa733c;
    function trans() public {
        to_addr.transfer(5 * 10 ** 18 );  //define is wei
        //need to transfer eth
    }
}      

这里有很多地址可选择

【智能合约】Solidity 基础知识 | 以太坊智能合约编程语言
【智能合约】Solidity 基础知识 | 以太坊智能合约编程语言

钱到哪去:向谁转钱,就用谁调用transfer

钱从哪来:合约的钱(payable),合约的钱不够transfer的时候会报错

【智能合约】Solidity 基础知识 | 以太坊智能合约编程语言

不支持索引

不支持length和push方法

可以修改,需要通过bytes转换

string me = "fanone";      

转bytes,然后就可以使用bytes的特性了

bytes(me).length;      

bytes转string

string(bytes)      

不定长字节数组:bytes:

支持length,push(在最后追加)方法

可以修改

支持索引,如果未分配空间(new分配空间),使用下标会报角标越界,其他的会自动分配空间

以十六进制格式赋值

bytes me = "fanone"
name.push("666")      

内置数组:string、bytes、bytes1…bytes32

自定义定长数组:长度不可变,支持length,不支持push

uint256[5] public nums = [1,2,3,4,5];      

自定义不定长数组:长度可变,内容可修改,支持length,push方法

uint256[] public nums = [1,2,3,4,5];
nums.push(6)
delete nums;      

函数中使用new分配空间

uint8[] memory aa = new uint8[](10);// 10个长度的空间      

函数不支持返回结构体对象,可以把值放到元组中返回(按个放到()中,返回元组)

struct 结构体名称{
    类型 字段名;
}      
struct Person {
    string name;
    uint age;
}
// 指定字段名,必须用()括起来,里面是花括号
Person public p1 = Person({name:"hallen",age:18});
// 按顺序初始化值,注意是括号()不是花括号{}
Person public p2 = Person("hallen",18);
// 结构体不定长数组
Person[] persons;
// 函数中可以往里面添加值,类型必须是结构体初始化对象
persons.push(p1);      

无法判断是否存在某个key

不支持length

mapping(string=>string) map_data;
// 函数中赋值
map_data["name"] = "hallen";
//获取指定的key的值
string storage aa = map_data["name"];      

storage:数据永远保存,引用传递,只有引用类型的变量才可以显示的声明为storage。

memory:存在内存中,会被回收,数据会过期丢失,类似值类型

bytes1转string要经过中间的bytes

角标用uint256类型,不然会类型不匹配

小生凡一,期待你的关注。

【智能合约】Solidity 基础知识 | 以太坊智能合约编程语言

继续阅读