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

智能推荐

艾美捷Epigentek DNA样品的超声能量处理方案-程序员宅基地

文章浏览阅读15次。空化气泡的大小和相应的空化能量可以通过调整完全标度的振幅水平来操纵和数字控制。通过强调超声技术中的更高通量处理和防止样品污染,Epigentek EpiSonic超声仪可以轻松集成到现有的实验室工作流程中,并且特别适合与表观遗传学和下一代应用的兼容性。Epigentek的EpiSonic已成为一种有效的剪切设备,用于在染色质免疫沉淀技术中制备染色质样品,以及用于下一代测序平台的DNA文库制备。该装置的经济性及其多重样品的能力使其成为每个实验室拥有的经济高效的工具,而不仅仅是核心设施。

11、合宙Air模块Luat开发:通过http协议获取天气信息_合宙获取天气-程序员宅基地

文章浏览阅读4.2k次,点赞3次,收藏14次。目录点击这里查看所有博文  本系列博客,理论上适用于合宙的Air202、Air268、Air720x、Air720S以及最近发布的Air720U(我还没拿到样机,应该也能支持)。  先不管支不支持,如果你用的是合宙的模块,那都不妨一试,也许会有意外收获。  我使用的是Air720SL模块,如果在其他模块上不能用,那就是底层core固件暂时还没有支持,这里的代码是没有问题的。例程仅供参考!..._合宙获取天气

EasyMesh和802.11s对比-程序员宅基地

文章浏览阅读7.7k次,点赞2次,收藏41次。1 关于meshMesh的意思是网状物,以前读书的时候,在自动化领域有传感器自组网,zigbee、蓝牙等无线方式实现各个网络节点消息通信,通过各种算法,保证整个网络中所有节点信息能经过多跳最终传递到目的地,用于数据采集。十多年过去了,在无线路由器领域又把这个mesh概念翻炒了一下,各大品牌都推出了mesh路由器,大多数是3个为一组,实现在面积较大的住宅里,增强wifi覆盖范围,智能在多热点之间切换,提升上网体验。因为节点基本上在3个以内,所以mesh的算法不必太复杂,组网形式比较简单。各厂家都自定义了组_802.11s

线程的几种状态_线程状态-程序员宅基地

文章浏览阅读5.2k次,点赞8次,收藏21次。线程的几种状态_线程状态

stack的常见用法详解_stack函数用法-程序员宅基地

文章浏览阅读4.2w次,点赞124次,收藏688次。stack翻译为栈,是STL中实现的一个后进先出的容器。要使用 stack,应先添加头文件include<stack>,并在头文件下面加上“ using namespacestd;"1. stack的定义其定义的写法和其他STL容器相同, typename可以任意基本数据类型或容器:stack<typename> name;2. stack容器内元素的访问..._stack函数用法

2018.11.16javascript课上随笔(DOM)-程序员宅基地

文章浏览阅读71次。<li> <a href = "“#”>-</a></li><li>子节点:文本节点(回车),元素节点,文本节点。不同节点树:  节点(各种类型节点)childNodes:返回子节点的所有子节点的集合,包含任何类型、元素节点(元素类型节点):child。node.getAttribute(at...

随便推点

layui.extend的一点知识 第三方模块base 路径_layui extend-程序员宅基地

文章浏览阅读3.4k次。//config的设置是全局的layui.config({ base: '/res/js/' //假设这是你存放拓展模块的根目录}).extend({ //设定模块别名 mymod: 'mymod' //如果 mymod.js 是在根目录,也可以不用设定别名 ,mod1: 'admin/mod1' //相对于上述 base 目录的子目录}); //你也可以忽略 base 设定的根目录,直接在 extend 指定路径(主要:该功能为 layui 2.2.0 新增)layui.exten_layui extend

5G云计算:5G网络的分层思想_5g分层结构-程序员宅基地

文章浏览阅读3.2k次,点赞6次,收藏13次。分层思想分层思想分层思想-1分层思想-2分层思想-2OSI七层参考模型物理层和数据链路层物理层数据链路层网络层传输层会话层表示层应用层OSI七层模型的分层结构TCP/IP协议族的组成数据封装过程数据解封装过程PDU设备与层的对应关系各层通信分层思想分层思想-1在现实生活种,我们在喝牛奶时,未必了解他的生产过程,我们所接触的或许只是从超时购买牛奶。分层思想-2平时我们在网络时也未必知道数据的传输过程我们的所考虑的就是可以传就可以,不用管他时怎么传输的分层思想-2将复杂的流程分解为几个功能_5g分层结构

基于二值化图像转GCode的单向扫描实现-程序员宅基地

文章浏览阅读191次。在激光雕刻中,单向扫描(Unidirectional Scanning)是一种雕刻技术,其中激光头只在一个方向上移动,而不是来回移动。这种移动方式主要应用于通过激光逐行扫描图像表面的过程。具体而言,单向扫描的过程通常包括以下步骤:横向移动(X轴): 激光头沿X轴方向移动到图像的一侧。纵向移动(Y轴): 激光头沿Y轴方向开始逐行移动,刻蚀图像表面。这一过程是单向的,即在每一行上激光头只在一个方向上移动。返回横向移动: 一旦一行完成,激光头返回到图像的一侧,准备进行下一行的刻蚀。

算法随笔:强连通分量-程序员宅基地

文章浏览阅读577次。强连通:在有向图G中,如果两个点u和v是互相可达的,即从u出发可以到达v,从v出发也可以到达u,则成u和v是强连通的。强连通分量:如果一个有向图G不是强连通图,那么可以把它分成躲个子图,其中每个子图的内部是强连通的,而且这些子图已经扩展到最大,不能与子图外的任一点强连通,成这样的一个“极大连通”子图是G的一个强连通分量(SCC)。强连通分量的一些性质:(1)一个点必须有出度和入度,才会与其他点强连通。(2)把一个SCC从图中挖掉,不影响其他点的强连通性。_强连通分量

Django(2)|templates模板+静态资源目录static_django templates-程序员宅基地

文章浏览阅读3.9k次,点赞5次,收藏18次。在做web开发,要给用户提供一个页面,页面包括静态页面+数据,两者结合起来就是完整的可视化的页面,django的模板系统支持这种功能,首先需要写一个静态页面,然后通过python的模板语法将数据渲染上去。1.创建一个templates目录2.配置。_django templates

linux下的GPU测试软件,Ubuntu等Linux系统显卡性能测试软件 Unigine 3D-程序员宅基地

文章浏览阅读1.7k次。Ubuntu等Linux系统显卡性能测试软件 Unigine 3DUbuntu Intel显卡驱动安装,请参考:ATI和NVIDIA显卡请在软件和更新中的附加驱动中安装。 这里推荐: 运行后,F9就可评分,已测试显卡有K2000 2GB 900+分,GT330m 1GB 340+ 分,GT620 1GB 340+ 分,四代i5核显340+ 分,还有写博客的小盒子100+ 分。relaybot@re...

推荐文章

热门文章

相关标签