# Solidity error : errored: Gas required exceeds limit: 30000

i am new to solidity and trying to learn it. I was looking at some contract source codes and trying to run them in testnet. i found the below contract and used remix ide to test it in ropsnet but get the error when i try to initialize the sale: Steps i have followed: 1.Create Ven contract 2. create Ven sale contract 3. trying to initialize using parameters - (contract address of Ven contract, ethaddress, ethaddress)

i get the gas limit exceeded error on step. Step 1 and 2 works fine. Am i doing the right thing or following the right steps?

Contract Code:

``````pragma solidity ^0.4.11;

contract Owned {

function Owned() {
owner = msg.sender;
}

modifier onlyOwner() {
require(msg.sender == owner);
_;
}

owner = _newOwner;
}
}

/**
* @title SafeMath
* @dev Math operations with safety checks that throw on error
*/
library SafeMath {
function mul(uint256 a, uint256 b) internal constant returns (uint256) {
uint256 c = a * b;
assert(a == 0 || c / a == b);
return c;
}

function div(uint256 a, uint256 b) internal constant returns (uint256) {
// assert(b > 0); // Solidity automatically throws when dividing by 0
uint256 c = a / b;
// assert(a == b * c + a % b); // There is no case in which this doesn't hold
return c;
}

function sub(uint256 a, uint256 b) internal constant returns (uint256) {
assert(b <= a);
return a - b;
}

function add(uint256 a, uint256 b) internal constant returns (uint256) {
uint256 c = a + b;
assert(c >= a);
return c;
}

function toUINT112(uint256 a) internal constant returns(uint112) {
assert(uint112(a) == a);
return uint112(a);
}

function toUINT120(uint256 a) internal constant returns(uint120) {
assert(uint120(a) == a);
return uint120(a);
}

function toUINT128(uint256 a) internal constant returns(uint128) {
assert(uint128(a) == a);
return uint128(a);
}
}

// Abstract contract for the full ERC 20 Token standard
// https://github.com/ethereum/EIPs/issues/20

contract Token {
/* This is a slight change to the ERC20 base standard.
function totalSupply() constant returns (uint256 supply);
is replaced with:
uint256 public totalSupply;
This automatically creates a getter function for the totalSupply.
This is moved to the base contract since public getter functions are not
currently recognised as an implementation of the matching abstract
function by the compiler.
*/
/// total amount of tokens
//uint256 public totalSupply;
function totalSupply() constant returns (uint256 supply);

/// @param _owner The address from which the balance will be retrieved
/// @return The balance
function balanceOf(address _owner) constant returns (uint256 balance);

/// @notice send `_value` token to `_to` from `msg.sender`
/// @param _to The address of the recipient
/// @param _value The amount of token to be transferred
/// @return Whether the transfer was successful or not
function transfer(address _to, uint256 _value) returns (bool success);

/// @notice send `_value` token to `_to` from `_from` on the condition it is approved by `_from`
/// @param _from The address of the sender
/// @param _to The address of the recipient
/// @param _value The amount of token to be transferred
/// @return Whether the transfer was successful or not

/// @notice `msg.sender` approves `_addr` to spend `_value` tokens
/// @param _spender The address of the account able to transfer the tokens
/// @param _value The amount of wei to be approved for transfer
/// @return Whether the approval was successful or not
function approve(address _spender, uint256 _value) returns (bool success);

/// @param _owner The address of the account owning tokens
/// @param _spender The address of the account able to transfer the tokens
/// @return Amount of remaining tokens allowed to spent

}

