admin管理员组文章数量:1332872
I have this contract:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;
contract CampaignFactory {
address[] public deployedCampaigns;
function createCampaign(uint minimum) public {
address newCampaign = address(new Campaign(minimum, msg.sender));
deployedCampaigns.push(newCampaign);
}
function getDeployedCampaigns() public view returns(address[] memory) {
return deployedCampaigns;
}
}
contract Campaign {
struct Request {
string description;
uint value;
address recipient;
bool plete;
uint approvalCount;
mapping(address => bool) approvals;
}
Request[] public requests;
address public manager;
uint public minimumContribution;
mapping(address => bool) public approvers;
uint public approversCount;
modifier restricted() {
require(msg.sender == manager);
_;
}
constructor(uint minimum, address creator) {
manager = creator;
minimumContribution = minimum;
}
function contribute() public payable {
require(msg.value > minimumContribution);
approvers[msg.sender] = true;
approversCount++;
}
function createRequest(string calldata description, uint value, address recipient) public restricted {
Request storage newRequest = requests.push();
newRequest.description = description;
newRequest.value = value;
newRequest.recipient = recipient;
newRequestplete = false;
newRequest.approvalCount = 0;
}
function approveRequest(uint index) public {
Request storage request = requests[index];
require(approvers[msg.sender]);
require(!request.approvals[msg.sender]);
request.approvals[msg.sender] = true;
request.approvalCount++;
}
function finalizeRequest(uint index) public restricted {
Request storage request = requests[index];
require(request.approvalCount > (approversCount / 2));
require(!requestplete);
payable(request.recipient).transfer(request.value);
requestplete = true;
}
}
And test:
const assert = require('assert');
const ganache = require('ganache-cli');
const Web3 = require('web3');
const web3 = new Web3(ganache.provider());
const piledFactory = require('../ethereum/build/CampaignFactory.json');
const piledCampaign = require('../ethereum/build/Campaign.json');
let accounts;
let factory;
let campaignAddress;
let campaign;
beforeEach(async() => {
accounts = await web3.eth.getAccounts();
web3.eth.getBalance(accounts[0]).then(result => console.log(result));
factory = await new web3.eth.Contract(piledFactory.abi)
.deploy({ data: piledFactory.evm.bytecode.object })
.send({ from: accounts[0], gas: '1000000' });
await factory.methods.createCampaign('100').send({
from: accounts[0],
gas: '1000000'
});
[campaignAddress] = await factory.methods.getDeployedCampaigns().call();
campaign = await new web3.eth.Contract(
JSON.parse(piledCampaign.interface),
campaignAddress
);
});
describe('Campaigns', () => {
it('deploys a factory and a campaign', () => {
assert.ok(factory.options.address);
assert.ok(campaign.options.address);
});
});
When I run the test, I get VM Exception while processing transaction: out of gas, but it logs that accounts[0] balance is 100000000000000000000. The problem occurs where the factory is assigned a new contract instance saying there isn't enough gas, while there clearly is.
I have this contract:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;
contract CampaignFactory {
address[] public deployedCampaigns;
function createCampaign(uint minimum) public {
address newCampaign = address(new Campaign(minimum, msg.sender));
deployedCampaigns.push(newCampaign);
}
function getDeployedCampaigns() public view returns(address[] memory) {
return deployedCampaigns;
}
}
contract Campaign {
struct Request {
string description;
uint value;
address recipient;
bool plete;
uint approvalCount;
mapping(address => bool) approvals;
}
Request[] public requests;
address public manager;
uint public minimumContribution;
mapping(address => bool) public approvers;
uint public approversCount;
modifier restricted() {
require(msg.sender == manager);
_;
}
constructor(uint minimum, address creator) {
manager = creator;
minimumContribution = minimum;
}
function contribute() public payable {
require(msg.value > minimumContribution);
approvers[msg.sender] = true;
approversCount++;
}
function createRequest(string calldata description, uint value, address recipient) public restricted {
Request storage newRequest = requests.push();
newRequest.description = description;
newRequest.value = value;
newRequest.recipient = recipient;
newRequest.plete = false;
newRequest.approvalCount = 0;
}
function approveRequest(uint index) public {
Request storage request = requests[index];
require(approvers[msg.sender]);
require(!request.approvals[msg.sender]);
request.approvals[msg.sender] = true;
request.approvalCount++;
}
function finalizeRequest(uint index) public restricted {
Request storage request = requests[index];
require(request.approvalCount > (approversCount / 2));
require(!request.plete);
payable(request.recipient).transfer(request.value);
request.plete = true;
}
}
And test:
const assert = require('assert');
const ganache = require('ganache-cli');
const Web3 = require('web3');
const web3 = new Web3(ganache.provider());
const piledFactory = require('../ethereum/build/CampaignFactory.json');
const piledCampaign = require('../ethereum/build/Campaign.json');
let accounts;
let factory;
let campaignAddress;
let campaign;
beforeEach(async() => {
accounts = await web3.eth.getAccounts();
web3.eth.getBalance(accounts[0]).then(result => console.log(result));
factory = await new web3.eth.Contract(piledFactory.abi)
.deploy({ data: piledFactory.evm.bytecode.object })
.send({ from: accounts[0], gas: '1000000' });
await factory.methods.createCampaign('100').send({
from: accounts[0],
gas: '1000000'
});
[campaignAddress] = await factory.methods.getDeployedCampaigns().call();
campaign = await new web3.eth.Contract(
JSON.parse(piledCampaign.interface),
campaignAddress
);
});
describe('Campaigns', () => {
it('deploys a factory and a campaign', () => {
assert.ok(factory.options.address);
assert.ok(campaign.options.address);
});
});
When I run the test, I get VM Exception while processing transaction: out of gas, but it logs that accounts[0] balance is 100000000000000000000. The problem occurs where the factory is assigned a new contract instance saying there isn't enough gas, while there clearly is.
Share edited Aug 23, 2022 at 17:32 TylerH 21.1k78 gold badges79 silver badges112 bronze badges asked Jan 11, 2022 at 10:07 Andrija GajicAndrija Gajic 3824 silver badges17 bronze badges 3- Double check how you provide gas and/or gas fees. It sounds like the problem lies there, not in your contract implementation. – Marko Popovic Commented Jan 11, 2022 at 13:17
- @MarkoPopovic what do you mean how do I provide gas? I am using web3 account that you get with web3 library. So far I haven't had any issues with writing my tests this way. – Andrija Gajic Commented Jan 11, 2022 at 20:52
- Does this answer your question? VM Exception while processing transaction: out of gas – TylerH Commented Aug 23, 2022 at 17:33
2 Answers
Reset to default 8Where you have .send({ from: accounts[0], gas: '1000000' })
, you are specifying that a maximum of 1000000
gas can be used to process that transaction, regardless of the balance of the from
account.
If you're deploying a large enough contract, this amount will be too small. Increasing this amount should resolve the issue.
Note, if the number you specify for gas is larger than the amount actually used, the difference will be refunded.
Please update the gasLimit
.
test/Campaign.test.js
const assert = require("assert");
const ganache = require("ganache-cli");
const Web3 = require("web3");
const options = {
gasLimit: 10000000,
};
const web3 = new Web3(ganache.provider(options));
const piledFactory = require("../build/CampaignFactory.json");
const piledCampaign = require("../build/Campaign.json");
let accounts;
let factory;
let campaignAddress;
let campaign;
beforeEach(async () => {
accounts = await web3.eth.getAccounts();
factory = await new web3.eth.Contract(piledFactory.abi)
.deploy({ data: piledFactory.evm.bytecode.object })
.send({ from: accounts[0], gas: "10000000" });
await factory.methods.createCampaign("100").send({
from: accounts[0],
gas: "10000000",
});
[campaignAddress] = await factory.methods.getDeployedCampaigns().call();
campaign = await new web3.eth.Contract(piledCampaign.abi, campaignAddress);
});
describe("Campaigns", () => {
it("deploys a factory and a campaign", () => {
assert.ok(factory.options.address);
assert.ok(campaign.options.address);
});
});
It works for me!
本文标签: javascriptweb3VM Exception while processing transaction out of gasStack Overflow
版权声明:本文标题:javascript - web3 - VM Exception while processing transaction: out of gas - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1742295251a2448594.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论