cryptokitties(以太坊云养猫)是近期出现在以太坊区块链上一个游戏。超级可爱的猫形象,再配合上繁殖,配种,拍卖这样丰富的玩法,一下子就引爆了以太坊的区块链。这款游戏的核心是基于以太坊的智能合约,也是第一款基于智能合约的游戏。这款游戏除了繁殖时候的基因工程合约以外,其他合约都是开源的,她的源码对于学习智能合约的编写有着很大的启发意义。下面是我的一点点对于智能合约和cryptokitties源码的理解,分享给大家。

(本文假设你已经有一定的编程经验,而且对cryptokitties游戏规则有一定的了解)

我配出来的小暹罗,仅售0.3ETH,欢迎联系

智能合约简述

  1. 智能合约是什么? 智能合约是一段代码,放在以太坊区块链上。

  2. 智能合约怎么执行? 当年向智能合约打钱,并且在备注中加入 调用智能合约的代码,智能合约就执行了。(一切智能函数调用本质上都是转账)

  3. 智能合约在哪里执行? 智能合约由矿工执行,执行结果记录在区块链上。

  4. contract关键字和其他语言的class关键字有什么区别? 其实两者概念差不多的,区别就是,当年用contract创建智能合约的时候,你只创建了一个contract实例,区块链返回这个实例的地址。比如cryptokitties的其中一个合约地址0x06012c8cf97bead5deae237070f9587f8e7a266d

    用伪中文代码理解就是 以太坊区块链.创建智能合约('智能合约代码') 返回 合约地址0x06012c8cf97bead5deae237070f9587f8e7a266d

  5. 什么是event关键字?event关键字定义了一个事件类型,外部程序可以通过监听某个事件来获取智能合约上的变化(观察者模型),说白了event关键字打通了智能合约状态和外部程序的通道。

  6. 什么是view关键字?初学者要记住的就是从智能合约里读取数据是不要钱的也不用发送交易,你本质是在读取你本机或者其他人机器上的区块链数据,并不修改区块链。view关键字就是告诉你,这个函数仅仅是用来读取数据的,不修改区块链。

  7. 什么是msg对象?每次你调用合约的时候,都有一个msg对象,里面放着,发送人的地址(sender属性),发送了多少钱(value属性)等等。这个对象是每个函数预先定义的。如果你不了解,很可能被这个凭空冒出来的对象弄糊涂。

更多的细节可以阅读以太坊官网。

Ownable合约

这是一个很简单的智能合约,定义了所有权,她的作用类似一个抽象的基类,后续的类通过继承她来简化代码。

modifier也是以太的关键字,定义一个修饰符,她写在函数最后,在函数执行前,先执行修饰符中代码。一般修饰符代码都是权限检查等等。

就比如这个代码,用来移交合约的所有权,onlyOwner修饰符会先执行,因为只有真正拥有这个合约的人,才有权利移交这个合约。

ERC721合约

ERC是以太坊代币标准的缩写,ERC721是以太坊区块链代表标准的一种。比较常见的是ERC20。这个标准相当于定义了一个接口,当你的合约实现了这个接口以后,钱包软件就能通过调用这些接口,监听事件等等操作你的ERC721代币。用其他编程语言来理解,比如JAVA的STRUTS框架,它定义了action接口,你通过实现action接口,接入到struts这个框架中。又或者LINUX开发中,你要写一个驱动,你必须实现file_operations 里的各种读写函数。

那ERC721代币和ERC20代币有什么不同?

ERC721代币的核心是“Non-Fungible Tokens”,不可互换的代币。怎么理解“不可互换”? 比如你有2只猫(猫A和猫B),你的代币数量就是2,但是猫A和猫B是不同的,当你卖出你的猫时,你必须指定是卖哪知猫,因为猫A和猫B是不可以互换的。类比ERC20,就好比你有2块钱,这两块钱,你花其中任意一块钱,都不影响结果,只要账户里扣一块钱就可以了。 ERC721每个代币都有一个独立唯一的tokenid,这个id在这个cryptokitties里就是猫的id,比如下面这个链接“103646”其实就是猫的tokenid。

