CryptoKittes(加密猫,谜恋猫)智能合约结构和源码解析_加密猫智能合约编写-程序员宅基地

技术标签: 7.杂七杂八  

  CryptoKittes(加密猫、谜恋猫,https://www.cryptokitties.co/)是运行在以太坊上的一个游戏。 谜恋猫是世界首款架构在区块链技术上的数字猫收集与繁殖游戏,同样的技术突破使得比特币和以太坊的运作的基础。

  具体可以参考如下两篇参考资料:

  查看代码两个地方都可以

  查看源码,我画了如下的图,主要结构如下:

  • 猫的属性
  • 主要逻辑就是从上到下继承关系
  • 拍卖合约和繁殖合约
  • 遵循ERC721协议和基因科学合约(源码未公布)

   

下面我阅读源码的笔记,没有贴源码,请参照如上地址,阅读源码:

一、合约部分
1、权限:交易需要本人账号操作,CEO/CFO/COO有特殊权限(onlyCLevel指CEO/CFO/COO皆可)
1)onyCLLevel:设置区块产生速度(多少秒一个区块);提取拍卖所佣金到CFO账号;
2)CEO:暂停、启动整个合约、指定Kitty新合约地址、销售拍卖和交配权合约地址
3)COO: 生成宣传猫、初代猫,设置生育费
4)CFO: 提取佣金
2、基因科学合约(繁殖部分)未公布源码

3、主要合约分为:ERC271协议、权限控制、权属、繁殖、拍卖(猫交易、交配权拍卖)、创造(宣传猫、初代猫)
4、下面的代码是存储各种关系的数据结构,Kitty[] kitties是所有猫的数组,mapping我理解就是key-value的哈希表

  // An approximation of currently how many seconds are in between blocks.
    uint256 public secondsPerBlock = 15;

    /*** STORAGE ***/

    /// @dev An array containing the Kitty struct for all Kitties in existence. The ID
    ///  of each cat is actually an index into this array. Note that ID 0 is a negacat,
    ///  the unKitty, the mythical beast that is the parent of all gen0 cats. A bizarre
    ///  creature that is both matron and sire... to itself! Has an invalid genetic code.
    ///  In other words, cat ID 0 is invalid... ;-)
    Kitty[] kitties;

    /// @dev A mapping from cat IDs to the address that owns them. All cats have
    ///  some valid owner address, even gen0 cats are created with a non-zero owner.
    mapping (uint256 => address) public kittyIndexToOwner;

    // @dev A mapping from owner address to count of tokens that address owns.
    //  Used internally inside balanceOf() to resolve ownership count.
    mapping (address => uint256) ownershipTokenCount;

    /// @dev A mapping from KittyIDs to an address that has been approved to call
    ///  transferFrom(). Each Kitty can only have one approved address for transfer
    ///  at any time. A zero value means no approval is outstanding.
    mapping (uint256 => address) public kittyIndexToApproved;

    /// @dev A mapping from KittyIDs to an address that has been approved to use
    ///  this Kitty for siring via breedWith(). Each Kitty can only have one approved
    ///  address for siring at any time. A zero value means no approval is outstanding.
    mapping (uint256 => address) public sireAllowedToAddress;

    /// @dev The address of the ClockAuction contract that handles sales of Kitties. This
    ///  same contract handles both peer-to-peer sales as well as the gen0 sales which are
    ///  initiated every 15 minutes.
    SaleClockAuction public saleAuction;

    /// @dev The address of a custom ClockAuction subclassed contract that handles siring
    ///  auctions. Needs to be separate from saleAuction because the actions taken on success
    ///  after a sales and siring auction are quite different.
    SiringClockAuction public siringAuction;
二、猫的属性
1、基因是256位标记,猫没有性别,既可以当母亲,也可以当父亲
2、猫出生时间戳为代码执行系统时间
3、所有猫放在数组中,宣传猫和初代猫父母ID为0,怀孕的猫记录配偶的ID,用来判断是否怀孕,小猫出生后父亲ID就是母亲配偶ID
   ID是数组的索引,猫的ID是uint32,共40亿的量,以太坊每年5亿的交易量,使用ID的地方都需要溢出检查
