• EIP-3664合约研究笔记03--装备属性随机生成算法


    在 claim()函数铸造主体NFT,会附带铸造生成了全套装备。本文就研究装备的生成算法。

    1 函数调用流程

    claim()
         _afterTokenMint()    
                   计算装备的tokenId
                   mintSubToken()
                              _mint(address(this), subId);
                              attach(subId, attr, 1, bytes(""), true);
                              synthesizedTokens[tokenId].push(SynthesizedToken(_msgSender(), subId));

    2 主体NFT和装备NFT的 tokenId计算方法

    主体NFT的最大发行数量是 _totalSupply = 8000, 范围是【1~8000】
    每个主体NFT拥有8个装备,所以装备的tokenId范围是 【8001~72000】
    计算公式: 
    id = _totalSupply + (tokenId - 1) * 8 + 1;

    3 装备的属性值如何随机化?

     其实这是一个非常令人困扰的事情, 在mintSubToken中,你找不到任何属性具体值的代码, 那么到底在什么时间点/代码中确定出装备的属性的呢?
    答案揭晓: 属性值并不是在铸造时设置的,而是在你访问合约读取tokenURI时根据装备的tokenId计算得到的。所以决定关系如下:
    主体tokenId  --> 装备的tokenId  ----> 装备的属性值
    【结论】主体的tokenId已经决定了一切,  😮 是不是让你大吃一惊,这种想法太惊人了,从来没有碰到过这种脑回路。
    先说明计算细节:
    示例: head, tokenId= 69411,  属性值:  "Ghoul Tear"  War Cap  of Rage
    "attributes":[     
            {
                "trait_type":"HEAD NAME",
                "value":"War Cap"
            },
            {
                "trait_type":"HEAD ID",
                "value":"69411"
            },
            {
                "trait_type":"HEAD suffix",
                "value":"of Rage"
            },
            {
                "trait_type":"HEAD namePrefixes",
                "value":"Ghoul"
            },
            {
                "trait_type":"HEAD nameSuffixes",
                "value":"Tear"
            },
    在pluckAttribute()中, 计算随机数:
    input = "HEAD" + "69411"
    rand = uint256(keccak256(abi.encodePacked(input)))
    output = sourceArray[rand % sourceArray.length]         // headArmor[7] = "War Cap"    rand%15=7
    继续计算后缀随机数:  greatness = rand % 21, 必须保证greatness>14才能有后缀。    rand%21>14
         suffix =  suffixes[rand % suffixes.length]     // suffixes[9] = " of Rage"       rand%16=9
    必须保证greatness>19才能有名称前缀+后缀。
       namePrefixes[] = " Ghoul "          // namePrefixes[28] = "Ghoul"    rand%69 = 28
       nameSuffixes[] = " Tear"               //nameSuffixes[13] = "Tear"        rand%18 = 13
    最终生成的data是
            {
                "trait_type":"HEAD NAME",
                "value":"War Cap"
            },
            {
                "trait_type":"HEAD ID",
                "value":"69411"
            },
            {
                "trait_type":"HEAD suffix",
                "value":"of Rage"
            },
            {
                "trait_type":"HEAD namePrefixes",
                "value":"Ghoul"
            },
            {
                "trait_type":"HEAD nameSuffixes",
                "value":"Tear"
            },

    4 获取NFT属性的组装过程

    一般的NFT元数据文件是从合约中得到URI,然后再从外部存储网络(IPFS)获得。 
    Legoot合约的元数据文件并非如此, 是根据属性参数自动拼装出来的字符串,完全内置化,无需外部存储。
    json格式:name:
                     description:
                     image:
                     attributes:
    调用流程:
    tokenURI( tokenId )
           getImageText(tokenId, 20)    
           getAttributes(tokenId)
           Base64.encode(...);

     

  • 相关阅读:
    翌加科技:教抖音小店商家采取措施避免售后争议
    【八股】synchronized
    网络安全常用靶场推荐
    猿创征文|Java 程序员的效率工具箱
    微信网页支付小白指南-域内浏览器支付 + 外部浏览器支付
    文件上传四次绕过
    【数据结构--八大排序】之希尔排序
    Shell(8)循环
    电力监控系统的组网方案与设计
    认识线程,初始并发
  • 原文地址:https://blog.csdn.net/u012084827/article/details/127118912