罗韭菜的solidity 学习(六)枚举、结构体与字典&映射

枚举体

  • 可以理解为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;
    }
}

你可能感兴趣的:(罗韭菜的solidity 学习(六)枚举、结构体与字典&映射)