7

I try to test one of my first Smart Contract in Solidity, a simple sub currency example, as you can see below :

pragma solidity ^0.4.0;

contract Coin {

  address public owner;
  mapping (address => uint) balances;



  function Coin() {
    owner = msg.sender;
    balances[tx.origin] = 1000;
  }


  function send(address receiver, uint amount) returns (bool success) {
    if (balances[msg.sender] < amount) {
      return  false;
    }
    balances[msg.sender] -= amount;
    balances[receiver] += amount;
    return true;

  }


  function getBalance (address user) constant returns (uint balance) {
    return balances[user];
  }
}

After migration and compile, please look my truffle command in the console

> var a = web3.eth.accounts[0]
> var b = web3.eth.accounts[1]
> var coin = Coin.deployed()
> coin.then(function(instance) {return instance.getBalance.call(a);})
{ [String: '1000'] s: 1, e: 3, c: [ 1000 ] }
> coin.then(function(instance) {return instance.getBalance.call(b);})
> { [String: '0'] s: 1, e: 0, c: [ 0 ] }

At this point I'm agree with these output, but when I want to make the transaction, they said I don't have enough funds ...:

> coin.then(function(instance) {return instance.send(b,500);})
Error: Error: sender doesn't have enough funds to send tx. The upfront cost is: 724579920256558730963659928732440307373701337785 and the senders account only has: 99835768400000000000
    at runCall (/usr/local/lib/node_modules/ethereumjs-testrpc/node_modules/ethereumjs-vm/lib/runTx.js:97:10)
    at /usr/local/lib/node_modules/ethereumjs-testrpc/node_modules/ethereumjs-vm/node_modules/async/dist/async.js:3686:9
    at replenish (/usr/local/lib/node_modules/ethereumjs-testrpc/node_modules/ethereumjs-vm/node_modules/async/dist/async.js:882:17)
    at iterateeCallback (/usr/local/lib/node_modules/ethereumjs-testrpc/node_modules/ethereumjs-vm/node_modules/async/dist/async.js:867:17)
    at /usr/local/lib/node_modules/ethereumjs-testrpc/node_modules/ethereumjs-vm/node_modules/async/dist/async.js:840:16
    at /usr/local/lib/node_modules/ethereumjs-testrpc/node_modules/ethereumjs-vm/node_modules/async/dist/async.js:3691:13
    at apply (/usr/local/lib/node_modules/ethereumjs-testrpc/node_modules/ethereumjs-vm/node_modules/async/dist/async.js:21:25)
    at /usr/local/lib/node_modules/ethereumjs-testrpc/node_modules/ethereumjs-vm/node_modules/async/dist/async.js:56:12
    at Object.async.eachSeries (/usr/local/lib/node_modules/ethereumjs-testrpc/node_modules/async-eventemitter/node_modules/async/lib/async.js:130:20)
    at VM.AsyncEventEmitter.emit (/usr/local/lib/node_modules/ethereumjs-testrpc/node_modules/async-eventemitter/lib/AsyncEventEmitter.js:42:9)
    at Object.InvalidResponse (/usr/local/lib/node_modules/truffle/node_modules/truffle-contract/node_modules/web3/lib/web3/errors.js:35:16)
    at /usr/local/lib/node_modules/truffle/node_modules/truffle-contract/node_modules/web3/lib/web3/requestmanager.js:86:36
    at XMLHttpRequest.request.onreadystatechange (/usr/local/lib/node_modules/truffle/node_modules/web3/lib/web3/httpprovider.js:119:13)
    at XMLHttpRequestEventTarget.dispatchEvent (/usr/local/lib/node_modules/truffle/node_modules/xhr2/lib/xhr2.js:64:18)
    at XMLHttpRequest._setReadyState (/usr/local/lib/node_modules/truffle/node_modules/xhr2/lib/xhr2.js:354:12)
    at XMLHttpRequest._onHttpResponseEnd (/usr/local/lib/node_modules/truffle/node_modules/xhr2/lib/xhr2.js:509:12)
    at IncomingMessage.<anonymous> (/usr/local/lib/node_modules/truffle/node_modules/xhr2/lib/xhr2.js:469:24)
    at emitNone (events.js:91:20)
    at IncomingMessage.emit (events.js:185:7)
    at endReadableNT (_stream_readable.js:974:12)
    at _combinedTickCallback (internal/process/next_tick.js:74:11)
    at process._tickDomainCallback (internal/process/next_tick.js:122:9)

I tried with other accounts available in Testrpc, I've same results ... May be I missed something in my command or set up I Don't know. But this cost seems to important, no ?

Thanks for your help !

  • In your contract code, seems, getBalance should return the same value balances[owner] everytime for any address. Is this the same contract you used in your truffle tests? – Viktor Baranov Feb 13 '17 at 16:12
  • Thanks for this good remark ! wrong copy/paste of the version of my code... it's balances[user] and not balances[owner] ! – Lbrth_BoC Feb 13 '17 at 16:39
3

In your project folder, you should have a genesis.json file (in one of the directories).

According to that page it seems you can define balances amount for the accounts:

 "accounts": {
    "0000000000000000000000000000000000000001": { "balance": "1", "nonce": "1048576", "builtin": { "name": "ecrecover", "pricing": { "linear": { "base": 3000, "word": 0 } } } },
    "0000000000000000000000000000000000000002": { "balance": "1", "nonce": "1048576", "builtin": { "name": "sha256", "pricing": { "linear": { "base": 60, "word": 12 } } } },
    "0000000000000000000000000000000000000003": { "balance": "1", "nonce": "1048576", "builtin": { "name": "ripemd160", "pricing": { "linear": { "base": 600, "word": 120 } } } },
    "0000000000000000000000000000000000000004": { "balance": "1", "nonce": "1048576", "builtin": { "name": "identity", "pricing": { "linear": { "base": 15, "word": 3 } } } },
    "102e61f5d8f9bc71d0ad4a084df4e65e05ce0e1c": { "balance": "1606938044258990275541962092341162602522202993782792835301376", "nonce": "1048576" }
1

This simple test works for your contract, if you'll run it with truffle test:

contract('Coin', function(accounts) {
  it("works", function() {
    var coin = Coin.deployed();

    var a = accounts[0];
    var b = accounts[1];

    getBalances(coin, a, b, function() {
       coin.send(b,500).then(function() {
        getBalances(coin, a, b);
       });
    })
  });
});

function getBalances(coin, a, b, cb) {
  coin.getBalance.call(a).then(function(balanceA) {
    console.log("balanceA: " + balanceA);

    coin.getBalance.call(b).then(function(balanceB) {
      console.log("balanceB: " + balanceB);
      if (cb)
        cb();
    });
  });
}

The output:

balanceA: 1000
balanceB: 0
balanceA: 500
balanceB: 500
  • This shouldn't be marked as correct answer, as it doesn't answer the question at all .. – Othman Benchekroun May 17 '17 at 21:35
1

I had this issue and I think 'send' is already used as a function name / keyword and can't be used as a function name in the contract (at-least if we wish to interact with it through the truffle console). When I change the name of the send function to 'sendCoin' or something that isn't 'send' and redeploy then the above error goes away.

If you do: Coin.deployed().then(function(contractDesc) {console.log(contractDesc)}) the functions available from that contract are listed and at the bottom there is already a send function defined send: [Function],. I'm not sure how to interpret this definition properly but I guess we can't have two of the same.

1

Restart testrpc and the problem will be solved.

0

send method is a reserved method for each contract, just simply change the send method in Coin contract to sendAmount or other name, it will work.

Refer: https://github.com/sgyyz/solidity-learning/issues/1

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.