2

I have the following two contracts :

contract Token {
   string public name;
   uint8 public decimals;
   address public owner;
   mapping (address => uint256) public balanceOf;

    function Token(uint256 initialSupply, string tokenName, uint8 decimalUnits)    {
        balanceOf[msg.sender] = initialSupply;             
        name = tokenName;                                  
        decimals = decimalUnits;  
        owner = msg.sender;
    }

    function transfer(address _to, uint256 _value) {
        balanceOf[owner] -= _value;
        balanceOf[_to] += _value;
    }
}

contract Crowdsale {

    address public beneficiary;
    uint public fundingGoal;
    uint public amountRaised; 
    uint public deadline;
    uint public price;   
    Token public tokenReward;
    mapping(address => uint256) public balanceOf; 
    bool public fundingGoalReached = false; 
    bool public crowdsaleClosed = false;

    function Crowdsale(uint _fundingGoal, uint _duration, uint costToken, Token addressOfToken) { 
        beneficiary = msg.sender; 
        fundingGoal = _fundingGoal; 
        deadline = now + _duration ; 
        price = costToken;
        tokenReward = Token(addressOfToken); 
    }

    function contribute() public {
        if (crowdsaleClosed) throw; 
        uint amount = msg.value; 
        balanceOf[msg.sender] = amount; 
        amountRaised += amount; 
        tokenReward.transfer(msg.sender, amount / price); 
    }

    modifier afterDeadline() {
        if (now >= deadline) 
            _ 
    }

    function checkGoalReached() afterDeadline{
        if (amountRaised >= fundingGoal) { 
           fundingGoalReached = true; 
        } 
        crowdsaleClosed = true; 
    }
}

I'm trying to execute contribute function but no change occurs to the amountRaised and the function transfer also doesnt get called. What am I doing wrong?

I deployed first token contract. then used its address as parameter for constructor call. i'm using 2 nodes the first node is deploying the contracts and the second is calling the contribute function as follows : fundingGoal is 10000 (say)

var camp = eth.contract(abi).at(address)
camp.contribute.sendTransaction({from : eth.coinbase , value : 5000})
  • Can you provide some details on how you're making the call? – Richard Horrocks Aug 29 '16 at 8:19
  • i have updated the question – Aditi Aug 29 '16 at 8:29
  • can you show the outputs of eth.getTransaction and eth.getTransactionReceipt on that tx? – kobigurk Aug 29 '16 at 11:51
  • I am trying to do the same thing, but got lots of failed transactions. What should the addressoftoken be? Is it contract address or token holder's address? If token holder's address, is it should be the creator of token contract? Thanks. – Jeffrey Joo-Han Song Oct 4 '16 at 1:19
2

Summary

Your transaction ran out of gas as you were using the default gas amount. Set a higher gas amount and the transaction should succeed.



Details

The default gas for a transaction to a contract is 90,000. The default gas for a transaction to another accounts is 21,000.

When I sent the transaction using the default gas of 90,000 by either leaving out the gas field or by specifying gas: 90000, the transaction ran out of gas (gasUsed == gas specified):

var tx = crowdsale1.contribute.sendTransaction({
    from : eth.accounts[1], 
    value : 5000, 
    gas:90000});
"0x3470d1f3d8f30ca9a8dcd6bc462c39048dd534fdb3a7ccec20c142cb5c841315"
eth.getTransactionReceipt(tx)
{
  blockHash: "0x810850aa7cc73cc88f782c845fde37ff755610e72e0bd6ba2f174ffc1e257133",
  blockNumber: 5012,
  contractAddress: null,
  cumulativeGasUsed: 90000,
  from: "0x4d5bbe7fbc80933ffa90ece988a764e41ee6d018",
  gasUsed: 90000,
  logs: [],
  root: "0bde4bb628081d72749ce52c1a2c113095d58ce24616f9954b054a0b74af737b",
  to: "0x2bb37852254a30008dfb8652cc4910fc29bc4b83",
  transactionHash: "0x3470d1f3d8f30ca9a8dcd6bc462c39048dd534fdb3a7ccec20c142cb5c841315",
  transactionIndex: 0
}

When I bumped specified gas of 100,000, the transaction ran out of gas:

var tx = crowdsale1.contribute.sendTransaction({
    from : eth.accounts[1], 
    value : 5000, 
    gas: 100000})
"0x8923eeaae8b8b4bbc1b4d5ef2f818b6111faabcfea7141c075334222acc51fbf"
eth.getTransactionReceipt(tx)
{
  blockHash: "0x700e07a23ca603d0dc4d76ff53f3f8419eab9453ea69b341d970b0c94444d2de",
  blockNumber: 5018,
  contractAddress: null,
  cumulativeGasUsed: 100000,
  from: "0x4d5bbe7fbc80933ffa90ece988a764e41ee6d018",
  gasUsed: 100000,
  logs: [],
  root: "29cd898651720f714e8f7ce17e4de6f34836aa8ab394762d00b77f49d8e82ab3",
  to: "0x2bb37852254a30008dfb8652cc4910fc29bc4b83",
  transactionHash: "0x8923eeaae8b8b4bbc1b4d5ef2f818b6111faabcfea7141c075334222acc51fbf",
  transactionIndex: 0
}

When I bumped specified gas of 1,000,000, the transaction was successful:

var tx = crowdsale1.contribute.sendTransaction({
    from : eth.accounts[1], 
    value : 5000, 
    gas: 1000000})
