松露测试不起作用,收到:处理交易时的 VM 异常:气体耗尽

问题描述

我正在尝试测试我的合同,但收到此错误

  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)

然而,在查看我的代码时,我相信我有足够的 gas,也许这个错误与其他东西有关。

这是我的测试代码

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 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,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",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);
  });

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...