https://www.cryptokitties.co/kitty/103646

从这个transfer函数也能看出,每次转账,只能转某个具体的猫(没有数量)。

GeneScienceInterface合约

这个合约没有源码,从名字看已经很明显,就是猫的基因工程,用于决定新出生猫的基因。这里仅仅定义了一个接口,没有具体实现,后续的调用请看后续代码分析。

KittyAccessControl合约

require关键字(函数),它类似很多编程语言里的assert,你如果括号里的条件是False,它会终止合约的执行。

相当于 if state == false: exit(),以前以太坊退出程序的时候会收走你左右的手续费,现在硬分升级以后,仅仅收取运行到这里的手续费,这样大大节约了手续费的开支。

这个合约也是一个类似抽象基类合约,定义了猫的权限控制,其中定义了3个角色,CEO,CFO,COO。

定义了一些修饰符,比如 onlyCEO只能CEO操作的方法,onlyCFO就是只能CFO操作的方法。

游戏本身可以暂停

游戏运营方可以暂停游戏,后面很多游戏的方法都有whenNotPaused修饰符,这个修饰符以一种很简洁的方式处理了游戏的暂停,避免了大量的代码重复。

上面写了一大堆终于要进入cryptokitties的正题。

KittyBase合约

首先它是继承KittyAccessControl,这样它就可以直接使用之前上面定义的一堆控制修饰符。然后看看两个事件:

Birth事件 外部程序通过关注该事件,当有猫出生的时候,就能从区块链上得到通知。cryptokitties的外部程序关注了这个事件,然后在有新猫出生的时候,给你发送邮件。Birth事件上的参数,是给外部使用的,区块链会告诉你 谁owner,获得了一直新猫(kittyId),猫的父亲母亲是谁(sireId,matronId),基因genes(是什么)

Transfer事件用于通知猫的转手。

猫的核心数据结构

猫的数据结构

Kitty结构是存储在区块链上猫的数据表示。cryptokitties也就是通过操作这个数据结构的属性变化,来完成各种猫相关的业务。

generation 猫的代数,系统生成的猫是 Gen 0表示第0代。后面的后代,代数会慢慢增长。

genes 猫的基因,决定了猫的样子,但是需要注意的是,存储在以太坊区块链上的仅仅是一个基因数据,具体的显示,本身还是由cryptokitties服务器提供的数据,也就是说,如果cryptokitties关了服务器,你的猫只是这个256位数。

birthTime出生时间,这个属性用处不大

cooldownEndBlock 还有多久可以配种,以太坊上,有关时间的操作,大多数是用区块表示的。比如当年区块号是1000,出1个块时间是15秒,那么我说,这个猫要等1分钟以后可以配种,那么其实就是要等4区块(60秒/15)以后,就是1004号区块,在1005号出来的时候,你才能进行配种。

matronId,sireId matronId表示这只猫的猫妈妈的ID,sireId表示猫爸爸ID。由于初代猫是没有猫爸爸猫妈妈(是开发团队变出来的)所以初代ID都为0。

siringWithId 配偶ID,这个游戏里,猫是没性别的,当你参与交配的时候,扮演母猫的一方拿走出生的小猫,扮演工贸的一方拿走配种费。siringWithId !=0表示这只猫正在配种,siringWithId==0表示这种猫空巢。

cooldownIndex 配种冷却时间 当年点击一只猫的时候,这个属性决定了它的剩余速度级别。

它和下面这张表是配合使用的

cooldownIndex = 0代表1分钟就是上图的FAST,1代表SWIFT。

下面的代码定义了,猫业务核心数据。

mapping是以太坊智能合约的一种数据结构,它和JAVA里的hashmap,python里的dict是一样的,就是一张hash表。这张hash表是存储在以太坊智能合约上的。

kittes数组,所有的猫都会存储在 kitties数组里,这个数组会不断增长,kittyId其实就是Kitty对象在这个数组中的下标。而kittyId其实就是erc721的tokenId。kitties数组建立了erc721 token 和猫数据结构的映射关系。通过erc721的tokenid就能够获取到Kitty对象数据.

