本人培育的鸭子,只要0.2ETH便宜了
kittes数组,所有的猫都会存储在 kitties数组里,这个数组会不断增长,kittyId其实就是Kitty对象在这个数组中的下标。而kittyId其实就是erc721的tokenId。kitties数组建立了erc721 token 和猫数据结构的映射关系。通过erc721的tokenid就能够获取到Kitty对象数据.
kittyIndexToOwner表,通过这个映射,可以快速的知道,哪知猫是谁的。那为什么owner属性为什么不放在Kitty的数据结构里呢?笔者推测,很多场景并不需要获取Kitty上具体数据,如果每次要先找到猫再获取主人,效率可能比较低,毕竟智能合约的执行是要钱的。
ownershipTokenCount表,记录了谁有几只猫。
kittyIndexToApproved表,记录了一种授权操作,你可以把你的猫授权给某个地址,比如你进行拍卖的时候,你的猫其实授权给了拍卖合约,这个合约有权利将你的猫转给他人。
sireAllowedToAddress表,你可以把你的猫拿去配种,对方要和你猫的配种,必须要得到你的授权,那这张表记录了,你把你的那种猫允许谁配种。
这几个属性几乎记录了,所有猫的所有权和配种操作。
KittyBreeding合约
event Pregnant 定义了怀孕事件,两只猫成功配种以后就会通知。
geneScience属性是一个比较重要的属性所谓的基因工程,他是一个外部合约,这个合约负责决定两只猫生下来小猫的样子。通过setGeneScienceAddress函数可以随时更换猫咪基因工程算法。
_isReadyToBreed 判断猫咪是否可以进行生育,2个条件,一个是 公猫配偶ID要是0,第二个就是冷却时间OK。
_isSiringPermitted 判断两只猫是否可以配种,先通过公猫母猫ID,拿到所有者。如果两只猫都是你的,你就可以配种。如果不是同一人的,需要查询sireAllowedToAddress表来确定,公猫所有者是否允许你进行配种。
_triggerCooldown 这个函数是在猫咪生育之后触发生育冷却时间的,可以看到。第一行先计算了预计冷却到第几个区块之后更新生育冷却时间cooldownIndex,也就是说,每生育一次,生育速度都会下降,直到最后生育一次几个小时。
approveSiring 授权配种,核心还是修改sireAllowedToAddress表。
isPregnant判断母猫怀孕的函数,核心还是看siringWithId属性。
_isValidMatingPair是一个比较有趣的函数。cryptokitties里的猫也不是你想配就随便能配的,他要满足几个条件。
-
自己不能和自己配(这不是废话么,但是代码不知道哦。)
-
不能和自己的父母交配(其实这个事情在现实的猫舍中很常见,可能cryptokitties还是很人道的)
-
有兄弟关系的不能配(说白了,同父异母,同母异父都不能配)
满足上面3点就才允许两只猫配种生新的猫。
_breedWith两只猫配种的核心函数。做了几件事情
-
matron.siringWithId = uint32(_sireId); 设置母猫的配偶,前面说了,确定是否怀孕就是看这个属性
-
触发生育冷却,_triggerCooldown这个函数上文也讲过,每次触发冷却,都会让猫的生育速度下降一个档次
-
清空配种sireAllowedToAddress配种权力表(同意一次只能配一次,不然人家就反复配啦)
-
发送两只猫怀孕事件
giveBirth函数,调用以后就产生新的猫了。(笔者这里有疑问,这个函数其实并没有在实际操作中见到过,不知道是谁调用的,难道是cryptokitties公司调用么(函数本谁都可以调用)。这个函数做了如下事情:
-
确定新出生猫是第几代的,注意,他总是选更大代数+1。比如你一只0代猫和一只5代猫配,配出来是一直6代猫。感觉代数如果差距比较大配种不太划算。
-
geneScience.mixGenes基因工程合约确定新生猫的基因,由于基因工程的合约并不开源,所以生什么猫还是可以控制的,说不定哪天搞活动生出很多超梦猫。
-
调用_createKitty产生一只新猫,母猫的所有者即是新生猫的所有者。
-
清空母猫的配偶信息。
-
调用该函数还需要支付生育金。
至此,猫咪培育的部分就说完了。
猫咪拍卖和配种拍卖
ClockAuctionBase基于时间的基础拍卖合约
这是一个很棒的基类合约,他定义了一次拍卖的基础操作。
定义了一个基础的拍卖数据结构Auction。nonFungibleContract是ERC721代币(这里就是只每只猫,该合约细节上期讲过)。这个拍牌是实质是拍卖任何ERC721代币,其实这代码不止可以用在猫上,还可以用在很多地方。
检验你是否拥有这个TOKEN。
当你要进行拍卖的时候,你需要将你的物品交给这个合约托管。
移交物品的所有权。
_addAuction添加一个拍卖,实质拍卖对象是外部创建的。由于不同拍卖,拍卖对象可能不同,所以这个里是对象级别。
_cancelAuction删除一个拍卖,这里可以看到,删除的时候,会把托管的token(猫)还给用户。
_bid表示拍下物品,这个代码比较长,我删除一些检查方便截图。
-
先实时计算价格,看看出价够不够
-
删除拍卖,同时收取拍卖手续费
-
然后给卖家打钱
-
退回多余的钱
-
发布拍卖成功事件。
KittyAuction合约
这个合约实际真正负责了,猫咪的拍卖和配种拍卖。
bidOnSiringAuction当我们在界面上点击付费配种的时候,实际调用的是这个函数。
这个函数会先走
siringAuction.bid.value(msg.value - autoBirthFee)(_sireId); 做配种竞拍,如果能成功才会走下一行。
最后就调用 _breedWith 让两只猫进行配种。
还有一个是猫咪拍卖,其实这个就是基础的拍卖ERC721 TOKE转让,上文已经说过。
KittyMinting合约
这个合约是cryptokitties团队控制,用来生产0代猫。
创造一直0代猫,并投放到竞拍市场。
0代猫的价格计算,是平均卖价的150%,开发团队真的有点黑心的。
写到这里,cryptokitties的智能合约代码基本分析完了。个人觉得,代码写的非常有功力,条理清晰,目的明确。同时注释也比较多,非常适合作为智能合约的学习资料。有些不知道哪里找源码的朋友,可以关注我然后私信给我,我把我这份自己写有一些注释的版本发给你。以后会有很多更多好文分享。