BoredApe Yachtclub的合约代码中数值运算在新版solc编译后运行出错

  • jinglin
  • 更新于 4天前
  • 阅读 139

BoredApeYachtclub的合约代码中数值运算在新版solc编译后运行出错我今天学习一下NFT的代码,里面有个数值运算的函数,用于生成每个NFTid对应的url.有个函数负责讲id转换成字符串.比如123变成'123'.silidity本身没有实现uint=>stri

BoredApe Yachtclub的合约代码中数值运算在新版solc编译后运行出错

我今天学习一下NFT 的代码,里面有个数值运算的函数,用于生成每个NFT id对应的url. 有个函数负责讲id 转换成字符串.比如 123 变成'123'. silidity 本身没有实现uint => string的转换,因此需要自己编写代码转换

pragma solidity >=0.6.0 <0.8.0;

/**
 * @dev String operations.
 */
library Strings {
    /**
     * @dev Converts a `uint256` to its ASCII `string` representation.
     */
    function toString(uint256 value) internal pure returns (string memory) {
        // Inspired by OraclizeAPI's implementation - MIT licence
        // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol

        if (value == 0) {
            return "0";
        }
        uint256 temp = value;
        uint256 digits;
        while (temp != 0) {
            digits++;
            temp /= 10;
        }
        bytes memory buffer = new bytes(digits);
        uint256 index = digits - 1;
        temp = value;
        while (temp != 0) {
            buffer[index--] = bytes1(uint8(48 + temp % 10));
            temp /= 10;
        }
        return string(buffer);
    }
}

我自己编写了几个由数字转换成字符串的solidity函数,想对比一下gas开销. 但是这个函数在0.8.17 的slidity编译出来, 在evm 里面执行的时候,这个toString 函数总是会失败.

今天调试了半天,最后相同,因为这里面的index 会出现变成 0 -- 场景,引发参数越界,因此计算错误. boredape 以前的版本,没有越界检查,就不会出错.

另外几种uint256 转字符串 的gas比较

下面的 toString() 来自无聊猿引用(oraclize/ethereum-api), toString2() 和toString3() 是我写的,开的内存更大,但是不先计算总共几个数字. 结果还是这个toString的gas开销更小.

//SPDX-License-Identifier:MIT
pragma solidity >0.8.0;
contract StringUtil{
    function getDigits(uint256 temp) public pure returns (uint256 digits){

        while (temp != 0) {
            digits++;
            temp /= 10;
        }
    }

    //gas 3731   6133
 function toString(uint256 value) public pure returns (string memory) {
        // Inspired by OraclizeAPI's implementation - MIT licence
        // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol

        if (value == 0) {
            return "0";
        }
        uint256 temp = value;
        uint256 digits;
        while (temp != 0) {
            digits++;
            temp /= 10;
        }
        bytes memory buffer = new bytes(digits);
        uint256 index = digits - 1;
        temp = value;
        while (temp != 0) {
            buffer[index] = bytes1(uint8(48 + temp % 10));
            if(index >0) index --;
            temp /= 10;
        }
        return string(buffer);
    }

   function sliceToString( bytes calldata arr , uint start ) pure external returns (string memory){
        return string(arr[start:]);
    }

    //gas 6730  8444
   function toString2(uint256  _num )  public view returns (string memory){
        if(_num == 0) return "0";
        bytes memory arr = new bytes (78); // utin256 max  1.15e77
        uint256 curr = _num;
        uint i ;
        for(  i = arr.length -1 ; i >= 0 && curr > 0 ; -- i){
            arr[i] = bytes1(uint8( curr % 10) + uint8(0x30));// digit + '0'
            curr = curr / 10;
        }
        return this.sliceToString(arr,i + 1);
    }

//4755(2digit)  7451(4 digit)
   function toString3(uint256  _num )  public pure returns (string memory){
        if(_num == 0) return "0";
        bytes memory arr = new bytes (78); // utin256 max  1.15e77
        uint256 curr = _num;
        uint i ;
        for(  i = arr.length -1 ; i >= 0 && curr > 0 ; -- i){
            arr[i] = bytes1(uint8( curr % 10) + uint8(0x30));// digit + '0'
            curr = curr / 10;
        }
        i += 1;
        bytes memory ret = new bytes(arr.length - i);
        for(uint j = 0 ; j < ret.length; ++ j){
            ret[j] = arr[j + i];
        }

        return string(ret);
    }
}

BoreApe的合约代码连接: <!--StartFragment-->

Bored Ape Yacht Club: BAYC Token | Address 0xbc4ca0eda7647a8ab7c2061c2e118a18a936f13d | Etherscan

<!--EndFragment-->

点赞 0
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
jinglin
jinglin
0xf54D...aDcd
http://github.com/nextuser