• 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(...);

     

  • 相关阅读:
    构建RAG应用-Datawhale笔记
    从源码全面解析 dubbo 服务端服务调用的来龙去脉
    企业园区办公室无线覆盖部署案例
    项目解决方案:海外门店视频汇聚方案(全球性的连锁店、国外连锁店视频接入和汇聚方案)
    C#重启 --- 语言基础
    抖音的兴趣电商已经碰到流量天花板?
    my_print_defaults 及perror
    ES京东搜索
    项目管理工具dhtmlxGantt入门教程(二):如何初始化dhtmlxGantt(下)
    Java基础---第八篇
  • 原文地址:https://blog.csdn.net/u012084827/article/details/127118912