Erc-1155
如何讓使用者將 ERC1155 代幣從我的合約地址轉移到他的地址?
我想要實現的目標:使用者應該能夠將 ERC1155 代幣從我的合約地址轉移到他的賬戶。
我嘗試了兩種方法:
- 部署 ERC1155 合約,然後將其地址傳遞給處理轉賬的第二個合約的建構子。
這行得通。使用者可以毫無錯誤地呼叫 buyItems()。
pragma solidity ^0.8.0; import '@openzeppelin/contracts/token/ERC1155/IERC1155.sol'; import '@openzeppelin/contracts/token/ERC1155/utils/ERC1155Holder.sol'; import '@openzeppelin/contracts/token/ERC1155/presets/ERC1155PresetMinterPauser.sol'; contract ERC1155Preset is ERC1155PresetMinterPauser { constructor() ERC1155PresetMinterPauser("https://token-cdn-domain/{id}.json") {} } contract testContract is ERC1155Holder { IERC1155 private _IERC1155; constructor(IERC1155 ERC1155Address) { _IERC1155 = ERC1155Address; } function buyItems(uint256 _itemId, uint256 _amount) external { require(_IERC1155.balanceOf(address(this), _itemId) >= _amount); _IERC1155.safeTransferFrom(address(this), msg.sender, _itemId, _amount, ""); } }
- 只為 ERC1155 和轉賬部署一份合約。
這行不通。當使用者呼叫 buyItems() 時,我收到此錯誤:執行恢復:ERC1155:呼叫者不是所有者也不是批准
pragma solidity ^0.8.0; import '@openzeppelin/contracts/token/ERC1155/utils/ERC1155Holder.sol'; import '@openzeppelin/contracts/token/ERC1155/presets/ERC1155PresetMinterPauser.sol'; contract testContract2 is ERC1155PresetMinterPauser, ERC1155Holder { constructor() ERC1155PresetMinterPauser("https://token-cdn-domain/{id}.json") {} function supportsInterface(bytes4 interfaceId) public view virtual override(ERC1155PresetMinterPauser, ERC1155Receiver) returns (bool) { return interfaceId == type(IERC1155).interfaceId || interfaceId == type(IERC1155Receiver).interfaceId || super.supportsInterface(interfaceId); } function buyItems(uint256 _itemId, uint256 _amount) external { require(balanceOf(address(this), _itemId) >= _amount); safeTransferFrom(address(this), msg.sender, _itemId, _amount, ""); } }
我的問題:為什麼第一種方法有效,為什麼第二種方法無效?
您可以查看有關 openzepplin 的文件嗎?我在這裡連結了它,特別是與ERC1155PresetMinterPauser相關。這裡有一個我沒有提到的依賴項,即Access Control。
您使用的地址(在這種情況下為呼叫者)未註冊為 an
owner
或 otherapproved
,因此出現錯誤。
2 合約方法起作用的原因是第二個合約(testContract 是 ERC1155Holder)不像 ERC1155PresetMinterPauser 那樣繼承 AccessControl。因此,任何人都可以訪問 testContract。單一合約方法確實使用 AccessControl,因此 ERC1155PresetMinterPauser 合約中包含的任何功能都將受到限制。