"0x42493b8d656889064e21dcac0074c0323d3bff56b0f26a8b724f9437de3bddca"
eth.getTransactionReceipt(tx)
{
  blockHash: "0xd6849c93366f15a61957f48803e41afbab03085c454339dbd43ec311e02c7901",
  blockNumber: 5024,
  contractAddress: null,
  cumulativeGasUsed: 87765,
  from: "0x4d5bbe7fbc80933ffa90ece988a764e41ee6d018",
  gasUsed: 87765,
  logs: [],
  root: "ef9eca739275dd9e316caaac26db9635b72b4948a0eeb5e600adeec7020f357f",
  to: "0x2bb37852254a30008dfb8652cc4910fc29bc4b83",
  transactionHash: "0x42493b8d656889064e21dcac0074c0323d3bff56b0f26a8b724f9437de3bddca",
  transactionIndex: 0
}

Checking that the transaction succeeded:

> crowdsale.balanceOf(eth.accounts[1]);
5000
> token.balanceOf(eth.accounts[1]);
50

The strange thing is that the gas required was 87765 but the default 90,000 or the specified 100,000 failed.

So I tried gas of 120,000:

> eth.getTransactionReceipt(tx)
{
  blockHash: "0x8da8d92cd2505a4c41c6b5c7f8edb844127f7780faec50393e915fe4c0dfb522",
  blockNumber: 5065,
  contractAddress: null,
  cumulativeGasUsed: 42765,
  from: "0x4d5bbe7fbc80933ffa90ece988a764e41ee6d018",
  gasUsed: 42765,
  logs: [],
  root: "2aafe894dfa857a79faa423732a79760328f981d50690159b56fcf8bbdac747a",
  to: "0x2bb37852254a30008dfb8652cc4910fc29bc4b83",
  transactionHash: "0xc2441e38fde80ed853943d0e178a76542391cf8fc8e1b6f146aad3ce90d9bbbb",
  transactionIndex: 0
}

And I tried gas of 100,000 and now it works:

> eth.getTransactionReceipt(tx)
{
  blockHash: "0x9f4fef406d6fe0c8a77e786f50c952001b7fa933c2ffa5e0b3ca71e1531f066a",
  blockNumber: 5072,
  contractAddress: null,
  cumulativeGasUsed: 42765,
  from: "0x4d5bbe7fbc80933ffa90ece988a764e41ee6d018",
  gasUsed: 42765,
  logs: [],
  root: "efaecfe5f23410fed052a30b6b7a0c99e644c519f854965db672f9ad906c3afd",
  to: "0x2bb37852254a30008dfb8652cc4910fc29bc4b83",
  transactionHash: "0x817b30894cff5b94ec9f2011c79a7c447ee6158c7443c4eb1334da7116540825",
  transactionIndex: 0
}

I think that the reason why the initial transactions failed is because the cost of creating the first mapping is more than the cost of changing the value in the mapping.

So I tested a simple contract and confirmed that the creation of the mapping entry cost more gas than updating the value of an existing mapping entry:

contract Test {
   mapping (address => uint256) public balanceOf;

   function test(address _address, uint256 _value) {
       balanceOf[_address] = _value;
   }
}

The first transaction call to test(...) gave the following result:

Result: {
  "blockHash": "0x4602ab6c92896a4034ec7a1c73e98f177dd4a6a9585529485e03865210592b28",
  "blockNumber": 5132,
  "contractAddress": null,
  "cumulativeGasUsed": 43147,
  "from": "0xa7857047907d53a2e494d5f311b4b586dc6a96d2",
  "gasUsed": 43147,
  "logs": [],
  "root": "a8e5e666108060eba085b26996c0b2593ee9c3c006f5a48b6133103a3bd00bd4",
  "to": "0x4452da92e2d5828b08a6698f3b828721fe589193",
  "transactionHash": "0xba578464da93ce76b9195450ef7228bb5e0df96eaf92adbd439146da97f960b0",
  "transactionIndex": 0
}
Transaction cost: 43147 gas. 

And the second transaction call to the same function with the same address parameter gave the following result:

Result: {
  "blockHash": "0xefeedd0ed3c61f5f8af40ebc43ad48122a67b8e8178958fc5a7bfc2c03d5ac37",
  "blockNumber": 5134,
  "contractAddress": null,
  "cumulativeGasUsed": 28147,
  "from": "0xa7857047907d53a2e494d5f311b4b586dc6a96d2",
  "gasUsed": 28147,
  "logs": [],
  "root": "21e1c09c2cb2ceff0f5933427ae54eb99db9cbc1a983138cb964c58c50133f17",
  "to": "0x4452da92e2d5828b08a6698f3b828721fe589193",
  "transactionHash": "0x21e86669de32c7ea6bb2a05677e4be6ebc56e4c476e9c2cb5f3ded5aefddb907",
  "transactionIndex": 0
}
Transaction cost: 28147 gas. 

A third transaction call to the same function with a different address parameter gave the following result:

Result: {
  "blockHash": "0xf5d740fffdb5dbd1764591d415307028a98453b9e8040e5dc9e23e0c9d54cd2e",
  "blockNumber": 5144,
  "contractAddress": null,
  "cumulativeGasUsed": 43147,
  "from": "0xa7857047907d53a2e494d5f311b4b586dc6a96d2",
  "gasUsed": 43147,
  "logs": [],
  "root": "fb776d9e8fc7da3d84032de6dab94d33f3c995eccd4b16c4b7ad333fc122f14b",
  "to": "0x4452da92e2d5828b08a6698f3b828721fe589193",
  "transactionHash": "0x7561f93cd5bd335783661dfad12067387c1b7c6fe455b6db2f194ea30a1429e1",
  "transactionIndex": 0
}
Transaction cost: 43147 gas. 
  • 1
    Thank u very much :) – Aditi Aug 30 '16 at 4:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.