3

I notice that preset balances in testrpc, like this:

unix$ testrpc --account="privKey1,balance1" --account="privKey2,balance2" ...

don't get passed to this Solidity data structure:

mapping(address => uint) public accounts

Here is the trivial code:

pragma solidity ^0.4.7;

contract EtherBank {

    // ---------------------------------------------------------------------------
    // Define variables used in this contract (including in constructor) here.
    // ---------------------------------------------------------------------------
    mapping(address => uint) public accounts;
    // ---------------------------------------------------------------------------

    // ---------------------------------------------------------------------------
    // Constructor (initializer). Runs once upon creation.
    // ---------------------------------------------------------------------------
    function EtherBank() {
        accounts[msg.sender] = 1000;
    }
    // ---------------------------------------------------------------------------

    // ---------------------------------------------------------------------------
    // ---------------------------------------------------------------------------
    function getBalance(address addr) constant returns (uint _balance) {
        return accounts[addr];
    }
    // ---------------------------------------------------------------------------
}

And here is the interactive truffle console session that leads to different results:

truffle(default)> account1 = web3.eth.accounts[0]
truffle(default)> account2 = web3.eth.accounts[1]

truffle(default)> web3.eth.getBalance(account1)
{ [String: '9.99997416659e+22'] s: 1, e: 22, c: [ 999997416, 65900000000000 ] }

truffle(default)> web3.eth.getBalance(account2)
{ [String: '1e+23'] s: 1, e: 23, c: [ 1000000000 ] }

truffle(default)> c = EtherBank.deployed()

truffle(default)> c.getBalance(account1)
{ [String: '1000'] s: 1, e: 3, c: [ 1000 ] } <-- Expected above to be the same as this.

truffle(default)> c.getBalance(account2)  
{ [String: '0'] s: 1, e: 0, c: [ 0 ] }  <-- Expected this to be same as above.

Any ideas? Maybe I'm doing something incorrectly. Thank you! =:)

3

These results make sense, because when EtherBank is deployed, only the msg.sender of the deployment transaction is given a balance.

There are two entirely separate types of balance here: There is Ether, the funds that allow you to pay for gas and which act as mining rewards, and then there is your "Bank" balance. When you use the

--account="privKey1,balance1" --account="privKey2,balance2" ...

option, you are allocating Ether to the two accounts, as you can see with

web3.eth.getBalance(account1)

The next type of balance is the "EtherBank" balance, which is just a number in the storage of a contract.

When the constructor is run:

function EtherBank() {
    accounts[msg.sender] = 1000;
}

you can see that the contract gives the sender of the transaction that created the contract a balance of 1000. Note that this is not 1000 ETH, it's just that a variable in the contract is set to 1000.

One potential point of confusion is:

 mapping(address => uint) public accounts;

The name accounts is entirely meaningless. We could name this foo and the contract would behave exactly the same.

TestRPC doesn't know anything about your contract, which is an entirely arbitrary construct. It will behave the same on the main network as it does on TestRPC.

If I understand correctly, you want to preset balances in your contract (which remember are just arbitrary values and have no meaning outside that which the contract assigns to them). If this is the case, just make this the constructor:

 function EtherBank(address[] addrs, uint[] balances) {
    if(addrs.length != balances.length) throw;
    for(uint i; i < addrs.length; i++){
        accounts[addrs[i]] = balances[i];
    }
}

I don't believe constructors in Truffle can take arguments, so you may have to make this a separate function that can only be called once.

  • Yes I realized that they are different data structures (that's what gave rise to my question). But can you elaborate on the distinction? It would be helpful. Note: The original test code didn't intend to set a balance anywhere. I simply added it here to demonstrate the issue (misunderstanding or otherwise). What I intended, was to use the "--account" Special Options of testrpc, mentioned here -- github.com/ethereumjs/testrpc -- to preset keys/balances (and not hard-code anything). Using one non-hard coded contract, how does one simulate a network of preset keys/balances via testrpc? – NYCeyes Jan 10 '17 at 18:42
  • P.S. I'll have a further read of this Wik and referenced examples: github.com/ethereum/wiki/wiki/JavaScript-API – NYCeyes Jan 10 '17 at 19:00
  • Do you want to give your accounts real ETH, or just a balance in a contract? – Tjaden Hess Jan 10 '17 at 19:04
  • Ah, okay. Thank you for the delightful expansion to your original answer (which I selected). It will be helpful to others, too. On your last comment, actually both kinds, but initially balance in a contract -- just to get my feet wet. =:) – NYCeyes Jan 10 '17 at 19:15

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.