/// VEN token, ERC20 compliant
contract VEN is Token, Owned {
using SafeMath for uint256;

string public constant name    = "VeChain Token";  //The Token's name
uint8 public constant decimals = 18;               //Number of decimals of the smallest unit
string public constant symbol  = "VEN";            //An identifier

// packed to 256bit to save gas usage.
struct Supplies {
// uint128's max value is about 3e38.
// it's enough to present amount of tokens
uint128 total;
uint128 rawTokens;
}

Supplies supplies;

// Packed to 256bit to save gas usage.
struct Account {
// uint112's max value is about 5e33.
// it's enough to present amount of tokens
uint112 balance;

// raw token can be transformed into balance with bonus
uint112 rawTokens;

// safe to store timestamp
uint32 lastMintedTimestamp;
}

// Balances for each account

// Owner of account approves the transfer of an amount to another account

// bonus that can be shared by raw tokens
uint256 bonusOffered;

// Constructor
function VEN() {
}

function totalSupply() constant returns (uint256 supply){
return supplies.total;
}

// Send back ether sent to me
function () {
revert();
}

// If sealed, transfer is enabled and mint is disabled
function isSealed() constant returns (bool) {
return owner == 0;
}

function lastMintedTimestamp(address _owner) constant returns(uint32) {
return accounts[_owner].lastMintedTimestamp;
}

// Claim bonus by raw tokens
require(isSealed());
if (accounts[_owner].rawTokens != 0) {
uint256 realBalance = balanceOf(_owner);
uint256 bonus = realBalance
.sub(accounts[_owner].balance)
.sub(accounts[_owner].rawTokens);

accounts[_owner].balance = realBalance.toUINT112();
accounts[_owner].rawTokens = 0;
if(bonus > 0){
Transfer(this, _owner, bonus);
}
}
}

// What is the balance of a particular account?
function balanceOf(address _owner) constant returns (uint256 balance) {
if (accounts[_owner].rawTokens == 0)
return accounts[_owner].balance;

if (bonusOffered > 0) {
uint256 bonus = bonusOffered
.mul(accounts[_owner].rawTokens)
.div(supplies.rawTokens);

}

return uint256(accounts[_owner].balance)
}

// Transfer the balance from owner's account to another account
function transfer(address _to, uint256 _amount) returns (bool success) {
require(isSealed());

// implicitly claim bonus for both sender and receiver
claimBonus(msg.sender);
claimBonus(_to);

// according to VEN's total supply, never overflow here
if (accounts[msg.sender].balance >= _amount
&& _amount > 0) {
accounts[msg.sender].balance -= uint112(_amount);
Transfer(msg.sender, _to, _amount);
return true;
} else {
return false;
}
}

// Send _value amount of tokens from address _from to address _to
// The transferFrom method is used for a withdraw workflow, allowing contracts to send
// tokens on your behalf, for example to "deposit" to a contract address and/or to charge
// fees in sub-currencies; the command should fail unless the _from account has
// deliberately authorized the sender of the message via some mechanism; we propose
// these standardized APIs for approval:
function transferFrom(
uint256 _amount
) returns (bool success) {
require(isSealed());

// implicitly claim bonus for both sender and receiver
claimBonus(_from);
claimBonus(_to);

// according to VEN's total supply, never overflow here
if (accounts[_from].balance >= _amount
&& allowed[_from][msg.sender] >= _amount
&& _amount > 0) {
accounts[_from].balance -= uint112(_amount);
allowed[_from][msg.sender] -= _amount;
Transfer(_from, _to, _amount);
return true;
} else {
return false;
}
}

// Allow _spender to withdraw from your account, multiple times, up to the _value amount.
// If this function is called again it overwrites the current allowance with _value.
function approve(address _spender, uint256 _amount) returns (bool success) {
allowed[msg.sender][_spender] = _amount;
Approval(msg.sender, _spender, _amount);
return true;
}

/* Approves and then calls the receiving contract */
allowed[msg.sender][_spender] = _value;
Approval(msg.sender, _spender, _value);

//call the receiveApproval function on the contract you want to be notified. This crafts the function signature manually so one doesn't have to include a contract in here just for this.
//it is assumed that when does this that the call *should* succeed, otherwise one would use vanilla approve instead.
return true;
}

return allowed[_owner][_spender];
}

// Mint tokens and assign to some one
function mint(address _owner, uint256 _amount, bool _isRaw, uint32 timestamp) onlyOwner{
if (_isRaw) {
} else {
}

accounts[_owner].lastMintedTimestamp = timestamp;

Transfer(0, _owner, _amount);
}

// Offer bonus to raw tokens holder
function offerBonus(uint256 _bonus) onlyOwner {
Transfer(0, this, _bonus);
}

// Set owner to zero address, to disable mint, and enable token transfer
function seal() onlyOwner {
setOwner(0);
}
}

}

