这是个人solidity学习整理第一篇
合约
Solidity 的代码都包裹在合约里面.
一份合约就是以太应币应用的基本模块, 所有的变量和函数都属于一份合约, 它是所有应用的起点.
一份名为 HelloWorld 的空合约如下:
`contract HelloWorld {
}`
版本指令
所有的 Solidity 源码都必须冠以 "version pragma" — 标明 Solidity 编译器的版本. 以避免将来新的编译器可能破坏你的代码。
综上所述,下面就是一个最基本的合约,每次新建一个项目时的第一段代码:
事件
事件 是合约和区块链通讯的一种机制。你的前端应用“监听”某些事件,并做出反应。
你的 app 前端可以监听这个事件。JavaScript 实现如下:
状态变量
状态变量是被永久地保存在合约中。也就是说它们被写入以太币区块链中. 想象成写入一个数据库。
uint mynum = 100;
定义 mynum 为 uint 类型,并赋值100。
无符号整数: uint
uint 无符号数据类型, 指其值不能是负数,对于有符号的整数存在名为 int 的数据类型。
注:Solidity中, uint 实际上是 uint256代名词, 一个256位的无符号整数。你也可以定义位数少的uints — uint8, uint16, uint32, 等
string
字符串用于保存任意长度的 UTF-8 编码数据。 如:
string hh = "Hello world!"
数组
如果你想建立一个集合,可以用 数组 这样的数据类型. Solidity 支持两种数组: 静态数组和动态数组
uint[2] Array; 固定长度为2的静态数组 uint[ ] Array; 动态数组,长度不固定,可以动态添加元素
状态变量被永久保存在区块链中。所以在你的合约中创建动态数组来保存成结构的数据是非常有意义的。
可以建立一个 结构体类型的数组
Person[] people;
结构体
结构体允许生成一个更复杂的数据类型,它有多个属性。
使用结构体和数组
创建新的结构体
创建一个新的Person:
Person xiannv = Person(172, "xiannv");
将新创建的xiannv添加进people数组:
people.push(xiannv);
数学运算
- 加法: x + y
- 减法: x - y
- 乘法: x * y
- 除法: x / y
- 取模 / 求余: x % y
- 乘方:x**y
定义函数
function eatHamburgers(string _name, uint _amount) { } 名为 eatHamburgers的函数,它接受两个参数:一个
string类型的 和 一个uint类型的。
习惯上函数里的变量都是以(_)开头 (但不是硬性规定) 以区别全局变量。
私有 / 公共函数
Solidity 定义的函数的属性默认为公共。 这就意味着任何一方 (或其它合约) 都可以调用你合约里的函数。
显然,不是什么时候都需要这样,而且这样的合约易于受到攻击。 所以将自己的函数定义为私有是一个好的编程习惯,只有当你需要外部世界调用它时才将它设置为公共。
设置一个私有函数
在函数名字后面使用关键字 private 即可
function _addToArray(uint _number) private {
}
这意味着只有我们合约中的其它函数才能够调用这个函数
函数的返回值和修饰符
要想函数返回一个数值,函数的定义里可包含返回值的数据类型
修饰符
上面的函数实际上没有改变 Solidity 里的状态,即,它没有改变任何值或者写任何东西。
这种情况下我们可以把函数定义为 view, 意味着它只能读取数据不能更改数据:
function sayHello() public view returns (string) {} Solidity 还支持 pure 函数, 表明这个函数甚至都不访问应用里的数据。
这个函数甚至都不读取应用里的状态 — 它的返回值完全取决于它的输入参数,在这种情况下我们把函数定义为 pure.
可能很难记住何时把函数标记为 pure/view。 Solidity 编辑器会给出提示,提醒你使用这些修饰符
Keccak256 和 类型转换
如何让函数返回一个全(半) 随机的 uint
Ethereum 内部有一个散列函数keccak256,它用了SHA3版本。一个散列函数基本上就是把一个字符串转换为一个256位的16进制数字。字符串的一个微小变化会引起散列数据极大变化
输入字符串只改变了一个字母,输出就已经天壤之别了
在区块链中安全地产生一个随机数是一个很难的问题, 本例的方法不安全。
类型转换
有时你需要变换数据类型。
uint8 a = 5;
uint b = 6;
uint8 c = a * uint8(b);