之前以太坊有个养猫dapp火爆一时,我们按照养猫的思路来搭建一个养僵尸的dapp,整个小项目的代码已上传到github:https://github.com/lightTrace/contract ,可参照对比学习!
首先建立我们的僵尸军团, 让我们先建立一个基础合约,称为 ZombieFactory。
一.建立一个空合约 ZombieFactory。
pragma solidity ^0.4.19;
contract ZombieFactory {
}
所有的 Solidity 源码都必须冠以 “version pragma” — 标明 Solidity 编译器的版本. 以避免将来新的编译器可能破坏你的代码。
例如: pragma solidity ^0.4.19;
而contract 就相当于Java的class,实际上contract是一门静态语言,语法和Java很像,只是声明结构上会有所区别!
二.定义一个僵尸的dna,由一个十六位整数组成:
pragma solidity ^0.4.19;
contract ZombieFactory {
uint dnaDigits = 16;
uint dnaModulus = 10 ** dnaDigits;
}
uint 无符号数据类型, 指其值不能是负数,对于有符号的整数存在名为 int 的数据类型,上面的dnaModulus为一个十六位整数。
三.复杂的数据结构
在Java中我们常常用集合来存放不同类型的数据,solidity同样也有类似的操作,它叫结构体,我们赋予一个僵尸name和dna的属性:
pragma solidity ^0.4.19;
contract ZombieFactory {
uint dnaDigits = 16;
uint dnaModulus = 10 ** dnaDigits;
struct Zombie{
string name;
uint dna;
}
}
四.数组
使用solidity创建的合约保存数据是永久保存在区块链上,所以创建动态不指定长度的数组很有必要,我们现在想把多个僵尸放到数组中,即创建一个zombies数组来保存Zombie的结构体:
pragma solidity ^0.4.19;
contract ZombieFactory {
uint dnaDigits = 16;
uint dnaModulus = 10 ** dnaDigits;
struct Zombie {
string name;
uint dna;
}
Zombie[] public zombies;
}
上面的zombies数组为public,合约会自动创建getter方法,其它合约可以读取zombies的数据,但不能写入!!!
五.定义函数
函数也就是所谓的方法,所有的编程语言都逃不过给函数参数,通过函数转换成想要的结果返回给我们,我们现在创建一个创造僵尸的函数,即创建一个Zombie,把它扔进zombies数组:
pragma solidity ^0.4.9
contract ZombieFactory{
uint dnaDigits = 16;
uint dnaModulus = 10 ** dnaDigits;
struct Zombie {
string name;
uint dna;
}
Zombie[] public zombies;
function createZombie(string name,uint dna){
zombies.push(Zombie(_name, _dna));
}
}
我们创建的函数默认属性是公有的(public),这意味着其它合约也可以调用这个函数,这显然是不合理的,同样和我们Java中一样,使用private来声明其私有属性,即:
function createZombie(string name,uint dna) private{
zombies.push(Zombie(_name, _dna));
}
这意味着只有合约中的其他函数才能调用它,是不是感觉真的和Java差不多,反正我是这么感觉的。
函数还有更多的属性,例如加上view表示函数只能读取数据而不能更改数据,而加上pure甚至表示函数不会访问合约里的数据,我们现在想创建一个随机生成dna的函数,如下:
pragma solidity ^0.4.19;
contract ZombieFactory {
uint dnaDigits = 16;
uint dnaModulus = 10 ** dnaDigits;
struct Zombie {
string name;
uint dna;
}
Zombie[] public zombies;
function _createZombie(string _name, uint _dna) private {
zombies.push(Zombie(_name, _dna));
}
function _generateRandomDna(string _str) private view returns (uint) {
}
}
function _generateRandomDna(string _str) private view returns (uint) { }表示这个函数只能被同一合约其他函数读取数据。