未标题-3
img

加密和NFT加密领域试图解决的一个大问题是中心化。区块链是其中一个重要部分。如果没有区块链,我们就不会有持有数百万美元的DAO或像CryptoPunks这样的项目。但是,大多数项目仍然存在一个问题:“如果IPFS下降怎么办?”

IPFS已经非常去中心化了,所以不用担心。但是一些收藏家可能更喜欢他们的代币的纯链上数据。元数据和艺术。值得庆幸的是,我们可以在 Solidity 中做到这一点。它也与 OpenSea 兼容。

如何在链上存储图像?

我们可以在链上存储任何东西,问题是如何存储它。我们很可能希望对我们的数据进行base64编码,并在其前缀/后缀上添加更多的信息,以便计算机知道它正在看什么。这就是OpenSea的工作原理,我已经进行了测试。

智能合约(或库)可用于将数据编码为链上 base64。我用过这个库。这是Loopring 团队的人做的。

现在,在针对NFT的智能合约中,我们希望能够将SVG数据编码为base64,并为其添加正确的信息前缀。

function svgToImageURI(string memory _source) public pure returns (string memory) {    string memory baseURL = "data:image/svg+xml;base64,";    string memory svgBase64Encoded = Base64.encode(bytes(string(abi.encodePacked(_source))));    return string(abi.encodePacked(baseURL, svgBase64Encoded));}

这个函数将在后面的safeMint函数的另一个函数中使用,但它本质上是将SVG ‘ string ‘编码为base64,并将其编码后返回给Solidity以供进一步处理。

SVG不是字符串,它们是图像,对吧?

不,它们可以被视为图像,但它们只是被写成代码,非常类似于HTML。

图像看起来如何?

因为我之前已经对一个潜在的客户端进行了测试,所以我还找到了一个简单的SVG文件来进行测试。它在普通SVG中看起来是这样的:

<svg width=’500′ height=’500′ viewBox=’0 0 285 350′ fill=’none’ xmlns=’http://www.w3.org/2000/svg’>
<path fill=’black’ d=’M150,0,L75,200,L225,200,Z’></path>
</svg>

base64编码它看起来是这样的:

data:image/svg+xml;base64,PHN2ZyB3aWR0aD0nNTAwJyBoZWlnaHQ9JzUwMCcgdmlld0JveD0nMCAwIDI4NSAzNTAnIGZpbGw9J25vbmUnIHhtbG5zPSdodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Zyc+PHBhdGggZmlsbD0nYmxhY2snIGQ9J00xNTAsMCxMNzUsMjAwLEwyMjUsMjAwLFonPjwvcGF0aD48L3N2Zz4=

我们可以复制这个已编码的字符串并将其粘贴到浏览器的地址栏中,以查看实际解析的SVG(至少在Chrome中是这样)。这就是我们正在做的,我们让它对浏览器具有可读性,除了我们需要让它对浏览器具有可访问性,而区块链这就是为什么我们用abi.encodePacked()对它进行进一步编码的原因。

注意字符串的第一个(粗体)。就是说data是一个imagefromsvg+xml编码的类型base64。

img

浏览器读取它没有任何问题

对 TokenURI 进行编码

TokenURI(通常)是指向带有特定属性的JSON文件的链接。但是,像图片一样,我们也可以对JSON文件进行base64编码,并使用正确的前缀使其在浏览器中可读。我们没有使用SVG前缀,而是使用data:application/json;base64来让浏览器知道它是一个base64编码的json文件。

我们也可以在Solidity中创建整个文件。我们把它编码,再编码,再编码。虽然这段代码看起来很有趣,但是很整洁,但它适用于OpenSea。

function formatTokenURI(string memory _imageURI, string memory _name, string memory _description, string memory _properties) public pure returns (string memory) {        return string(            abi.encodePacked(                "data:application/json;base64,",                Base64.encode(                    bytes(                        abi.encodePacked(                            '{"name":"', _name,                            '", "description": "', _description, '"',                            ', "attributes": ', _properties,                            ', "image":"', _imageURI, '"}'                        )                    )                )            )        );    }

作为参数,我使用tokenURI具有的不同属性,并使用encodepack作为将所有字符串粘贴在一起的方法(因为JSON可以用作字符串)。

注意:_properties值是一个可以是数组的字符串,比如“[1,2,3]”。

我们使用导入的库将最终的JSON编码为base64,并再次使用encodepack为其添加前缀,使其可用于浏览器,就像它是一个常规URL一样。

ContractURI?

除了给出每个代币信息的TokenURI之外,我们还有ContractURI。它提供了关于收藏品的整体信息,OpenSea也(在一定程度上)支持这一点。除了合约地址,我们不需要在OpenSea中手动添加任何东西。

我用下面的代码编码它。它类似于TokenURI,但选项更少。我只是将整个ContractURI JSON作为一个字符串传递。

function setContractURI(string memory contractURI_) public onlyOwner() {        _contractURI = string(abi.encodePacked(                "data:application/json;base64,",                Base64.encode(                    bytes(                        contractURI_                    )                )            ));    }

注意:OpenSea不会从区块链更新收集信息,所以在将其添加到OpenSea之前需设置一次!

铸造新代币

由于所有东西都在链上,所以铸造新的代币确实需要更多的信息。我们还需要设置所有信息(或稍后使用setTokenURI()函数进行设置),而不是简单地检查价格或创建一个新的代币。

function safeMint(string memory _source, string memory _name, string memory _description, string memory _properties) public onlyOwner() {    _safeMint(msg.sender, _tokenIdCounter.current());    string memory imageURI = svgToImageURI(_source);    _setTokenURI(_tokenIdCounter.current(), formatTokenURI(imageURI, _name, _description, _properties));    emit tokenChanged(_tokenIdCounter.current());    _tokenIdCounter.increment();}

因此,我们传递了更多的信息以及safeMint函数,如description、name、source (SVG)和properties,然后我们都使用前面介绍的函数对它们进行编码。

结论

尽管创建链上收藏品看起来很酷,但要小心,对于那些将制造代币的人来说,它是非常便宜的。我们必须向区块链提交更多的数据,这将消耗非常多的gas。

Source:https://medium.com/quick-programming/how-to-implement-fully-on-chain-nft-contracts-8c409acc98b7

关于

ChinaDeFi – ChinaDeFi.com 是一个研究驱动的DeFi创新组织,同时我们也是区块链开发团队。每天从全球超过500个优质信息源的近900篇内容中,寻找思考更具深度、梳理更为系统的内容,以最快的速度同步到中国市场提供决策辅助材料。

Layer 2道友 – 欢迎对Layer 2感兴趣的区块链技术爱好者、研究分析人与Gavin(微信: chinadefi)联系,共同探讨Layer 2带来的落地机遇。敬请关注我们的微信公众号 “去中心化金融社区”

640