// Contract to sell and distribute VEN tokens
contract VENSale is Owned{

/// chart of stage transition
///
/// deploy   initialize      startTime                            endTime                 finalize
///                              | <-earlyStageLasts-> |             | <- closedStageLasts -> |
///  O-----------O---------------O---------------------O-------------O------------------------O------------>
///     Created     Initialized           Early             Normal             Closed            Finalized
enum Stage {
NotCreated,
Created,
Initialized,
Early,
Normal,
Closed,
Finalized
}

using SafeMath for uint256;

uint256 public constant totalSupply         = (10 ** 9) * (10 ** 18); // 1 billion VEN, decimals set to 18

uint256 constant privateSupply              = totalSupply * 9 / 100;  // 9% for private ICO
uint256 constant commercialPlan             = totalSupply * 23 / 100; // 23% for commercial plan
uint256 constant reservedForTeam            = totalSupply * 5 / 100;  // 5% for team
uint256 constant reservedForOperations      = totalSupply * 22 / 100; // 22 for operations

// 59%
uint256 public constant nonPublicSupply     = privateSupply + commercialPlan + reservedForTeam + reservedForOperations;
// 41%
uint256 public constant publicSupply = totalSupply - nonPublicSupply;

uint256 public constant officialLimit = 64371825 * (10 ** 18);
uint256 public constant channelsLimit = publicSupply - officialLimit;

// packed to 256bit
struct SoldOut {
uint16 placeholder; // placeholder to make struct pre-alloced

// amount of tokens officially sold out.
// max value of 120bit is about 1e36, it's enough for token amount
uint120 official;

uint120 channels; // amount of tokens sold out via channels
}

SoldOut soldOut;

uint256 constant venPerEth = 3500;  // normal exchange rate
uint256 constant venPerEthEarlyStage = venPerEth + venPerEth * 15 / 100;  // early stage has 15% reward

uint constant minBuyInterval = 30 minutes; // each account can buy once in 30 minutes
uint constant maxBuyEthAmount = 30 ether;

VEN ven; // VEN token contract follows ERC20 standard

address venVault; // the account to keep non-public offered VEN tokens

uint public constant startTime = 1503057600; // time to start sale
uint public constant endTime = 1504180800;   // tiem to close sale
uint public constant earlyStageLasts = 3 days; // early bird stage lasts in seconds

bool initialized;
bool finalized;

function VENSale() {
soldOut.placeholder = 1;
}

/// @notice calculte exchange rate according to current stage
/// @return exchange rate. zero if not in sale.
function exchangeRate() constant returns (uint256){
if (stage() == Stage.Early) {
return venPerEthEarlyStage;
}
if (stage() == Stage.Normal) {
return venPerEth;
}
return 0;
}

/// @notice for test purpose
function blockTime() constant returns (uint32) {
return uint32(block.timestamp);
}

/// @notice estimate stage
/// @return current stage
function stage() constant returns (Stage) {
if (finalized) {
return Stage.Finalized;
}

if (!initialized) {
// deployed but not initialized
return Stage.Created;
}

if (blockTime() < startTime) {
// not started yet
return Stage.Initialized;
}

// all sold out
return Stage.Closed;
}

if (blockTime() < endTime) {
// in sale
// early bird stage
return Stage.Early;
}
// normal stage
return Stage.Normal;
}

// closed
return Stage.Closed;
}

uint size;
if (_addr == 0) return false;
assembly {
}
return size > 0;
}

/// @notice entry to buy tokens
function () payable {
}

/// @notice entry to buy tokens
// reject contract buyer to avoid breaking interval limit
require(!isContract(msg.sender));
require(msg.value >= 0.01 ether);

uint256 rate = exchangeRate();
// here don't need to check stage. rate is only valid when in sale
require(rate > 0);
// each account is allowed once in minBuyInterval

uint256 requested;
} else {
requested = msg.value.mul(rate);
}

uint256 remained = officialLimit.sub(soldOut.official);
if (requested > remained) {
//exceed remained
requested = remained;
}

