第二课是僵尸猎食,将把app变得更像一个游戏,添加多人模式,建立更多创造僵尸的方法。


chapter1
  依然是简介

chapter2:映射和地址

  映射相当于一个索引,指向不同地址,不同地址存储的数据不同,相当于一种特殊的存储结构。此例中用来存储每个僵尸的上一级。

mapping(address=>uint) public accountBalance;

  key是address,value是uint。

 

chapter3: msg.sender

  指向调用函数的用户地址。注意:智能合约部署在区块链上,只有当一个外部账户调用智能合约的函数时才会执行合约,所以msg.sender总是存在的。

  一个例子:

mapping (address => uint) favoriteNumber;

function setMyNumber(uint _myNumber) public {
  // Update our `favoriteNumber` mapping to store `_myNumber` under `msg.sender`
  favoriteNumber[msg.sender] = _myNumber;
  // ^ The syntax for storing data in a mapping is just like with arrays
}

function whatIsMyNumber() public view returns (uint) {
  // Retrieve the value stored in the sender's address
  // Will be `0` if the sender hasn't called `setMyNumber` yet
  return favoriteNumber[msg.sender];
}

  相对于其他存储方式,运用_msg.sender更为安全,只有当你的私钥泄露时,别人才能更改你的账户数据。

 

chapter4:require

  使用require编辑限制条件,不满足条件时程序会抛出异常。

  例子:

function sayHiToVitalik(string _name) public returns (string) {
  // Compares if _name equals "Vitalik". Throws an error and exits if not true.
  // (Side note: Solidity doesn't have native string comparison, so we
  // compare their keccak256 hashes to see if the strings are equal)
  require(keccak256(_name) == keccak256("Vitalik"));
  // If it's true, proceed with the function:
  return "Hi!";
}

  solidity中字符串不能直接比较,所以将字符串进行keccak256编码再做比较。

  注:solidity比较时对两边顺序没有固定要求。

 

chapter5:继承

  类似其他面向对象语言的继承,可继承父亲的public函数等。

contract Dog is Animal{}

 

chapter6:引入

  类似其他语言的库,易于长代码的模块化编辑和管理。

 

chapter7:storage 和 memory

  storage 和 memory 是solidity中变量的两种存储方式,storage 永久存储在区块链上,而memory会在外部函数调用时清除,有点类似计算机的磁盘和ram。solidity默认函数外定义的状态变量是storage存储,而函数内定义的变量是memory形式存储。

  当然有时需要手动定义来满足一些需求,不过不用担心,solidity编译器会在你定义不恰当的时候提出warning。

contract SandwichFactory {
  struct Sandwich {
    string name;
    string status;
  }

  Sandwich[] sandwiches;

  function eatSandwich(uint _index) public {
    // Sandwich mySandwich = sandwiches[_index];

    // ^ Seems pretty straightforward, but solidity will give you a warning
    // telling you that you should explicitly declare `storage` or `memory` here.

    // So instead, you should declare with the `storage` keyword, like:
    Sandwich storage mySandwich = sandwiches[_index];
    // ...in which case `mySandwich` is a pointer to `sandwiches[_index]`
    // in storage, and...
    mySandwich.status = "Eaten!";
    // ...this will permanently change `sandwiches[_index]` on the blockchain.

    // If you just want a copy, you can use `memory`:
    Sandwich memory anotherSandwich = sandwiches[_index + 1];
    // ...in which case `anotherSandwich` will simply be a copy of the 
    // data in memory, and...
    anotherSandwich.status = "Eaten!";
    // ...will just modify the temporary variable and have no effect 
    // on `sandwiches[_index + 1]`. But you can do this:
    sandwiches[_index + 1] = anotherSandwich;
    // ...if you want to copy the changes back into blockchain storage.
  }
}

 

chapter8: Zombie Dna

chapter9: 更多关于函数可见化的问题

  除了public和private,solidity中还有internal和external来控制函数可见化。

  internal类似于private,但有一点不同,internal定义的函数可以为外部继承合约调用,而private不行。

  external类似于public,但external定义的函数只能被其他合约调用,本合约内的函数不能调用。

  两者添加定义的方法相同。

 

chapter10:僵尸吃什么

   吃cryptoketties。估计是作者的恶作剧。实际上并不会对cryptokitties的数据产生什么影响,只是读取其中的数据。

  所以本章的主题就是和其他的智能合约交互。定义一个新合约,合约只含需要调用的合约内的函数头部,不含其他任何函数或者变量,且用“;”代替函数体大括号。

  比如有一个合约:

contract LuckyNumber {
  mapping(address => uint) numbers;

  function setNum(uint _num) public {
    numbers[msg.sender] = _num;
  }

  function getNum(address _myAddress) public view returns (uint) {
    return numbers[_myAddress];
  }
}

  外部合约需要调用getNum函数,则定义接口:

contract NumberInterface {
  function getNum(address _myAddress) public view returns (uint);
}

 

chapter11: 使用接口

contract MyContract {
  address NumberInterfaceAddress = 0xab38... 
  // ^ The address of the FavoriteNumber contract on Ethereum
  NumberInterface numberContract = NumberInterface(NumberInterfaceAddress);
  // Now `numberContract` is pointing to the other contract

  function someFunction() public {
    // Now we can call `getNum` from that contract:
    uint num = numberContract.getNum(msg.sender);
    // ...and do something with `num` here
  }
}

  定义一个接口合约地址就好

 

chapter12:多参数返回值

  例子:

function multipleReturns() internal returns(uint a, uint b, uint c) {
  return (1, 2, 3);
}

function processMultipleReturns() external {
  uint a;
  uint b;
  uint c;
  // This is how you do multiple assignment:
  (a, b, c) = multipleReturns();
}

// Or if we only cared about one of the values:
function getLastReturnValue() external {
  uint c;
  // We can just leave the other fields blank:
  (,,c) = multipleReturns();
}

  后续函数调用多参数返回函数时,可以只返回一个或若干个值,但要把其他返回值空出来,加逗号隔开就行。

 

chapter13:奖励:kitty基因

   让那些继承自kitty的zombies有独特的特征,即修改定义僵尸特征的16位数的最后两位。

chapter14:部署合约

 

内容来源于网络如有侵权请私信删除
你还没有登录,请先登录注册
  • 还没有人评论,欢迎说说您的想法!