【发布时间】:2022-01-07 05:19:19
【问题描述】:
我正在建立在 Truffle 提供的教程之上:https://trufflesuite.com/tutorial/index.html
我正在尝试添加类似于以下内容的 returnPet 函数:Adding a return function to Truffles Pet Shop
但是,当我点击宠物上的“返回”按钮时,我在使用元掩码时遇到了 RPC 错误。
MetaMask - RPC Error: [ethjs-query] while formatting outputs from RPC '{"value":{"code":-32603,"data":{"message":"VM Exception while processing transaction: revert","code":-32000,"data":{"0x36735e441b9c6ffeb61bcebce098576993c38580ecc207f99043706a074a06e4":{"error":"revert","program_counter":70,"return":"0x"},"stack":"RuntimeError: VM Exception while processing transaction: revert\n at Function.RuntimeError.fromResults (/tmp/.mount_ganachz4CZxO/resources/static/node/node_modules/ganache-core/lib/utils/runtimeerror.js:94:13)\n at BlockchainDouble.processBlock (/tmp/.mount_ganachz4CZxO/resources/static/node/node_modules/ganache-core/lib/blockchain_double.js:627:24)\n at runMicrotasks (<anonymous>)\n at processTicksAndRejections (internal/process/task_queues.js:93:5)","name":"RuntimeError"}}}}'
Object { code: -32603, message: "[ethjs-query] while formatting outputs from RPC '{\"value\":{\"code\":-32603,\"data\":{\"message\":\"VM Exception while processing transaction: revert\",\"code\":-32000,\"data\":{\"0x36735e441b9c6ffeb61bcebce098576993c38580ecc207f99043706a074a06e4\":{\"error\":\"revert\",\"program_counter\":70,\"return\":\"0x\"},\"stack\":\"RuntimeError: VM Exception while processing transaction: revert\\n at Function.RuntimeError.fromResults (/tmp/.mount_ganachz4CZxO/resources/static/node/node_modules/ganache-core/lib/utils/runtimeerror.js:94:13)\\n at BlockchainDouble.processBlock (/tmp/.mount_ganachz4CZxO/resources/static/node/node_modules/ganache-core/lib/blockchain_double.js:627:24)\\n at runMicrotasks (<anonymous>)\\n at processTicksAndRejections (internal/process/task_queues.js:93:5)\",\"name\":\"RuntimeError\"}}}}'" }
我在这里维护这项工作:https://github.com/mpoletiek/pet-shop-tutorial
我不知道从哪里开始。在 Metamask 中批准交易之前,它会警告:
This transaction is expected to fail. Trying to execute it is expected to be expensive but fail, and is not recommended.
我单击“无论如何我都会尝试”以生成 RPC 错误。
这是我的 Solidity 合约:
pragma solidity ^0.5.0;
contract Adoption {
address[16] public adopters;
// Adopting a pet
function adopt(uint petId) public returns (uint) {
require(petId >= 0 && petId <= 15);
adopters[petId] = msg.sender;
return petId;
}
// Retrieving the adopters
function getAdopters() public view returns (address[16] memory) {
return adopters;
}
// Return Pet
function returnPet(uint petId) public returns (address) {
require(petId >= 0 && petId <= 15);
// Address must own the pet
require(msg.sender == adopters[petId]);
// Clear the adopter for this pet
adopters[petId] = address(0);
return adopters[petId];
}
}
和 app.js:
App = {
web3Provider: null,
accounts: [],
contracts: {},
adoptionInstance: null,
init: async function() {
// Load pets.
$.getJSON('../pets.json', function(data) {
var petsRow = $('#petsRow');
var petTemplate = $('#petTemplate');
for (i = 0; i < data.length; i ++) {
petTemplate.find('.panel-title').text(data[i].name);
petTemplate.find('img').attr('src', data[i].picture);
petTemplate.find('.pet-breed').text(data[i].breed);
petTemplate.find('.pet-age').text(data[i].age);
petTemplate.find('.pet-location').text(data[i].location);
petTemplate.find('.btn-adopt').attr('data-id', data[i].id);
petTemplate.find('.btn-return').attr('data-id', data[i].id);
petsRow.append(petTemplate.html());
}
});
return await App.initWeb3();
},
initWeb3: async function() {
// Modern dapp browsers...
if (window.ethereum){
try {
//Request account access
App.accounts = await window.ethereum.request({ method: "eth_requestAccounts" });
} catch (error) {
// User denied account access...
console.error("User denied account access");
}
// User granted access to accounts
console.log("Account[0]: "+App.accounts[0]);
App.web3Provider = window.ethereum;
console.log("modern dapp browser");
}
// Legacy dapp browsers...
else if (window.web3) {
App.web3Provider = window.web3.currentProvider;
App.accounts = window.eth.accounts;
console.log("legacy dapp browser");
}
// if no injected web3 instance is detected, fall back to Ganache
else {
App.web3Provider = new Web3.providers.HttpProvider('http://localhost:7545');
}
web3 = new Web3(App.web3Provider);
return App.initContract();
},
initContract: function() {
$.getJSON('Adoption.json', function(data) {
// Get the necessary contract artifact file and instantiate it with @truffle/contract
var AdoptionArtifact = data;
try { App.contracts.Adoption = TruffleContract(AdoptionArtifact); } catch (error) { console.error(error); }
// Set the provider for our contract
try {
App.contracts.Adoption.setProvider(App.web3Provider);
} catch (error){
console.log(error);
}
// Use our contract to retrieve and mark the adopted pets
return App.markAdopted();
});
return App.bindEvents();
},
bindEvents: function() {
$(document).on('click', '.btn-adopt', App.handleAdopt);
$(document).on('click', '.btn-return', App.handleReturn);
},
markAdopted: function() {
var adoptionInstance;
App.contracts.Adoption.deployed().then(function(instance) {
App.adoptionInstance = instance;
return App.adoptionInstance.getAdopters.call();
}).then(function(adopters) {
for(i=0;i<adopters.length;i++){
if (adopters[i] != '0x0000000000000000000000000000000000000000') {
if (adopters[i] == App.accounts[0]){
$('.panel-pet').eq(i).find('.btn-return').text('Return').attr('disabled', false);
$('.panel-pet').eq(i).find('.btn-adopt').text('Adopted').attr('disabled', true);
} else {
$('.panel-pet').eq(i).find('.btn-return').text('-').attr('disabled', true);
$('.panel-pet').eq(i).find('.btn-adopt').text('Adopted').attr('disabled', true);
}
} else {
$('.panel-pet').eq(i).find('.btn-return').text('-').attr('disabled', true);
}
}
}).catch(function(err) {
console.log(err.message);
});
},
handleReturn: function(event) {
event.preventDefault();
var petId = parseInt($(event.target).data('id'));
console.log("petID:"+petId);
App.contracts.Adoption.deployed().then(function(instance) {
// Execute adopt as a transaction by sending account
return App.adoptionInstance.returnPet(petId, {from: App.accounts[0]});
}).then(function(result) {
return App.markAdopted();
}).catch(function(err) {
console.log(err.message);
});
},
handleAdopt: function(event) {
event.preventDefault();
var petId = parseInt($(event.target).data('id'));
console.log("petId:"+petId);
App.contracts.Adoption.deployed().then(function(instance) {
// Execute adopt as a transaction by sending account
return App.adoptionInstance.adopt(petId, {from: account[0]});
}).then(function(result) {
return App.markAdopted();
}).catch(function(err) {
console.log(err.message);
});
}
};
$(function() {
$(window).load(function() {
App.init();
});
});
一切都编译并且我的测试运行正常。在我确认之前不确定 Metamask 如何知道交易是坏的,但这是一个提示吗?如果有帮助,我会在 Firefox 和 Chrome 中得到相同的结果。
任何想法我应该首先检查什么?
谢谢,
【问题讨论】:
标签: javascript ethereum solidity smartcontracts web3