uint256 ethCost = requested.div(rate);
if (requested > 0) {
ven.mint(msg.sender, requested, true, blockTime());
// transfer ETH to vault
ethVault.transfer(ethCost);

onSold(msg.sender, requested, ethCost);
}

uint256 toReturn = msg.value.sub(ethCost);
if(toReturn > 0) {
// return over payed ETH
msg.sender.transfer(toReturn);
}
}

/// @notice returns tokens sold officially
function officialSold() constant returns (uint256) {
return soldOut.official;
}

/// @notice returns tokens sold via channels
function channelsSold() constant returns (uint256) {
return soldOut.channels;
}

/// @notice manually offer tokens to channel
function offerToChannel(address _channelAccount, uint256 _venAmount) onlyOwner {
Stage stg = stage();
// since the settlement may be delayed, so it's allowed in closed stage
require(stg == Stage.Early || stg == Stage.Normal || stg == Stage.Closed);

//should not exceed limit
require(soldOut.channels <= channelsLimit);

ven.mint(
_channelAccount,
_venAmount,
true,  // unsold tokens can be claimed by channels portion
blockTime()
);

onSold(_channelAccount, _venAmount, 0);
}

/// @notice initialize to prepare for sale
/// @param _ven The address VEN token contract following ERC20 standard
/// @param _ethVault The place to store received ETH
/// @param _venVault The place to store non-publicly supplied VEN tokens
function initialize(
VEN _ven,
require(stage() == Stage.Created);

// ownership of token contract should already be this

ven = _ven;

ethVault = _ethVault;
venVault = _venVault;

ven.mint(
venVault,
false, // team and operations reserved portion can't share unsold tokens
blockTime()
);

ven.mint(
venVault,
true, // private ICO and commercial plan can share unsold tokens
blockTime()
);

initialized = true;
onInitialized();
}

/// @notice finalize
function finalize() onlyOwner {
// only after closed stage
require(stage() == Stage.Closed);

uint256 unsold = publicSupply.sub(soldOut.official).sub(soldOut.channels);

if (unsold > 0) {
// unsold VEN as bonus
ven.offerBonus(unsold);
}
ven.seal();

finalized = true;
onFinalized();
}

event onInitialized();
event onFinalized();

}
``````
• Update : it looks like some sort of coding issue to me. because we see gas errors if its not able to calculate gas – andy Feb 1 '18 at 12:13

The error shown means that the computations that need to be done are more costly than 30000 Gas. You can adjust / increase the Gas Limit Parameter in the Remix IDE at the panel on the right side of the page.

Apart from that I do not understand lines like the following

``````privateSupply.add(commercialPlan),
``````

where you use 'add' on a specific element. I am not a Solidity expert but I think the right way to do it would be the following:

``````...
...
``````

Hope it helps.

EDIT:

I tried your code in Remix. I had no issue concerning the gas limit (3000000 was fine). Following your steps described above I had an issue with permissions. It came from line 547:

``````require(_ven.owner() == address(this));
``````

So I used the `setOwner` function to set the owner of the `VEN` contract to the address of the `VENSale` contract. After this it worked without error.

Steps:

1. Create `VEN` Contract
2. Create `VENSale` contract
3. Set `VENSale` contract as the owner of the `VEN` contract (with the `setOwner` function)
4. Invoke the `initialize` function with parameters (`VEN` contract address, ethaddress, ethaddress)
• thanks for your reply. How do i do that? if i comment everything in the initialise function then i get the metamask pop up. – andy Jan 31 '18 at 12:18
• Sorry, perhaps I got you wrong: What value does the "Gas limit" field in remix show you? From your question I concluded that it is 30000. If so you probably need to increase this value. – joffi Jan 31 '18 at 13:02
• This does not provide an answer to the question. Once you have sufficient reputation you will be able to comment on any post; instead, provide answers that don't require clarification from the asker. - From Review – Nicolas Massart Jan 31 '18 at 13:05
• @joffi - right now it says 3000000. but doesnt matter whatever i put in there, i get the same error. – andy Jan 31 '18 at 13:06
• @Nicolas Massart: I've edited my answer. Hopefully it was an improvement. Sorry for the bad style. I need to learn how to provide better answers... – joffi Jan 31 '18 at 13:53