好,这是我关于栈交换的第一个问题,我是一个新手。
我正在尝试创建一个ERC 721合约,该合约发出一个包含生成的nft的地址和(散列)令牌id的url。我注意到每次调用mint函数时发出的url都会变大。
我把问题缩小到Base64.encode(),但我卡住了。我搜索了,但似乎找不到答案,可能是因为我不知道要搜索什么。
看下面的合同。它发出一个自定义URL,其中包含通过Base64.encode()创建的数据字段。我希望每次发出的URL长度相同,因为在调用之间会清除内存。
但是…每次调用Mint函数时,数据字段包含以前调用的数据。
我第一次调用Mint()发出的结果如下:someURL.com? mhg5zdgzzte0mdmzmdc10ge4zmzkmddmogjknznlodzlynhoge1njky">
第二次调用Mint()发出的时间更长:"someURL.com MHg5ZDgzZTE0MDMzMDc1OGE4ZmZkMDdmOGJkNzNlODZlYmNhOGE1Njky ? MHg5ZDgzZTE0MDMzMDc1OGE4ZmZkMDdmOGJkNzNlODZlYmNhOGE1Njky"
每当我调用Mint()时,它就会继续运行。记忆似乎被保留了。为什么?我遗漏了什么?
非常感谢任何帮助或指导!
pragma solidity ^0.8.4;
import "@openzeppelin/contracts/utils/Strings.sol";
import "@openzeppelin/contracts/utils/Base64.sol";
contract URLMemory {
using Strings for uint256;
string customURL = "someURL.com";
event CustomURLIssued(string customURL);
function issueCustomURL() public returns (string memory){
customURL = string(
abi.encodePacked(
customURL,
"?",
Base64.encode( abi.encodePacked( Strings.toHexString(address(this)) )
)
));
return customURL;
}
function Mint() public {
emit CustomURLIssued(issueCustomURL());
}
}
customURL = string(
abi.encodePacked(
customURL,
"?",
Base64.encode(abi.encodePacked(Strings.toHexString(address(this))))
)
);
这段代码给customURL
赋了一个新值,新值由以下部分组成:
customURL
的上一个值?
string literal- 和编码地址
因此,每次执行此代码片段时,它都会有效地为customURL
添加新值。
省略Base64编码的简化示例。
customURL = string(
abi.encodePacked(
customURL,
"?"
)
);
customURL
初始值=A
第一次运行后,它变成了A?
。第二次运行A??
。第三次运行A???
。等等。
如果你想保留someURL.com
前缀,只添加?
和每个令牌的编码值,你可以只返回新生成的值,而不将其分配回customURL
。
function issueCustomURL() public view returns (string memory){
return string(
abi.encodePacked(
customURL,
"?",
Base64.encode( abi.encodePacked( Strings.toHexString(address(this)) )
)
));
}
注意:如果您升级到Solidity 0.8.12或更高版本,您可以使用本机函数string.concat()代替与abi.encodePacked()
连接字符串。
string.concat(customURL, "?", encoded)