【智能合约】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)

目录

注意事项

编译器选择

一些说明

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相互转换

最后

image.png


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


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


注意事项

编译器选择

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

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


一些说明

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

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

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

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


image.png

1. 变量

1.1 状态变量

定义在合约之内,但是在函数之外的变量,叫做状态变量,这些变量会上传到区块链保存的,默认是私有的,可以使用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;
    }
}


1.2 局部变量

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

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


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


2. 数据类型

2.1 值类型

2.1.1 布尔类型(Booleans):

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";
        }
    }
}


2.1.2 整型(Integers):

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); // 类型强转
  }


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

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


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


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

关键字有: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];
    }
}

image.png


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

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


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


2.1.6 枚举(Enums)

自定义类型

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

enum Gender {
  Male, 
  FeMale 
 }


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


Gender default = Gender.Male 


2.1.7 函数类型(Function Types)

状态变量:默认是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)修饰符


2.1.8 地址类型(Address)

基础知识

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

通过合约的地址串,调用合约内的函数,本质是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
    }
}


这里有很多地址可选择


image.png

image.png


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

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


image.png


2.2 引用类型

2.2.1 字符串

不支持索引

不支持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")

2.2.2 数组

内置数组: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个长度的空间


2.2.3 结构体:

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

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);


2.2.4 mapping:映射,

无法判断是否存在某个key

不支持length

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

2.2.5 storage和memory

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


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


bytes1、bytes、string相互转换

bytes1转string要经过中间的bytes


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


最后

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

image.png


image.png

相关文章
|
19天前
|
IDE 编译器 区块链
基于 Solidity 的智能合约详解
基于 Solidity 的智能合约详解
18 2
|
11月前
|
存储 前端开发 JavaScript
区块链智能合约编程语言 Solidity
上文介绍了[区块链生态发展](https://wangbinguang.blog.csdn.net/article/details/131440404),我们知道以太坊的到来可以使开发人员基于区块链开发DApp,本文介绍 Solidity 编程语言的使用,然后基于 Solidity 编写一个简单的智能合约。
99 1
|
JavaScript 前端开发 区块链
【区块链Solidity】智能合约与Solidity介绍
【区块链Solidity】智能合约与Solidity介绍
115 0
|
存储 区块链 数据库
Solidity开发智能合约
一个简单的智能合约 在Solidity中,一个合约由一组代码(合约的函数)和数据(合约的状态)组成。合约位于以太坊区块链上的一个特殊地址。
1491 0
|
存储 JavaScript 前端开发
【一步步一起学DApp开发】(三)Solidity语言讲解 | 用Solidity编写智能合约 下
【一步步一起学DApp开发】(三)Solidity语言讲解 | 用Solidity编写智能合约
227 0
|
存储 编译器 区块链
【一步步一起学DApp开发】(三)Solidity语言讲解 | 用Solidity编写智能合约 上
【一步步一起学DApp开发】(三)Solidity语言讲解 | 用Solidity编写智能合约
529 0
|
Java 区块链
【智能合约】Solidity 进阶编程 | 注意一下合约中的细节
目录 1. 内置的全局变量 2. 错误处理 3. 访问函数 4. 创建合约 5. 合约继承 6. 修饰器modifier 最后
227 0
【智能合约】Solidity 进阶编程 | 注意一下合约中的细节
|
存储 Java 区块链
6分钟以太坊实战 - 智能合约与Solidity高级语言(一)
1. 简介 合约是存放在以太坊区块链具有特定地址的代码和数据集合。 合约账户之间可以相互传递消息以实现图灵完备运算。 合约以以太坊特定的二进制字节码通过以太坊虚拟机(EVM)运行于区块链上。目前,合约通常是以Solidity(一门长得很像js的语言)高级语言编写,编译后传到区块链上运行。
9582 0
|
存储 区块链 编译器
以太坊智能合约简介(Solidity)
本文略过了冗杂介绍,直接下沉到代码示例。本文中包含一个存储实例和生成极简单 subcurrency 的实例
|
前端开发 JavaScript 区块链
以太坊智能合约开发入门
以太坊合约就是以太坊区块链特定账户地址上的一串代码(functions)和数据(state)。合约账户不仅可以相互间通讯,还可以执行几乎所有的图灵完备计算。以太坊区块链上的合约代码是特定的二进制形式,被称作以太坊虚拟机(EVM)二进制代码。本文以最受欢迎的Solidity为例说明以太坊开发如何入门。
5520 0