首先,所有的solidity源码前面必须标明编译器版本
pragma solidity^0.4.18;
这个就声明了版本是0.4.18到0.5.0的编译器中是可以工作的
合约
写一个合约的基本框架是:
contract name{}
变量
下面来看一下怎么声明变量,状态变量会永久的保存在合约里
uint表示无符号整数,int表示有符号的
在solidity里面uint默认表示uint256,其他的还有uint8、uint16、uint32...
声明一个变量:
uint id=115;
结构体
solidity也可以用结构体:下面声明了一个叫Student的结构体,有两个属性一个是string类型的name,另一个是uint类型的id
struct Student{string name;uint id;}
数组
solidity支持两种类型的数组,静态数组、动态数组
uint类型的固定长度为10的静态数组id
uint[10]id;
uint类型的长度不定的动态数组id
uint[]id;
也可以建立一个结构体类型的数组students
Student[]students;
函数
习惯上,函数里面的变量都是以_开头的
function sayhello(string _name,uint _id){}
使用结构体和数组
下面我们来了解一下怎么使用结构体和数组
Student yichen=Student('yichen',115);//创建一个新的studentstudents.push(yichen);//把创建的yichen添加到students结构体数组里面
当然也可以一步完成
students.push(Student('yichen',115));
函数的属性
solidity默认的属性是公共的(public),也就是说谁都可以调用,这样明显是不安全的,所以我们将它设置为私有的(private),只需要在函数后面加上一个private就可以,另外私有函数习惯名称前带个下划线
function _sayhello(string _name,uint _id)private{}
函数的更多属性
想让函数返回一个值的话可以这样:
string greeting="hello yichen!";function _sayhello()returns(string){return greeting;}
在以太坊中,你去执行一些操作比如:转账、部署合约等是需要花费一些钱的(gas),因为以太坊需要消耗资源去计算
我们可以发现上面那个函数并没有修改任何东西,所以可以给他设置一个view修饰符,表示它只是读取数据,没有改变或者写任何东西,那么运行这个函数的时候只需要去查询保存的数据就可以,不需要全世界都知道并且把它写进区块中,所以不会消耗gas
还有个pure修饰符,表示这个函数甚至不会访问合约里的任何东西,他的返回值完全取决于我们的输入,例如:
function _multiply(uint a,uint b)private pure returns(uint){return a*b;}//这个函数接收我们的输入,然后把两个数的乘积返回给我们
Keccak256
Ethereum内部有一个散列函数keccak256,他会把一个字符串转换成16进制的数字
//6e91ec6b618bb462a4a6ee5aa2cb0e9cf30f7a052bb467b0ba58b8748c00d2e5keccak256("aaaab");//b1f078126895a1424524de5321b339ab00408010b7cf0e6ed451514981e58aa9keccak256("aaaac");
类型转换
uint8->uint16小单位变到大单位,值不变uint16->uint8大单位变到小单位,变为原值mod 256bytes8->bytes16后面补0bytes16->bytes8只取前面的8数address->uint按照uint的单位从地址后面开始截取对应长度address->bytes按照bytes的单位从地址前面开始截取对应长度uint/bytes->address前面填充0,直到符合address长度
事件
事件是以太坊虚拟机(EVM)日志功能中提供的一组方便的接口。当事件被触发时,它们会将参数保存到交易日志中——区块链中一种特殊的数据结构。这些日志与合约地址相关联,并且会被打包进区块中,因此可以被永久访问(不过Serenity版本或许会有所改变)。注意,日志和事件的数据是不能被合约访问的,即便是创建它们的合约也不行(不然常规的数据存储就没意义了)
event IntegersAdded(uint x,uint y,uint result);
function add(uint _x,uint _y)public{uint result=_x+_y;//触发事件,通知appIntegersAdded(_x,_y,result);return result;}