Solidity(1)

学习cryptoZombies的Solidity部分,链接地址:https://cryptozombies.io/zh/

第二章 合约

  • 合约:Solidity 的代码都包裹在合约里面。一份合约就是以太应币应用的基本模块, 所有的变量和函数都属于一份合约,它是你所有应用的起点。
//一份名为 HelloWorld 的空合约
contract HelloWorld {
}
  • 版本指令:所有的 Solidity 源码都必须冠以version pragma — 标明 Solidity 编译器的版本。例如:pragma solidity ^0.4.19;

第三章 状态变量和整数

  • 状态变量被永久地保存在合约中,也就是说它们被写入以太币区块链中。
  • 无符号整数uint:一个256位的无符号整数,其值不能是负数。也可以定义位数少的uints-uint8、uint16等。
  • 有符号整数存在名为int的数据类型。

第四章 数学运算

  • 加法: x + y
  • 减法: x - y
  • 乘法: x * y
  • 除法: x / y
  • 取模 / 求余: x % y
  • 乘方:x ** y

第五章 结构体

struct Person {
  uint age;
  string name;
}

第六章 数组

  • Solidity支持两种数组:静态数组和动态数组
// 固定长度为2的静态数组:
uint[2] fixedArray;
// 固定长度为5的string类型的静态数组:
string[5] stringArray;
// 动态数组,长度不固定,可以动态添加元素:
uint[] dynamicArray;
  • 结构体类型数组
Person[] people; // 这是动态数组,我们可以不断添加元素
  • 公共数组:Solidity会自动创建getter方法,其他合约可以从该数组读取数据,但不能写入数据。
Person[] public people;

第七章 定义函数

习惯上函数里的变量都是以_开头以区别全局变量。

function eatHamburgers(string _name, uint _amount) {
}

第八章 使用结构体和数组

  • array.push() 在数组的尾部加入新元素
  • array.push() 返回数组的长度,类型是uint
struct Person {
  uint age;
  string name;
}

Person[] public people;

// 创建一个新的Person:
Person satoshi = Person(172, "Satoshi");

// 将新创建的satoshi添加进people数组:
people.push(satoshi);

第九章 私有/公有函数

  • 默认为公有函数
  • 定义私有函数在函数名后加关键字private即可
  • 私有函数名字用_起始
function _createZombie(string _name, uint _dna) private {
      zombies.push(Zombie(_name, _dna));
}

第十章 函数的更多属性

  • 返回值:return(返回值类型)
  • 函数的修饰符:view表示只能读取数据不能更改数据;pure表示函数不能读取应用中的状态
function _generateRandomDna(string _str) private view returns(uint){
}

第十一章 Keccak256和类型转换

  • Ethereun 内部有一个散列函数Keccak256,采用SHA3版本。一个散列函数把一个字符串转换成一个256位的16进制数字。字符串一个微小的改变会引起散列数据的极大变化。
  • 类型转换:数据类型(变量)
function _generateRandomDna(string _str) private view returns (uint) {
      uint rand = uint(keccak256(_str));
      return rand % dnaModulus;
}

第十三章 事件

事件是合约和区块链通讯的一种机制。前端应用监听某些事件并做出反应 。

// 这里建立事件
event IntegersAdded(uint x, uint y, uint result);

function add(uint _x, uint _y) public {
  uint result = _x + _y;
  //触发事件,通知app
  IntegersAdded(_x, _y, result);
  return result;
}

app前端可以监听这个事件。JavaScript实现如下:

YourContract.IntegersAdded(function(error, result) {
  // 干些事
})

第十四章 Web3.js

以太坊有一个JavaScript库,名为Web3.js。

// 下面是调用合约的方式:
var abi = /* abi是由编译器生成的 */
var ZombieFactoryContract = web3.eth.contract(abi)
var contractAddress = /* 发布之后在以太坊上生成的合约地址 */
var ZombieFactory = ZombieFactoryContract.at(contractAddress)
// `ZombieFactory` 能访问公共的函数以及事件

// 某个监听文本输入的监听器:
$("#ourButton").click(function(e) {
  var name = $("#nameInput").val()
  //调用合约的 `createRandomZombie` 函数:
  ZombieFactory.createRandomZombie(name)
})

// 监听 `NewZombie` 事件, 并且更新UI
var event = ZombieFactory.NewZombie(function(error, result) {
  if (error) return
  generateZombie(result.zombieId, result.name, result.dna)
})

// 获取 Zombie 的 dna, 更新图像
function generateZombie(id, name, dna) {
  let dnaStr = String(dna)
  // 如果dna少于16位,在它前面用0补上
  while (dnaStr.length < 16)
    dnaStr = "0" + dnaStr

  let zombieDetails = {
    // 前两位数构成头部.我们可能有7种头部, 所以 % 7
    // 得到的数在0-6,再加上1,数的范围变成1-7
    // 通过这样计算:
    headChoice: dnaStr.substring(0, 2) % 7 + 1,
    // 我们得到的图片名称从head1.png 到 head7.png

    // 接下来的两位数构成眼睛, 眼睛变化就对11取模:
    eyeChoice: dnaStr.substring(2, 4) % 11 + 1,
    // 再接下来的两位数构成衣服,衣服变化就对6取模:
    shirtChoice: dnaStr.substring(4, 6) % 6 + 1,
    //最后6位控制颜色. 用css选择器: hue-rotate来更新
    // 360度:
    skinColorChoice: parseInt(dnaStr.substring(6, 8) / 100 * 360),
    eyeColorChoice: parseInt(dnaStr.substring(8, 10) / 100 * 360),
    clothesColorChoice: parseInt(dnaStr.substring(10, 12) / 100 * 360),
    zombieName: name,
    zombieDescription: "A Level 1 CryptoZombie",
  }
  return zombieDetails
}
posted @ 2020-11-17 09:41  又又又8  阅读(222)  评论(0编辑  收藏  举报