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

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值