4、后代的代,父母的代中最大的一个加1,比如0代和1代生出的小猫代为2
5、冷却时间,1分钟-7天共14档,出生后初始值是代除以2[ floor(generation/2) ],比如2代出生后冷却就是1档,5代就是2档,以后每交配一次增加一档,最大是14档(7d)

    14档{1m,2m,5m,10m,30m,1h,2h,4h,8h,16h,1d,2d,4d,7d}

    /// @dev A lookup table indicating the cooldown duration after any successful
    ///  breeding action, called "pregnancy time" for matrons and "siring cooldown"
    ///  for sires. Designed such that the cooldown roughly doubles each time a cat
    ///  is bred, encouraging owners not to just keep breeding the same cat over
    ///  and over again. Caps out at one week (a cat can breed an unbounded number
    ///  of times, and the maximum cooldown is always seven days).
    uint32[14] public cooldowns = [
        uint32(1 minutes),
        uint32(2 minutes),
        uint32(5 minutes),
        uint32(10 minutes),
        uint32(30 minutes),
        uint32(1 hours),
        uint32(2 hours),
        uint32(4 hours),
        uint32(8 hours),
        uint32(16 hours),
        uint32(1 days),
        uint32(2 days),
        uint32(4 days),
        uint32(7 days)
    ];

    冷却时间确定了之后,会根据冷却时间除以区块的生成速度计算冷却区块索引
    冷却时间的区块索引,这个是计算生猫后小猫记录区块的位置,防止溢出

    交配后母猫冷却时间为怀孕时间,公猫也有相应的冷却时间

下面代码是Kitty的数据结构,好好理解一下

 /// @dev The main Kitty struct. Every cat in CryptoKitties is represented by a copy
    ///  of this structure, so great care was taken to ensure that it fits neatly into
    ///  exactly two 256-bit words. Note that the order of the members in this structure
    ///  is important because of the byte-packing rules used by Ethereum.
    ///  Ref: http://solidity.readthedocs.io/en/develop/miscellaneous.html
    struct Kitty {
        // The Kitty's genetic code is packed into these 256-bits, the format is
        // sooper-sekret! A cat's genes never change.
        uint256 genes;

        // The timestamp from the block when this cat came into existence.
        uint64 birthTime;

        // The minimum timestamp after which this cat can engage in breeding
        // activities again. This same timestamp is used for the pregnancy
        // timer (for matrons) as well as the siring cooldown.
        uint64 cooldownEndBlock;

        // The ID of the parents of this kitty, set to 0 for gen0 cats.
        // Note that using 32-bit unsigned integers limits us to a "mere"
        // 4 billion cats. This number might seem small until you realize
        // that Ethereum currently has a limit of about 500 million
        // transactions per year! So, this definitely won't be a problem
        // for several years (even as Ethereum learns to scale).
        uint32 matronId;
        uint32 sireId;

        // Set to the ID of the sire cat for matrons that are pregnant,
        // zero otherwise. A non-zero value here is how we know a cat
        // is pregnant. Used to retrieve the genetic material for the new
        // kitten when the birth transpires.
        uint32 siringWithId;

        // Set to the index in the cooldown array (see below) that represents
        // the current cooldown duration for this Kitty. This starts at zero
        // for gen0 cats, and is initialized to floor(generation/2) for others.
        // Incremented by one for each successful breeding action, regardless
        // of whether this cat is acting as matron or sire.
        uint16 cooldownIndex;

        // The "generation number" of this cat. Cats minted by the CK contract
        // for sale are called "gen0" and have a generation number of 0. The
        // generation number of all other cats is the larger of the two generation
        // numbers of their parents, plus one.
        // (i.e. max(matron.generation, sire.generation) + 1)
        uint16 generation;
    }
三、繁殖
繁殖的过程分为:
1)出售交配权(公猫),母猫主人拍卖,交配、怀孕、生产
2)相同账号的两只猫可以繁殖,只有后面三个过程

条件
1)母猫主人生育费是否够2 Finney(1 ETH=1000 Finney)
2)需要公猫的用户授权(拍卖)
3)母猫未怀孕,且双方过了冷却时间
4)是否可以交配,父母和子女,兄妹之间都不可以

怀孕
1)怀孕后,母猫和公猫都增加一档冷却时间,母猫的冷却时间就是怀孕时间

出生
1)检查怀孕时间超过冷却时间
2)新生猫的代是最大的父母代+1
3)基因由父母基因遗传+突变

4)出生的小猫归母猫主人所有

繁殖的逻辑比较复杂,我这里就不贴代码了

