ERC721:转移调用者不是所有者也未获批准
ERC721: transfer caller is not owner nor approved
我有一个 nftToken 合约,可以将令牌铸造到 msg.sender,然后我在市场合约中有一个功能,可以将 nft 从所有者转移到市场合约。但是,我收到一条错误消息:ERC721:转移呼叫者不是所有者,也不是批准人。
这是我的 nftContract (nft) 函数片段:
function createToken(string memory tokenURI) public returns (uint) {
_tokenIds.increment();
uint256 newItemId = _tokenIds.current();
_mint(msg.sender, newItemId);
_setTokenURI(newItemId, tokenURI);
setApprovalForAll(contractAddress, true);
return newItemId;
}
这里是我的市场代码(stripeMarket Contract)函数片段:
function createItem(
address nftContract,
uint256 tokenId
) public payable{
address _owner = IERC721(nftContract).ownerOf(tokenId);
IERC721(nftContract).transferFrom(_owner, address(this),tokenId);
IERC721(nftContract).approve(address(this),tokenId);
}
我在这里尝试使用 web3 从前端调用它:
const getItems=async()=>{
await contracts.nft.methods.createToken("https://i.ytimg.com/vi/nYxGhQYi0s4/maxresdefault.jpg").send({from: accounts[0]});
const owners = await contracts.nft.methods.ownerOf(1).call({from:accounts[0]});
await contracts.stripeMarket.methods.createItem(contracts.nft._address,1).send({from: {owners}});
}
但是我遇到了错误。感谢任何帮助,谢谢!
当nftContract
执行setApprovalForAll(contractAddress, true)
时,它允许contractAddress
(市场合约)运行所有nftContract
的代币.
但是新铸造的代币属于 msg.sender
- 而不是 nftContract
。因此批准不适用于此令牌。
根据您的用例,您可以
将新代币铸造到 nftContract
(而不是 msg.sender
),以便允许市场合约操作它。或者直接铸造到市场合约。
// the owner is the `nftContract`
_mint(address(this), newItemId);
// the Market contract is allowed to operate the `nftContract`'s tokens
setApprovalForAll(contractAddress, true);
让 msg.sender
(令牌所有者)在执行 createItem()
.
之前在 nftContract
上执行 approve(marketAddress, tokenId)
这将允许市场合约批准操作 msg.sender
拥有的这个特定代币。 (假设它与 _owner
的地址相同 - 否则它将失败。)
我有一个 nftToken 合约,可以将令牌铸造到 msg.sender,然后我在市场合约中有一个功能,可以将 nft 从所有者转移到市场合约。但是,我收到一条错误消息:ERC721:转移呼叫者不是所有者,也不是批准人。
这是我的 nftContract (nft) 函数片段:
function createToken(string memory tokenURI) public returns (uint) {
_tokenIds.increment();
uint256 newItemId = _tokenIds.current();
_mint(msg.sender, newItemId);
_setTokenURI(newItemId, tokenURI);
setApprovalForAll(contractAddress, true);
return newItemId;
}
这里是我的市场代码(stripeMarket Contract)函数片段:
function createItem(
address nftContract,
uint256 tokenId
) public payable{
address _owner = IERC721(nftContract).ownerOf(tokenId);
IERC721(nftContract).transferFrom(_owner, address(this),tokenId);
IERC721(nftContract).approve(address(this),tokenId);
}
我在这里尝试使用 web3 从前端调用它:
const getItems=async()=>{
await contracts.nft.methods.createToken("https://i.ytimg.com/vi/nYxGhQYi0s4/maxresdefault.jpg").send({from: accounts[0]});
const owners = await contracts.nft.methods.ownerOf(1).call({from:accounts[0]});
await contracts.stripeMarket.methods.createItem(contracts.nft._address,1).send({from: {owners}});
}
但是我遇到了错误。感谢任何帮助,谢谢!
当nftContract
执行setApprovalForAll(contractAddress, true)
时,它允许contractAddress
(市场合约)运行所有nftContract
的代币.
但是新铸造的代币属于 msg.sender
- 而不是 nftContract
。因此批准不适用于此令牌。
根据您的用例,您可以
将新代币铸造到
nftContract
(而不是msg.sender
),以便允许市场合约操作它。或者直接铸造到市场合约。// the owner is the `nftContract` _mint(address(this), newItemId); // the Market contract is allowed to operate the `nftContract`'s tokens setApprovalForAll(contractAddress, true);
让
之前在msg.sender
(令牌所有者)在执行createItem()
.nftContract
上执行approve(marketAddress, tokenId)
这将允许市场合约批准操作
msg.sender
拥有的这个特定代币。 (假设它与_owner
的地址相同 - 否则它将失败。)