Truffle
錯誤:返回錯誤:處理事務時出現 VM 異常:還原(moralis 教程)
你們好嗎?我正在看這個影片教程,https://www.youtube.com/watch?v=y519kGkAQd8&list=RDCMUCgWS9Q3P5AxCWyQLT2kQhBw&t=235s 當我執行這個命令時
truffle migrate --network development
我收到了這個錯誤:
Error: Returned error: VM Exception while processing transaction: revert
這裡有人可以幫助我嗎?程式碼
令牌.sol
pragma solidity 0.8.10; import "../node_modules/@openzeppelin/contracts/token/ERC721/ERC721.sol"; import "../node_modules/@openzeppelin/contracts/access/Ownable.sol"; contract Token is ERC721, Ownable { struct Pet { uint8 damage; //0-255 uint8 magic; uint256 lastMeal; uint256 endurance; // 24 hours } uint256 nextId = 0; mapping(uint256 => Pet) private _tokenDetails; constructor(string memory name, string memory symbol) ERC721(name, symbol) {} function getTokenDetails(uint256 tokenId) public view returns (Pet memory) { return _tokenDetails[tokenId]; } function mint(uint8 damage, uint8 magic, uint256 endurance) public onlyOwner { _safeMint(msg.sender, nextId); _tokenDetails[nextId] = Pet(damage, magic, block.timestamp, endurance); nextId++; } function feed(uint256 tokenId) public { Pet storage pet = _tokenDetails[nextId]; require(pet.lastMeal + pet.endurance > block.timestamp); pet.lastMeal = block.timestamp; } function _beforeTokenTransfer(address from, address to, uint256 tokenId) internal override { Pet storage pet = _tokenDetails[nextId]; require(pet.lastMeal + pet.endurance > block.timestamp); //Pet still alive } }
2_token_migration.js
const Token = artifacts.require("Token"); module.exports = async function (deployer) { await deployer.deploy(Token, "NFT Game", "NFTG"); let tokenInstance = await Token.deployed(); await tokenInstance.mint(100,200,100000); // Token id 0 let pet = await tokenInstance.getTokenDetails(0); console.log(pet) };
有返回的錯誤
Error: Returned error: VM Exception while processing transaction: revert at module.exports (C:\Projetos\NFT\NFTGameMoralis\migrations\2_token_migration.js:6:23) at processTicksAndRejections (node:internal/process/task_queues:96:5) at Migration._deploy (C:\Users\Usuario\AppData\Roaming\npm\node_modules\truffle\build\webpack:\packages\migrate\Migration.js:75:1) at Migration._load (C:\Users\Usuario\AppData\Roaming\npm\node_modules\truffle\build\webpack:\packages\migrate\Migration.js:56:1) at Migration.run (C:\Users\Usuario\AppData\Roaming\npm\node_modules\truffle\build\webpack:\packages\migrate\Migration.js:217:1) at Object.runMigrations (C:\Users\Usuario\AppData\Roaming\npm\node_modules\truffle\build\webpack:\packages\migrate\index.js:150:1) at Object.runFrom (C:\Users\Usuario\AppData\Roaming\npm\node_modules\truffle\build\webpack:\packages\migrate\index.js:110:1) at Object.run (C:\Users\Usuario\AppData\Roaming\npm\node_modules\truffle\build\webpack:\packages\migrate\index.js:87:1) at runMigrations (C:\Users\Usuario\AppData\Roaming\npm\node_modules\truffle\build\webpack:\packages\core\lib\commands\migrate.js:258:1) at Object.run (C:\Users\Usuario\AppData\Roaming\npm\node_modules\truffle\build\webpack:\packages\core\lib\commands\migrate.js:223:1) at Command.run (C:\Users\Usuario\AppData\Roaming\npm\node_modules\truffle\build\webpack:\packages\core\lib\command.js:183:1) Truffle v5.4.21 (core: 5.4.21) Node v16.13.0
您的第一個問題在這裡:
function mint(uint8 damage, uint8 magic, uint256 endurance) public onlyOwner { _safeMint(msg.sender, nextId); _tokenDetails[nextId] = Pet(damage, magic, block.timestamp, endurance); nextId++; }
_safeMint
將在內部呼叫_beforeTokenTransfer
. 您的實現_beforeTokenTransfer
需要訪問給定 tokenId 的 Pet 結構,但這些僅在呼叫_safeMint
您的程式碼後設置。要解決此問題,您需要反轉呼叫順序:
function mint(uint8 damage, uint8 magic, uint256 endurance) public onlyOwner { _tokenDetails[nextId] = Pet(damage, magic, block.timestamp, endurance); _safeMint(msg.sender, nextId); nextId++; }
此外,我認為您的
_beforeTokenTransfer
實施有誤:function _beforeTokenTransfer(address from, address to, uint256 tokenId) internal override { Pet storage pet = _tokenDetails[nextId]; require(pet.lastMeal + pet.endurance > block.timestamp); //Pet still alive }
_tokenDetails[nextId]
不可能是對的。它將通過您的鑄幣廠操作,但如果您允許轉移 NFT,則會導致不良行為。正確的實現應該使用tokenId
接收的作為參數。所以像這樣:function _beforeTokenTransfer(address from, address to, uint256 tokenId) internal override { Pet storage pet = _tokenDetails[tokenId]; require(pet.lastMeal + pet.endurance > block.timestamp); //Pet still alive }
如果您在
_beforeTokenTransfer
. 使用它們,如您所見,它們非常方便。