四、拍卖猫
价格单位
//1: wei  Wei  Dai  戴伟 密码学家 ,发表 B-money
//10^3: lovelace   Ada Lovelace 洛夫莱斯 世界上第一位程序员、诗人拜伦之女
//10^6: babbage  Charles Babbage 巴贝奇  英国数学家、发明家兼机械工程师,提出了差分机与分析机的设计概念,被视为计算机先驱。
//10^9: shannon  Claude Elwood Shannon 香农  美国数学家、电子工程师和密码学家,被誉为信息论的创始人
//10^12: szabo    Nick Szabo  尼克萨博  密码学家、智能合约的提出者
//10^15: finney   Hal Finney   芬尼  密码学家、工作量证明机制(POW)提出
//10^18: ether     以太
1)条件:猫没有在卖猫/交配权的拍卖中,没有怀孕,
2)有交易费率,交易税率以当前价格乘以税率,拍卖价格以wei为单位
3)添加拍卖后,猫的所属就交给拍卖合约了,猫不能做其他事情了
4)拍卖持续时间大于1分钟,起始价格一般(也可以低)比最后价格高,价格线性下降
5)买家出价不低于当前价格就能买下(比如初始100,最后50,100秒,在第20秒时,价格20*(100-50)/100+50=60,出价大于等于60即可)
    真正扣费时是以交易时价格为准,剩余的金额会返回给买家
6)会记录0代猫的最新5只拍卖价格

五、拍卖交配权
1)条件:猫没有在猫交易/交配权的拍卖中,可以交配;符合交配规则
2)固定交易费
3)拍卖成功了直接繁殖

六、宣传猫和初代猫(COO有权限)
1)宣传猫直接给账号,初代猫放到市场拍卖;宣传猫5000只,初代猫45000只
2)初代猫默认价格10 Finney,默认拍卖时间1天

3)下一只初代猫开始价格为前五只猫的平均拍卖价格的1.5倍,如果小于默认价格,设为默认价格,最后价格为0,开始拍卖!

    /// @dev we can create promo kittens, up to a limit. Only callable by COO
    /// @param _genes the encoded genes of the kitten to be created, any value is accepted
    /// @param _owner the future owner of the created kittens. Default to contract COO
    function createPromoKitty(uint256 _genes, address _owner) external onlyCOO {
        address kittyOwner = _owner;
        if (kittyOwner == address(0)) {
             kittyOwner = cooAddress;
        }
        require(promoCreatedCount < PROMO_CREATION_LIMIT);

        promoCreatedCount++;
        _createKitty(0, 0, 0, _genes, kittyOwner);
    }

    /// @dev Creates a new gen0 kitty with the given genes and
    ///  creates an auction for it.
    function createGen0Auction(uint256 _genes) external onlyCOO {
        require(gen0CreatedCount < GEN0_CREATION_LIMIT);

        uint256 kittyId = _createKitty(0, 0, 0, _genes, address(this));
        _approve(kittyId, saleAuction);

        saleAuction.createAuction(
            kittyId,
            _computeNextGen0Price(),
            0,
            GEN0_AUCTION_DURATION,
            address(this)
        );

        gen0CreatedCount++;
    }

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/marising/article/details/79458403

智能推荐

JWT(Json Web Token)实现无状态登录_无状态token登录-程序员宅基地

文章浏览阅读685次。1.1.什么是有状态?有状态服务,即服务端需要记录每次会话的客户端信息,从而识别客户端身份,根据用户身份进行请求的处理,典型的设计如tomcat中的session。例如登录:用户登录后,我们把登录者的信息保存在服务端session中,并且给用户一个cookie值,记录对应的session。然后下次请求,用户携带cookie值来,我们就能识别到对应session,从而找到用户的信息。缺点是什么?服务端保存大量数据,增加服务端压力 服务端保存用户状态,无法进行水平扩展 客户端请求依赖服务.._无状态token登录

SDUT OJ逆置正整数-程序员宅基地

文章浏览阅读293次。SDUT OnlineJudge#include<iostream>using namespace std;int main(){int a,b,c,d;cin>>a;b=a%10;c=a/10%10;d=a/100%10;int key[3];key[0]=b;key[1]=c;key[2]=d;for(int i = 0;i<3;i++){ if(key[i]!=0) { cout<<key[i.

年终奖盲区_年终奖盲区表-程序员宅基地

