Why my base64 encode is out of gas. How can fix this

pragma solidity ^0.8.2;
import "./Base64.sol";

contract Test{
    function buildMetaData(uint256 _tokenId) public view returns (string memory) {
        string memory imageURI = buildImage();
        return string(
                abi.encodePacked(
                    "data:application/json;base64,",
                    Base64.encode(
                        bytes(
                            abi.encodePacked(
                                '{"name":"',
                                "SVG NFT", // You can add whatever name here
                                '", "description":"An NFT based on SVG!", "attributes":"", "image":"',imageURI,'"}'
                            )
                        )
                    )
                )
            );
    }
    function buildImage() view public returns (string memory) {
        // example:
        string memory background = '#FFFFFF';
        string memory baseURL = "data:image/svg+xml;base64,";
        string memory svgBase64Encoded = Base64.encode(bytes(string(abi.encodePacked(
            '<svg width="320" height="320" viewBox="0 0 320 320" xmlns="http://www.w3.org/2000/svg" shape-rendering="crispEdges">',
                '<rect width="100%" height="100%" fill="#', background, '" />',
                createRect(),
                '</svg>'
            ))));
        return string(abi.encodePacked(baseURL,svgBase64Encoded));
    }
    function createRect() public view returns (string memory){

        string[33] memory lookup = [
            '0', '10', '20', '30', '40', '50', '60', '70', 
            '80', '90', '100', '110', '120', '130', '140', '150',  
            '160', '170', '180', '190', '200', '210', '220', '230', 
            '240', '250', '260', '270', '280', '290', '300', '310',
            '320' 
        ];

        uint256 cursor;
        string[16] memory buffer;
        string memory part;
        for (uint256 i = 0; i < 250; i += 1) {
            buffer[cursor] = lookup[1];          // width
            buffer[cursor + 1] = lookup[1];         // x
            buffer[cursor + 2] = lookup[1];          // y
            buffer[cursor + 3] = lookup[1];  
            cursor+=4;
            if (cursor >= 16) {
								// Write the rectangles from the buffer to a string
								// and concatenate with the existing part string. 
                part = string(abi.encodePacked(part, _getChunk(cursor, buffer)));
                cursor = 0;
            }
        }
        return part;
    }

    function _getChunk(uint256 cursor, string[16] memory buffer) private pure returns (string memory) {
        string memory chunk;
        for (uint256 i = 0; i < cursor; i += 4) {
            chunk = string(
                abi.encodePacked(
                    chunk,
                    '<rect width="', buffer[i], '" height="10" x="', buffer[i + 1], '" y="', buffer[i + 2], '" fill="#', buffer[i + 3], '" />'
                )
            );
        }
        return chunk;
    }
}

When i create many react for example 250 reacts my function base64 can not encode and return out of gas. But when i decrease to 10 reacts its ok

looks like you’re contract is so heavy with metadata, best not too store or process too many data in smart contract :raised_hands: it tends to fail that way

i know heavy but i need to render many react to draw svg.


This github they generate alots rect too but why they can encode
https://nouns.wtf/

I can’t see their smart contract in their repo but the usual practice would be to render the image offchain and upload it to IPFS which then the tokenURI can be stored in the smart contract, but not the svg directly

No generate nft offchain by IPFS is defferent. My smart contract is generate onchain so we create a svg encode instead of save by ipfs

I never really heard that achieved before also it’s not something that will be compliant to any ERC721 or ERC1155 standard I think coz they both utilize tokenURI. This is also usually what’s used by marketplace like OpenSea and Rarible. Plus, gas fees on this if you encode them will be quite insane I’m afraid if that is possible

You can read here they generate onchain nft too

1 Like

hmmm looks interesting :thinking: just know this thanks for the resources I’ll take a look

Yah same with offchain but they encode svg instead of IPFS link. Browser can read svg and draw