Truffle 测试不起作用,收到:处理事务时出现 VM 异常:没油了
Truffle tests not working, recieving: VM Exception while processing transaction: out of gas
我正在尝试测试我的合同,但我收到了这个错误:
Events
✔ deploys a factory and an event
✔ marks caller as the event manager
1) allows the user to buy a ticket and stores their details
2 passing (1s)
1 failing
1) Events
allows the user to buy a ticket and stores their details:
c: VM Exception while processing transaction: out of gas
at Function.c.fromResults (node_modules/ganache-cli/build/ganache-core.node.cli.js:4:192416)
at w.processBlock (node_modules/ganache-cli/build/ganache-core.node.cli.js:42:50915)
at processTicksAndRejections (internal/process/task_queues.js:94:5)
但是,在查看我的代码时,我相信我有足够的汽油,也许这个错误与其他原因有关。
这是我的测试代码:
const assert = require('assert');
const ganache = require('ganache-cli');
const Web3 = require('web3');
const web3 = new Web3(ganache.provider({ gasLimit: 10000000 }));
const compiledFactory = require("../ethereum/build/EventFactory.json");
const compiledCampaign = require("../ethereum/build/Event.json");
let accounts;
let factory;
let eventAddress;
let event;
beforeEach(async () => {
accounts = await web3.eth.getAccounts();
factory = await new web3.eth.Contract(JSON.parse(compiledFactory.interface))
.deploy({ data: compiledFactory.bytecode })
.send({ from: accounts[0], gas: "10000000" });
await factory.methods.createEvent("test event", 2, 1, "Elton John's world tour", "Faketown auditorium", 100).send({
from: accounts[0],
gas: "10000000",
});
[eventAddress] = await factory.methods.getDeployedEvents().call();
event = await new web3.eth.Contract(
JSON.parse(compiledCampaign.interface),
eventAddress
);
});
describe("Events", () => {
it("deploys a factory and an event", () => {
assert.ok(factory.options.address);
assert.ok(event.options.address);
});
it("marks caller as the event manager", async () => {
const manager = await event.methods.manager().call();
assert.equal(accounts[0], manager);
});
it("allows the user to buy a ticket and stores their details", async () => {
await event.methods.buyTicket('Louie').send({
value: '1',
from: accounts[1]
});
const isContributor = await event.methods.attendees(account[1]).call();
assert(isContributor);
});
});
如您所见,我的前两个测试通过了。但是第三个不起作用。我相信我提供了足够的汽油。这是我的合同,您可以查看其中的功能:
pragma solidity ^0.4.17;
contract EventFactory {
address[] public deployedEvents;
function createEvent(string title, uint max, uint cost, string description, string location, uint date) public {
address newEvent = new Event(title, msg.sender, max, cost, description, location, date);
deployedEvents.push(newEvent);
}
function getDeployedEvents() public view returns (address[]) {
return deployedEvents;
}
}
contract Event {
struct Attendee {
bool valid;
string name;
uint ticketNumber;
bool confirmed;
uint amountPaid;
uint confirmationCode;
}
address public manager;
string public title;
uint public maxAttendees;
uint public ticketsSold;
mapping(address=>Attendee) public attendees;
uint public ticketCost;
string public eventDescription;
string public eventLocation;
uint public eventDate;
mapping(address=>bool) public blacklist;
modifier restricted() {
require(msg.sender == manager);
_;
}
function random(uint seed) private view returns (uint) {
uint tmp = uint(block.blockhash(block.number - 1));
return uint(keccak256(tmp,seed)) % 1000000000;
}
function Event(string eventTitle, address creator, uint max, uint cost, string description, string location, uint date) public {
title = eventTitle;
manager = creator;
maxAttendees = max;
ticketsSold = 0;
ticketCost = cost;
eventDescription = description;
eventLocation = location;
eventDate = date;
}
function buyTicket(string name) public payable {
require(blacklist[msg.sender] != true);
require(ticketsSold != maxAttendees);
require(attendees[msg.sender].valid == false);
require(msg.value == ticketCost);
Attendee memory attendee = Attendee({
valid: true,
name: name,
ticketNumber: (maxAttendees - ticketsSold),
confirmed: false,
amountPaid: ticketCost,
confirmationCode: 0
});
ticketsSold++;
attendees[msg.sender] = attendee;
}
function challengeAttendee(address attendee, uint seed) public restricted returns (uint) {
require(attendees[attendee].valid == true);
uint code = random(seed);
attendees[attendee].confirmationCode = code;
return code;
}
function confirmTicketOwnerShip(uint code) public {
require(attendees[msg.sender].confirmationCode != 0);
attendees[msg.sender].confirmed = attendees[msg.sender].confirmationCode == code;
}
function confirmResponse(address attendee) public restricted view returns (bool) {
return attendees[attendee].confirmed;
}
function addToBlackList(address blockedAddress) public restricted {
blacklist[blockedAddress] = true;
}
function getEventDetails() public view returns (string, uint, uint, uint, string, string, uint) {
return (
title,
maxAttendees,
ticketsSold,
ticketCost,
eventDescription,
eventLocation,
eventDate
);
}
}
尝试替换此测试:
it("allows the user to buy a ticket and stores their details", async () => {
await event.methods.buyTicket('Louie').send({
value: '1',
from: accounts[1]
});
const isContributor = await event.methods.attendees(account[1]).call();
assert(isContributor);
});
与以下一个:
it("allows the user to buy a ticket and stores their details", async () => {
await event.methods.buyTicket('Louie').send({
value: '1',
gasPrice: '1',
from: accounts[1]
});
const isContributor = await event.methods.attendees(account[1]).call();
assert(isContributor);
});
我发现了这个错误,不幸的是,这只是一个拼写错误。在第六行,我使用 account[1] 而不是 accounts[1]。我还必须指定气体,因为默认量不够。
我的代码现在看起来像:
it("allows the user to buy a ticket and stores their details", async () => {
await event.methods.buyTicket("Louie").send({
from: accounts[1],
value: '1',
gas: '20000000'
});
const isContributor = await event.methods.attendees(accounts[1]).call();
assert(isContributor.valid);
});
我正在尝试测试我的合同,但我收到了这个错误:
Events
✔ deploys a factory and an event
✔ marks caller as the event manager
1) allows the user to buy a ticket and stores their details
2 passing (1s)
1 failing
1) Events
allows the user to buy a ticket and stores their details:
c: VM Exception while processing transaction: out of gas
at Function.c.fromResults (node_modules/ganache-cli/build/ganache-core.node.cli.js:4:192416)
at w.processBlock (node_modules/ganache-cli/build/ganache-core.node.cli.js:42:50915)
at processTicksAndRejections (internal/process/task_queues.js:94:5)
但是,在查看我的代码时,我相信我有足够的汽油,也许这个错误与其他原因有关。
这是我的测试代码:
const assert = require('assert');
const ganache = require('ganache-cli');
const Web3 = require('web3');
const web3 = new Web3(ganache.provider({ gasLimit: 10000000 }));
const compiledFactory = require("../ethereum/build/EventFactory.json");
const compiledCampaign = require("../ethereum/build/Event.json");
let accounts;
let factory;
let eventAddress;
let event;
beforeEach(async () => {
accounts = await web3.eth.getAccounts();
factory = await new web3.eth.Contract(JSON.parse(compiledFactory.interface))
.deploy({ data: compiledFactory.bytecode })
.send({ from: accounts[0], gas: "10000000" });
await factory.methods.createEvent("test event", 2, 1, "Elton John's world tour", "Faketown auditorium", 100).send({
from: accounts[0],
gas: "10000000",
});
[eventAddress] = await factory.methods.getDeployedEvents().call();
event = await new web3.eth.Contract(
JSON.parse(compiledCampaign.interface),
eventAddress
);
});
describe("Events", () => {
it("deploys a factory and an event", () => {
assert.ok(factory.options.address);
assert.ok(event.options.address);
});
it("marks caller as the event manager", async () => {
const manager = await event.methods.manager().call();
assert.equal(accounts[0], manager);
});
it("allows the user to buy a ticket and stores their details", async () => {
await event.methods.buyTicket('Louie').send({
value: '1',
from: accounts[1]
});
const isContributor = await event.methods.attendees(account[1]).call();
assert(isContributor);
});
});
如您所见,我的前两个测试通过了。但是第三个不起作用。我相信我提供了足够的汽油。这是我的合同,您可以查看其中的功能:
pragma solidity ^0.4.17;
contract EventFactory {
address[] public deployedEvents;
function createEvent(string title, uint max, uint cost, string description, string location, uint date) public {
address newEvent = new Event(title, msg.sender, max, cost, description, location, date);
deployedEvents.push(newEvent);
}
function getDeployedEvents() public view returns (address[]) {
return deployedEvents;
}
}
contract Event {
struct Attendee {
bool valid;
string name;
uint ticketNumber;
bool confirmed;
uint amountPaid;
uint confirmationCode;
}
address public manager;
string public title;
uint public maxAttendees;
uint public ticketsSold;
mapping(address=>Attendee) public attendees;
uint public ticketCost;
string public eventDescription;
string public eventLocation;
uint public eventDate;
mapping(address=>bool) public blacklist;
modifier restricted() {
require(msg.sender == manager);
_;
}
function random(uint seed) private view returns (uint) {
uint tmp = uint(block.blockhash(block.number - 1));
return uint(keccak256(tmp,seed)) % 1000000000;
}
function Event(string eventTitle, address creator, uint max, uint cost, string description, string location, uint date) public {
title = eventTitle;
manager = creator;
maxAttendees = max;
ticketsSold = 0;
ticketCost = cost;
eventDescription = description;
eventLocation = location;
eventDate = date;
}
function buyTicket(string name) public payable {
require(blacklist[msg.sender] != true);
require(ticketsSold != maxAttendees);
require(attendees[msg.sender].valid == false);
require(msg.value == ticketCost);
Attendee memory attendee = Attendee({
valid: true,
name: name,
ticketNumber: (maxAttendees - ticketsSold),
confirmed: false,
amountPaid: ticketCost,
confirmationCode: 0
});
ticketsSold++;
attendees[msg.sender] = attendee;
}
function challengeAttendee(address attendee, uint seed) public restricted returns (uint) {
require(attendees[attendee].valid == true);
uint code = random(seed);
attendees[attendee].confirmationCode = code;
return code;
}
function confirmTicketOwnerShip(uint code) public {
require(attendees[msg.sender].confirmationCode != 0);
attendees[msg.sender].confirmed = attendees[msg.sender].confirmationCode == code;
}
function confirmResponse(address attendee) public restricted view returns (bool) {
return attendees[attendee].confirmed;
}
function addToBlackList(address blockedAddress) public restricted {
blacklist[blockedAddress] = true;
}
function getEventDetails() public view returns (string, uint, uint, uint, string, string, uint) {
return (
title,
maxAttendees,
ticketsSold,
ticketCost,
eventDescription,
eventLocation,
eventDate
);
}
}
尝试替换此测试:
it("allows the user to buy a ticket and stores their details", async () => {
await event.methods.buyTicket('Louie').send({
value: '1',
from: accounts[1]
});
const isContributor = await event.methods.attendees(account[1]).call();
assert(isContributor);
});
与以下一个:
it("allows the user to buy a ticket and stores their details", async () => {
await event.methods.buyTicket('Louie').send({
value: '1',
gasPrice: '1',
from: accounts[1]
});
const isContributor = await event.methods.attendees(account[1]).call();
assert(isContributor);
});
我发现了这个错误,不幸的是,这只是一个拼写错误。在第六行,我使用 account[1] 而不是 accounts[1]。我还必须指定气体,因为默认量不够。
我的代码现在看起来像:
it("allows the user to buy a ticket and stores their details", async () => {
await event.methods.buyTicket("Louie").send({
from: accounts[1],
value: '1',
gas: '20000000'
});
const isContributor = await event.methods.attendees(accounts[1]).call();
assert(isContributor.valid);
});