文章浏览阅读2.2k次。年终奖采用的平均每月的收入来评定缴税级数的,速算扣除数也按照月份计算出来,但是最终减去的也是一个月的速算扣除数。为什么这么做呢,这样的收的税更多啊,年终也是一个月的收入,凭什么减去12*速算扣除数了?这个霸道(不要脸)的说法,我们只能合理避免的这些跨级的区域了,那具体是那些区域呢?可以参考下面的表格:年终奖一列标红的一对便是盲区的上下线,发放年终奖的数额一定一定要避免这个区域,不然公司多花了钱..._年终奖盲区表

matlab 提取struct结构体中某个字段所有变量的值_matlab读取struct类型数据中的值-程序员宅基地

文章浏览阅读7.5k次,点赞5次,收藏19次。matlab结构体struct字段变量值提取_matlab读取struct类型数据中的值

Android fragment的用法_android reader fragment-程序员宅基地

文章浏览阅读4.8k次。1,什么情况下使用fragment通常用来作为一个activity的用户界面的一部分例如, 一个新闻应用可以在屏幕左侧使用一个fragment来展示一个文章的列表,然后在屏幕右侧使用另一个fragment来展示一篇文章 – 2个fragment并排显示在相同的一个activity中,并且每一个fragment拥有它自己的一套生命周期回调方法,并且处理它们自己的用户输_android reader fragment

FFT of waveIn audio signals-程序员宅基地

文章浏览阅读2.8k次。FFT of waveIn audio signalsBy Aqiruse An article on using the Fast Fourier Transform on audio signals. IntroductionThe Fast Fourier Transform (FFT) allows users to view the spectrum content of _fft of wavein audio signals

随便推点

Awesome Mac:收集的非常全面好用的Mac应用程序、软件以及工具_awesomemac-程序员宅基地

文章浏览阅读5.9k次。https://jaywcjlove.github.io/awesome-mac/ 这个仓库主要是收集非常好用的Mac应用程序、软件以及工具,主要面向开发者和设计师。有这个想法是因为我最近发了一篇较为火爆的涨粉儿微信公众号文章《工具武装的前端开发工程师》,于是建了这么一个仓库,持续更新作为补充,搜集更多好用的软件工具。请Star、Pull Request或者使劲搓它 issu_awesomemac

java前端技术---jquery基础详解_简介java中jquery技术-程序员宅基地

文章浏览阅读616次。一.jquery简介 jQuery是一个快速的,简洁的javaScript库,使用户能更方便地处理HTML documents、events、实现动画效果,并且方便地为网站提供AJAX交互 jQuery 的功能概括1、html 的元素选取2、html的元素操作3、html dom遍历和修改4、js特效和动画效果5、css操作6、html事件操作7、ajax_简介java中jquery技术

Ant Design Table换滚动条的样式_ant design ::-webkit-scrollbar-corner-程序员宅基地

文章浏览阅读1.6w次,点赞5次,收藏19次。我修改的是表格的固定列滚动而产生的滚动条引用Table的组件的css文件中加入下面的样式:.ant-table-body{ &amp;amp;::-webkit-scrollbar { height: 5px; } &amp;amp;::-webkit-scrollbar-thumb { border-radius: 5px; -webkit-box..._ant design ::-webkit-scrollbar-corner

javaWeb毕设分享 健身俱乐部会员管理系统【源码+论文】-程序员宅基地

文章浏览阅读269次。基于JSP的健身俱乐部会员管理系统项目分享:见文末!

论文开题报告怎么写?_开题报告研究难点-程序员宅基地

文章浏览阅读1.8k次,点赞2次,收藏15次。同学们,是不是又到了一年一度写开题报告的时候呀?是不是还在为不知道论文的开题报告怎么写而苦恼?Take it easy!我带着倾尽我所有开题报告写作经验总结出来的最强保姆级开题报告解说来啦,一定让你脱胎换骨,顺利拿下开题报告这个高塔,你确定还不赶快点赞收藏学起来吗?_开题报告研究难点

原生JS 与 VUE获取父级、子级、兄弟节点的方法 及一些DOM对象的获取_获取子节点的路径 vue-程序员宅基地

文章浏览阅读6k次,点赞4次,收藏17次。原生先获取对象var a = document.getElementById("dom");vue先添加ref <div class="" ref="divBox">获取对象let a = this.$refs.divBox获取父、子、兄弟节点方法var b = a.childNodes; 获取a的全部子节点 var c = a.parentNode; 获取a的父节点var d = a.nextSbiling; 获取a的下一个兄弟节点 var e = a.previ_获取子节点的路径 vue