kittyIndexToOwner表,通过这个映射,可以快速的知道,哪知猫是谁的。那为什么owner属性为什么不放在Kitty的数据结构里呢?笔者推测,很多场景并不需要获取Kitty上具体数据,如果每次要先找到猫再获取主人,效率可能比较低,毕竟智能合约的执行是要钱的。

ownershipTokenCount表,记录了谁有几只猫。

kittyIndexToApproved表,记录了一种授权操作,你可以把你的猫授权给某个地址,比如你进行拍卖的时候,你的猫其实授权给了拍卖合约,这个合约有权利将你的猫转给他人。

sireAllowedToAddress表,你可以把你的猫拿去配种,对方要和你猫的配种,必须要得到你的授权,那这张表记录了,你把你的那种猫允许谁配种。

_transfer函数 这个函数描述了猫转让的核心操作。 _from 是原持有人,_to是你要转让给谁,tokenId表示什么猫。首先对方猫数量要增加1,第二修改kittyIndexToOwner里该猫资产的所有人。这个函数里还对于from地址是否为0进行判断,因为这个猫可能是系统创建的,那from就是0。如果from是一个用户,那他的猫数量要减1,然后清除相关配种权力和转让权力。最后通过 Transfer(_from, _to, _tokenId); 发送猫转让事件,让外部系统进行通知等等。

_createKitty创建一只猫的核心函数的,首先比较有趣的是 cooldownIndex的处理,也就是说新的猫的繁殖速度是和他是第几代猫直接相关,越早代的猫繁殖冷却事件越低。然后新创建的Kitty对象会被放入Kitty数组,同时获得其KittyId。同时发送Birth事件,系统通过监听这个事件,给你发送 Your Kitty is born邮件。同时调用_transfer内部函数,分配这只猫的所有权,因为并不是用户和用户之间转让,所以_from是0表示系统转让给你。

KittyOwnership合约

上面讲的好几个合约,其实都是抽象基类,并没有部署在以太坊上,他们都是为了节约代码抽出来的。KittyOwnership合约是一个真正部署在以太坊上的合约,他定义了一个 ERC721代币。KittyOwnership把KittyBase和ERC721的接口桥接起来了。里面的很多代码,基本都是KittyBase合约的接口转换,并没有什么很特别的逻辑,大家可以自行阅读。

就挑这个方法讲一下,这个方法描述了你有几只猫,他遍历整个目前所有的猫,然后在kittyIndexToOwner查看这只猫是不是你的,因为之前记录了你有几只猫,所以查找到你所有的猫后就可以停下而不用遍历完所有的猫集合。但是这个函数依然是很昂贵的,注释的作者写到,这个函数不应该被智能合约调用,这个函数应该是本地用来查找区块链用的。他的效果就是网页的My Kitties按钮。

笔者写到这里已经虚脱,猫的繁殖和拍卖,下期再讲了,欢迎喜欢编程和区块链的朋友关注我。

转自:http://www.icokan.com/portal.php?mod=view&aid=6052

