Erc-1155

如何讓使用者將 ERC1155 代幣從我的合約地址轉移到他的地址?

  • November 18, 2021

我想要實現的目標:使用者應該能夠將 ERC1155 代幣從我的合約地址轉移到他的賬戶。

我嘗試了兩種方法:

  1. 部署 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, "");
   }
}
  1. 只為 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

您使用的地址(在這種情況下為呼叫者)未註冊為 anowner或 other approved,因此出現錯誤。

2 合約方法起作用的原因是第二個合約(testContract 是 ERC1155Holder)不像 ERC1155PresetMinterPauser 那樣繼承 AccessControl。因此,任何人都可以訪問 testContract。單一合約方法確實使用 AccessControl,因此 ERC1155PresetMinterPauser 合約中包含的任何功能都將受到限制。

引用自:https://ethereum.stackexchange.com/questions/98736