枚举体
- 可以理解为ActionChoices就是一个自定义的整型,当枚举数不够多时,它默认的类型为uint8,当枚举数足够多时,它会自动变成uint16,下面的GoLeft == 0,GoRight == 1, GoStraight == 2, SitStill == 3。在setGoStraight方法中,我们传入的参数的值可以是0 - 3当传入的值超出这个范围时,就会中断报错。
pragma solidity ^0.4.4;
contract test {
enum ActionChoices { GoLeft, GoRight, GoStraight, SitStill }
ActionChoices _choice;
ActionChoices constant defaultChoice = ActionChoices.GoStraight;
function setGoStraight(ActionChoices choice) public {
_choice = choice;
}
function getChoice() constant public returns (ActionChoices) {
return _choice;
}
function getDefaultChoice() pure public returns (uint) {
return uint(defaultChoice);
}
}
结构体
pragma solidity ^0.4.4;
contract Students {
struct Person {
uint age;
uint stuID;
string name;
}
Person _person = Person(18,101,"liyuechun");
}
- 初始化方法(两种)
Person [] persons = new Person[](3);
Person _person1 = Person(18,101,"melody");
Person _peson2 = Person({age:18, stuID:103, name:"luoxue"});
Person _person3 = Person(18,101,"melody");
// 构造函数
function Students(){
persons[0] = _person1;
persons[1] =_person2;
persons[2] = _person3;
}
- 指针默认是storage类型,但是状态变量默认是memory,所以在使用时需要加上memory, 因此创建一个memory类型方式如下
pragma solidity ^0.4.4;
contract Students {
struct Person {
uint age;
uint stuID;
string name;
}
function personInit() {
Person memory person = Person({age:18,stuID:101,name:"liyuechun"});
}
}
字典与映射
语法
mapping(_keytype =>_valuetype)
key不能相同,value可以相同,其实就是映射,举例子
{age:22, height: 160, name:melody}
pragma solidity ^0.4.4;
contract MappingExample {
// 测试账号
// 0xca35b7d915458ef540ade6068dfe2f44e8fa733c
// 0x14723a09acff6d2a60dcdf7aa4aff308fddc160c
// 0x4b0897b0513fdc7c541b6d9d7e929c4e5364d2db
mapping(address => uint) balances;
function update(address a,uint newBalance) public {
balances[a] = newBalance;
}
// {0xca35b7d915458ef540ade6068dfe2f44e8fa733c: 100,
//0x14723a09acff6d2a60dcdf7aa4aff308fddc160c: 200,
//0x4b0897b0513fdc7c541b6d9d7e929c4e5364d2db: 300 }
function searchBalance(address a) constant public returns (uint) {
return balances[a];
}
}
综合案例
- 下面的案例是一个集资合约的案例,里面有两个角色,一个是投资人Funder,也就是出资者。另一个角色是运动员Campaign,被赞助者。一个Funder可以给多个Campaign赞助,一个Campaign也可以被多个Funder赞助。
- 完整合约如下:
pragma solidity ^0.4.4;
contract CrowdFunding {
// 定义一个`Funder`结构体类型,用于表示出资人,其中有出资人的钱包地址和他一共出资的总额度。
struct Funder {
address addr; // 出资人地址
uint amount; // 出资总额
}
// 定义一个表示存储运动员相关信息的结构体
struct Campaign {
address beneficiary; // 受益人钱包地址
uint fundingGoal; // 需要赞助的总额度
uint numFunders; // 有多少人赞助
uint amount; // 已赞助的总金额
mapping (uint => Funder) funders; // 按照索引存储出资人信息
}
uint numCampaigns; // 统计运动员(被赞助人)数量
mapping (uint => Campaign) campaigns; // 以键值对的形式存储被赞助人的信息
// 新增一个`Campaign`对象,需要传入受益人的地址和需要筹资的总额
function newCampaign(address beneficiary, uint goal) public returns (uint campaignID) {
campaignID = numCampaigns++; // 计数+1
// 创建一个`Campaign`对象,并存储到`campaigns`里面
campaigns[campaignID] = Campaign(beneficiary, goal, 0, 0);
}
// 通过campaignID给某个Campaign对象赞助
function contribute(uint campaignID) public payable {
Campaign storage c = campaigns[campaignID];// 通过campaignID获取campaignID对应的Campaign对象
c.funders[c.numFunders++] = Funder({addr: msg.sender, amount: msg.value}); // 存储投资者信息
c.amount += msg.value; // 计算收到的总款
c.beneficiary.transfer(msg.value);
}
// 检查某个campaignID编号的受益人集资是否达标,不达标返回false,否则返回true
function checkGoalReached(uint campaignID) public returns (bool reached) {
Campaign storage c = campaigns[campaignID];
if (c.amount < c.fundingGoal)
return false;
return true;
}
}