跟着cryptokitties(以太坊云养猫)学写智能合约(上)相关推荐

  1. 尚硅谷以太坊区块链学习之NFT智能合约(6)

    尚硅谷以太坊区块链学习之NFT智能合约(6) 前言 一.NFT智能合约 1.智能合约代码 2.智能合约推送 3.具体调用 二.具体使用 三.NFT商家智能合约 前言 提示:服务外包区块链学习 5被ba ...

  2. 八、 以太坊的杰出之作:智能合约

    智能合约主要有两大方面的作用,一个是用于更便捷地处理交易,一个适用于更灵活的开发的APP,也就是区块链应用. 以太坊虚拟机:虚拟机是计算机领域里面的一个术语,可以理解为一个虚拟环境,在这个虚拟环境中可 ...

  3. 基于以太坊的次高价盲拍solidity智能合约(二)

    基于以太坊的次高价盲拍solidity智能合约(二) 4.揭标 5.第三方仲裁人终结拍卖 4.揭标 揭标的过程应该是本智能合约中最复杂且具有灵魂的关键步骤. 当每个发起过竞标的用户,利用该标的隐式价格 ...

  4. 基于以太坊的测试链发布一个智能合约

    1,创建账户 使用METAMASK钱包来进行操作,具体的创建过程请自行查阅.创建好的账户如下图所示,账户余额显示为0 详情下面显示对应账户的地址,这个是最关键的信息 首先选择左上角头像旁边的按键,切换 ...

  5. 学习以太坊:瑞波也要智能合约

    瑞波自2013年诞生以来,虽以强大的性能著称,但一直不支持智能合约.以太坊凭着智能合约,却一路高歌猛进.现在,这一情况将得到改变.瑞波支持的研发团队XRPL Labs在准备推出方案"Hook ...

  6. 区块链学习(3) 以太坊测试环境编译并部署智能合约(mac版)

    选择编写智能合约的语言 Ethereum上的智能合约需要使用solidity语言来撰写.虽然还有其他能用来撰写智能合约的语言如Serpent(类Python).lll(类Fortran),但目前看到所 ...

  7. 以太坊去中心化淘宝智能合约案例

    这篇文章我们来介绍一个简易的区块链电商系统的核心功能,10多年来,我们习惯了淘宝的电商模式,淘宝为电商在中国普及做出了突出贡献,值得肯定,也完成了历史使命. 淘宝模式的核心是什么? 免费是一方面,我认 ...

  8. MIMIC 以太坊医疗项目开发(6)Web3智能合约API

    web3.js是一个库集合,你可以使用HTTP或IPC连接本地或远程以太它节点进行交互. 它具备如下性质: •通过JSON-RPC与Ethereum客户端进行交互 •支持所有的JSON-RPC方法类型 ...

  9. MIMIC 以太坊医疗项目开发(7) 医疗智能合约 sample

    本文引自<基于区块链的医疗信息系统及智能合约设计>辽宁科技大学学报 第43卷 第2期 2020年4月 Journal of University of Science and Techno ...

最新文章

  1. 如何跟踪session
  2. ASP.NET中前台javascript与后台代码调用
  3. Linux-HA 高可用开源方案 Keepalived VS Heartbeat 对比
  4. 12v小型电机型号大全_电机型号参数大全,再不怕看不懂型号了!建议收藏
  5. USB3.0超高速接口应用方案
  6. sql server 2008学习3 表组织和索引组织
  7. 远程桌面退出全屏/不能全屏/全屏切换的技巧
  8. mysql json invalid json text_MySQL 5.7新增加的json数据类型
  9. c语言 统计数量用count_C语言编程学习之递归实现汉诺塔图解!还有零基础入门视频~...
  10. C++ 常见错误(01) —— error LNK1104: 无法打开文件“avcodec.lib”
  11. mysql用shell脚本链接数据库进行操作
  12. Linux内核快速处理路径尽量多用slab而慎用kmalloc
  13. Latex 版本简历
  14. win7 便签快捷键
  15. 【AMESim】AMESim和Simulink联合仿真步骤
  16. PBRT的scene.pbrt使用方法
  17. TRANSCAD基础技巧——质心连杆生成不了?
  18. log算子 和dog 算子
  19. 语义化版本号 Sematic Versioning
  20. php拆分excel,PHPExcel合并与拆分单元格的方法

热门文章

  1. cocos2dx-3.x物理引擎Box2D介绍
  2. streaming api_XML的Streaming API简介(StAX)
  3. 先知ppt_先知对股市的预测
  4. 三年级学生计算机学情分析,[三年级语文]三年级学生学情分析
  5. Vue+Excharts画出重庆地图
  6. 【Unity】实现类似皇室战争使用“火球”将敌人“炸开”效果
  7. 车载设备上音视频应用续播功能的实现
  8. iOS 14.4 Beta 2更新内容 iOS 14.4 Beta 2升级方法
  9. 自动辅助驾驶Openpilot安装 乐视手机去电池改造
  10. 一文带你学会Shell基操