如何将NFT转移到另一个智能合同中?
我正在尝试设置托管合同,该托管合同将押金作为NFT纳入合同。我正在努力将NFT存入合同中。
我首先要有一个简单的NFT,该NFT被用ID铸造到地址。
contract MyEpicNFT is ERC721URIStorage {
// Magic given to us by OpenZeppelin to help us keep track of tokenIds.
using Counters for Counters.Counter;
Counters.Counter private _tokenIds;
// We need to pass the name of our NFTs token and its symbol.
constructor() ERC721 ("SquareNFT", "SQUARE") {
console.log("This is my NFT contract. Woah!");
console.log(address(this));
}
// A function our user will hit to get their NFT.
function makeNft() public {
uint256 newItemId = _tokenIds.current();
_safeMint(msg.sender, newItemId);
_setTokenURI(newItemId, "https://jsonkeeper.com/b/1LHH");
console.log("An NFT w/ ID %s has been minted to %s", newItemId, msg.sender);
_tokenIds.increment();
}
}
在这种情况下,w/ id 0的NFT已被铸造给合同的味精。:0xDD870FA1B7C4700F2BD7F2BD7F444238821C26F7392148
我知道现在我需要允许批准托管合同来“支出”此tokken。为了在myepicnft合同上执行此操作,我将myepicnft的合同地址和铸造的NFT的ID称为批准功能。
console.log:
This is my NFT contract. Woah!
0x5fc7Dc95b4Bb48dbC9894fCaE417482cb8A6A45a
就我而言,我将(0x5FC7DC95B4BB48DBC9894FCAE417482CB8A6A45A,0)称为批准。现在,我需要在NFTESCROW合同中要做的是存放NFT。
我使用的批准功能是来自ERC721 lib,
approve(address to, uint256 tokenId)
有一个reademnft函数获取NFT地址 - 在我们的情况下0x5fc7dc7dc95b4bb48db48dbc9894fcae417482cb8a6a45a和0
The transaction has been reverted to the initial state.
Reason provided by the contract: "ERC721: transfer caller is not owner nor approved".
Debug the transaction to get more information.
contract NftEscrow is IERC721Receiver {
enum ProjectState {newEscrow, nftDeposited, cancelNFT, ethDeposited, canceledBeforeDelivery, deliveryInitiated, delivered}
address payable public sellerAddress;
address payable public buyerAddress;
address public nftAddress;
uint256 tokenID;
bool buyerCancel = false;
bool sellerCancel = false;
ProjectState public projectState;
receive() external payable {
}
constructor(){
sellerAddress = payable(msg.sender);
projectState = ProjectState.newEscrow;
}
function onERC721Received( address , address , uint256 , bytes calldata ) public pure override returns (bytes4) {
return this.onERC721Received.selector;
}
function depositNFT(address _NFTAddress, uint256 _TokenID) public onlySeller {
nftAddress = _NFTAddress;
tokenID = _TokenID;
ERC721(nftAddress).safeTransferFrom(msg.sender, address(this), tokenID);
projectState = ProjectState.nftDeposited;
}
function depositEth() public payable {
buyerAddress = payable(msg.sender);
projectState = ProjectState.ethDeposited;
}
function confirmDelivery()public payable {
ERC721(nftAddress).safeTransferFrom(address(this), buyerAddress, tokenID);
sellerAddress.transfer(address(this).balance);
}
modifier onlySeller() {
require(msg.sender == sellerAddress);
_;
}
}
。在这一天。为什么我不能将NFT存入智能合同?
I am trying to setup an escrow contract which takes a deposit as a NFT into the contract. I am struggling to deposit the NFT into the contract.
I start by having a simple NFT that gets minted to the address with an id.
contract MyEpicNFT is ERC721URIStorage {
// Magic given to us by OpenZeppelin to help us keep track of tokenIds.
using Counters for Counters.Counter;
Counters.Counter private _tokenIds;
// We need to pass the name of our NFTs token and its symbol.
constructor() ERC721 ("SquareNFT", "SQUARE") {
console.log("This is my NFT contract. Woah!");
console.log(address(this));
}
// A function our user will hit to get their NFT.
function makeNft() public {
uint256 newItemId = _tokenIds.current();
_safeMint(msg.sender, newItemId);
_setTokenURI(newItemId, "https://jsonkeeper.com/b/1LHH");
console.log("An NFT w/ ID %s has been minted to %s", newItemId, msg.sender);
_tokenIds.increment();
}
}
An NFT w/ ID 0 has been minted to the msg.sender of the contract in this case: 0xdD870fA1b7C4700F2BD7f44238821C26f7392148
I know now I need to approve the Escrow contract to be allowed to "spend" this token. To do this on MyEpicNft contract I call the approve function with the contract address of the MyEpicNft and the Id of the NFT that was minted.
console.log:
This is my NFT contract. Woah!
0x5fc7Dc95b4Bb48dbC9894fCaE417482cb8A6A45a
In my case I call the approve with (0x5fc7Dc95b4Bb48dbC9894fCaE417482cb8A6A45a, 0) - this seems to work. Now what I need to do in the NftEscrow contract is to deposit the NFT.
The approve function i am using is from the ERC721 lib
approve(address to, uint256 tokenId)
There is a depositNFT function which takes the NFT address - in our case 0x5fc7Dc95b4Bb48dbC9894fCaE417482cb8A6A45a and 0. But when i do this i get the error message:
The transaction has been reverted to the initial state.
Reason provided by the contract: "ERC721: transfer caller is not owner nor approved".
Debug the transaction to get more information.
contract NftEscrow is IERC721Receiver {
enum ProjectState {newEscrow, nftDeposited, cancelNFT, ethDeposited, canceledBeforeDelivery, deliveryInitiated, delivered}
address payable public sellerAddress;
address payable public buyerAddress;
address public nftAddress;
uint256 tokenID;
bool buyerCancel = false;
bool sellerCancel = false;
ProjectState public projectState;
receive() external payable {
}
constructor(){
sellerAddress = payable(msg.sender);
projectState = ProjectState.newEscrow;
}
function onERC721Received( address , address , uint256 , bytes calldata ) public pure override returns (bytes4) {
return this.onERC721Received.selector;
}
function depositNFT(address _NFTAddress, uint256 _TokenID) public onlySeller {
nftAddress = _NFTAddress;
tokenID = _TokenID;
ERC721(nftAddress).safeTransferFrom(msg.sender, address(this), tokenID);
projectState = ProjectState.nftDeposited;
}
function depositEth() public payable {
buyerAddress = payable(msg.sender);
projectState = ProjectState.ethDeposited;
}
function confirmDelivery()public payable {
ERC721(nftAddress).safeTransferFrom(address(this), buyerAddress, tokenID);
sellerAddress.transfer(address(this).balance);
}
modifier onlySeller() {
require(msg.sender == sellerAddress);
_;
}
}
Not sure what I am doing wrong and been stuck on this for a day. Why can't i deposit the NFT to the smart contract?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您的托管合同将使用
“ ERC721:转让呼叫者为所有者也不批准”
如果以下各项为真:msg.sender
是合同的所有者。 sg.sender 已批准所有者
msg.sender
在您的情况下,所有者批准了该令牌,我们选择了第三种选项。
我们需要检查的是
当托管合同
以NFT合同的角度拨打NFT合同时,
msg.sender
是托管合同。因此,您的批准过程为99%。请分享有关此信息的更多信息。编辑:
我们正在尝试使以下条件正确,其中
spender
是托管合同的地址,如果签名确实是返回合同地址,请尝试在您的NFT合同中添加以下功能:
Your escrow contract will revert with
"ERC721: transfer caller is not owner nor approved"
if none of the following are true:msg.sender
is the owner of contractmsg.sender
is approved for all for the ownermsg.sender
is approved for that token by the ownerIn your situation, we are opting for the 3rd option.
What we need to check is
When the escrow contract calls the NFT contract
in NFT contract's point of view, the
msg.sender
is the escrow contract. So the problem is 99% with your approval process. Please share more information about that.EDIT:
We are trying to get the following condition true, where the
spender
is the escrow contract's adressIf getApproved is really returns the contract address, try adding following function to your nft contract: