safeTransferFrom(address(this), msg.sender, ProjectB, 1, "0x0");
I get this error: execution reverted: ERC1155: caller is not owner nor approved.
safeTransferFrom(address(this), msg.sender, ProjectB, 1, "0x0");
I get this error: execution reverted: ERC1155: caller is not owner nor approved.
You should add a custom function users can call, and internally use _safeTransferFrom
.
Hi @frangio , thanks for replying.
I am not understanding, can you please share any example code?
I am minting tokens in the constructor to address(this) and when the user call the buy function then transferring this token to the caller’s address.
I want this process like, in ERC20 we use to transfer().
with current functionality, I have to approve users every time.
Is this possible, that our contract itself can send tokens to msg.sender based on any condition?
//user will buy share for ProjectA
//user will send 100 API tokens to this address to by RS-NFT for ProjectA
function buyRSNFTForProjectA() external {
//checking balance Of AliAPIToken in user's account
require(balanceOf(msg.sender,AliAPIToken) != 0, "Please buy API tokens first to buy RS-NFT");
//transferring tokens from user aaccount to this contract address
safeTransferFrom(msg.sender,address(this), AliAPIToken,100,"");
//transfer RS-NFT to user
safeTransferFrom(address(this), msg.sender, ProjectA, 1, "");
}```
You’re using safeTransformFrom
which is the public function. This function will require that msg.sender
has permission to transfer these tokens, so the transfer you want to do will fail.
Instead, if you use the internal _safeTransferFrom
function you can transfer without checking that msg.sender has permissions. You should use this one.
@frangio thankyou so much.
I am not able to make this contract ERC1155 holder, it is already implementing IERC1155Receiver.
Not working with this.(ERC1155: transfer to non ERC1155Receiver implementer)
When I import ERC1155 holder, it gives me error.
execution reverted: ERC1155: transfer to non ERC1155Receiver implementer
Trx hash
Is there any way to make this contract holder?
I am using ^0.8, _safeTransferFrom is not available in older versions.
What error do you see?
TypeError: Derived contract must override function “supportsInterface”. Two or more base classes define function with same name and parameter types. → Task9.sol:10:1: | 10 | contract ALIAPIToken is ERC1155,ERC1155Holder,Ownable{ | ^ (Relevant source part starts here and spans across multiple lines). Note: Definition in “ERC1155”: → https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC1155/ERC1155.sol:41:5: | 41 | function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) { | ^ (Relevant source part starts here and spans across multiple lines). Note: Definition in “ERC1155Receiver”: → https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC1155/utils/ERC1155Receiver.sol:15:5: | 15 | function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) { | ^ (Relevant source part starts here and spans across multiple lines).
@frangio this is my code
// contracts/GameItems.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.0;
import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC1155/ERC1155.sol";
import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/IERC20.sol";
import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/access/Ownable.sol";
import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC1155/utils/ERC1155Holder.sol";
contract ALIAPIToken is ERC1155,ERC1155Holder,Ownable{
address private _token = 0xc7AD46e0b8a400Bb3C915120d284AafbA8fc4735; //dai address
IERC20 private token;
address panacloud;
address dev;
//tokens
uint256 public constant AliAPIToken =0;
uint256 public constant ProjectA = 1;
uint256 public constant ProjectB = 2;
//percentages
uint256 public panaCloudPercentage = 5;
uint256 public investorPercentage = 10;
// minting two NFT's
constructor(address _panacloud,address _dev) ERC1155("") {
panacloud = _panacloud;
dev = _dev;
token = IERC20(_token);
//0xc7AD46e0b8a400Bb3C915120d284AafbA8fc4735
_mint(address(this),ProjectA,1,"0x0"); //NFT
_mint(address(this),ProjectB,2,"0x0"); //NFT
setApprovalForAll(address(this), true);
}
//to check DAI token alallowance(for UI)
function checkDaiAllowance() external view returns(uint daiAllowed){
uint bal = token.allowance(msg.sender,address(this));
return bal;
}
//when this contract will receive any revenue eg.g dai token, it will percentages to panacloud, developer and Project Share holder.
// he needs to call this ffunction.
//we can automate this function by calling it in buyAPIToken function.
//for now, as per my understanding I am doing this way
function onDaiReceive(uint _daiAmount) external {
// checing dai allowance is not equal to zero
require(token.allowance(msg.sender,address(this)) != 0,"zero allowance, pleae approve DAI first to be used by this contract");
address from = msg.sender;
//transferring tokens from caller to this contract address
require(token.transferFrom(from, address(this), _daiAmount)== true,"error");
//transferring tokens to API developer by getting percentage
uint investorP = (_daiAmount*investorPercentage)/100;
token.transfer(dev, investorP);
//transferring token percentage to panacloud
uint panacloudP = (_daiAmount*panaCloudPercentage)/100;
token.transfer(panacloud, panacloudP);
//transfer tokens to API developer
require(token.transfer(owner(), token.balanceOf(address(this))),"Fialed");
}
//user can buy AliAPIToken that is currency to to buy RS-NFT for differet projects.
// he needs to set allowance first
// _amount wil be amout of DAI tokens
function buyAPIToken(uint _amount) external{
//checking allowance
require(token.allowance(msg.sender,address(this)) != 0,"zero allowance, pleae approve DAI first to be used by this contract");
address from = msg.sender;
//transferring DAI tokens from user to this address.
// it is different than onDaiReceive
require(token.transferFrom(from, address(this), _amount)== true,"error");
//minting AliAPITokens to user
_mint(msg.sender, AliAPIToken, _amount * 100, "");
}
//user will buy share for ProjectA
//user will send 100 API tokens to this address to by RS-NFT for ProjectA
function buyRSNFTForProjectA() external {
//checking balance Of AliAPIToken in user's account
require(balanceOf(msg.sender,AliAPIToken) != 0, "Please buy API tokens first to buy RS-NFT");
//transferring tokens from user aaccount to this contract address
safeTransferFrom(msg.sender,address(this), AliAPIToken,100,"");
//transfer RS-NFT to user
_safeTransferFrom(address(this), msg.sender, ProjectA, 1, "");
}
//user will buy share for ProjectB
//user will send 500 API tokens to this address to by RS-NFT for ProjectA
function buyRSNFTForProjectB() external {
//checking balance Of AliAPIToken in user's account
require(balanceOf(msg.sender,AliAPIToken) != 0, "Please buy API tokens first to buy RS-NFT");
//transferring tokens from user aaccount to this contract address
safeTransferFrom(msg.sender,address(this), AliAPIToken,500,"");
//transfer RS-NFT to user
_safeTransferFrom(address(this), msg.sender, ProjectB, 1, "0x0");
}
}
The error message says "Derived contract must override function supportsInterface".
You need to define this function and call super.supportsInterface
in it.
function supportsInterface(bytes4 interfaceId) public view virtual override(ERC1155, ERC1155Receiver) returns (bool) {
return super.supportsInterface(interfaceId);
}