一、Solidity简介
1.介绍
solidity是一门面向合约的、为实现智能合约而创建的高级编程语言,能在以太坊虚拟机(EVM)上运行。它是一门静态语言。内含的类型除了常见编程语言中的标准类型,还包括address等以太坊独有的类型。solidity源码文件通常以.sol作为扩展名。
2.语言特性
它的语法接近于Javascript,是一种面向对象的语言。但作为一种真正意义上运行在网络上的去中心合约,它又有很多的不同,下面列举一些:
- 以太坊底层是基于帐户,而非UTXO的,所以有一个特殊的
Address
的类型。用于定位用户,定位合约,定位合约的代码(合约本身也是一个帐户)。 - 由于语言内嵌框架是支持支付的,所以提供了一些关键字,如
payable
,可以在语言层面直接支持支付,而且超级简单。 - 存储是使用网络上的区块链,数据的每一个状态都可以永久存储,所以需要确定变量使用内存,还是区块链。
- 运行环境是在去中心化的网络上,会比较强调合约或函数执行的调用的方式。因为原来一个简单的函数调用变为了一个网络上的节点中的代码执行,分布式的感觉。
- 最后一个非常大的不同则是它的异常机制,一旦出现异常,所有的执行都将会被回撤,这主要是为了保证合约执行的原子性,以避免中间状态出现的数据不一致。
3.编译器
目前solidity编程最好的方式是使用Remix(地址:https://remix.ethereum.org/),这是一个基于web浏览器的IDE,可在线使用而无需安装任何东西,可以编写solidity智能合约,然后编译、部署并运行该智能合约。
二、Solidity源码和智能合约
Solidity源代码成为可以运行的智能合约需要以下步骤:
1.源代码通过编译成字节码(Bytecode),同时会产生二进制接口规范(ABI);
2.通过交易将字节码部署到以太坊网络,部署成功会产生一个智能合约账户;
3.通过web3.js+ABI去调用智能合约中的函数来实现数据的读取和修改。
三、Solidity值类型
1.布尔(bool)
可能的取值为常量值true
和false
。
2.整型(int/uint)
分别表示的是有符号或无符号整型。支持从uint8
到uint256
,以及int8
到int256
,uint
和int
默认代表的是uint256
和int256
,变量支持的步长以8
递增。
3.浮点型(fixed/ufixed)
分别表示有符号或无符号的浮点型。
4.地址(address)
存储一个20字节的值(以太坊地址的大小)。地址类型也有成员变量,并作为合约的基础。
- balance(uint256)查询该地址的以太币余额,以Wei为单位
- transfer(uint256)向该地址发送指定数量的以太币,以Wei为单位,失败时抛出异常
- send(uint256)向该地址发送指定数量的以太币,以Wei为单位,失败时返回false
pragma solidity ^0.4.0;
contract sendMoney{
//payable关键字代表我们可以通过这个函数给我们的合约地址充值,转账。
function pay() payable{
}
//获取合约账户上的金额
function getBalance() view returns(uint){
return this.balance;
}
//合约地址
function getThis() view returns(address){
return this;
}
//获取任意账户地址的金额
function getRandomBanlance(address account) view returns(uint){
// address account = 0xAb8483F64d9C6d1EcF9b849Ae677dD3315835cb2;
return account.balance;
}
//向指定账户(account)转账
//可以直接输入account.transfer(10 ether);就代表给账户转账
//如果函数内什么操作都没有,但是有payable属性,那么msg.value的值就会转到合约账户地址上
//如果转账金额大于10(eg:20),那么剩余的10会转到合约账户去,被两个账户瓜分
function transfer() payable{
address account = 0xAb8483F64d9C6d1EcF9b849Ae677dD3315835cb2;
account.transfer(10 ether);
}
//向合约账户转账,这种方式必须要有一个回滚函数
function transfer2() payable{
this.transfer(msg.value);
}
//回滚函数,无函数名和返回值
function () payable{
}
}
5.定长字节数组(byte arrays)
bytes1
, … ,bytes32
,允许值以步长1
递增。byte
默认表示byte1
。
6.枚举(enum)
一种用户自定义类型。可以显示的转换与整数进行转换,默认从0开始递增,一般用来模拟合约的状态。枚举类型应至少有一名成员。
pragma solidity ^0.4.0;
contract enumTest{
//enum必须有成员
//不能有汉字
//不能加;
// enum girl{}
enum girl{
a,b,c} //0,1,2...
girl dateGirl = girl.a;
function getEnum() view returns(girl){
return girl.b;
}
//用途:标志状态的转移
function first() returns(string){
require(dateGirl == girl.a);
dateGirl = girl.b;
return "date with a";
}
function second() returns(string){
require(dateGirl == girl.b);
return "date with b";
}
}
7.函数(function)
四、Solidity引用类型
数组(Array)
结构(Struct)
pragma solidity ^0.4.0;
contract structTest{
//结构体的定义
struct student{
uint grade;
string name;
mapping(uint => string) map;
}
//结构体的定义
struct student2{
uint grade;
string name;
// student2 stu; 结构体不能包含自己本身,但是可以是动态长度的数组,也可以是映射
student2[] stu;