3

After setting up testrpc and attaching geth:

testrpc -a 10
geth attach rpc:http://localhost:8545

I initialise the following contract on the geth command line:

pragma solidity ^0.4.6;
contract AddressList {  
    event addressregistered(address addy);

    uint public NoMembers; 
    address[] public MemberAddresses;

    function registerAddress() { 
        MemberAddresses.push(msg.sender);    
        NoMembers = MemberAddresses.length;    
        addressregistered(msg.sender);
        }  
}

var addresslistContract = web3.eth.contract([{"constant":false,"inputs":[],"name":"registerAddress","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"NoMembers","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"MemberAddresses","outputs":[{"name":"","type":"address"}],"payable":false,"type":"function"},{"anonymous":false,"inputs":[{"indexed":false,"name":"addy","type":"address"}],"name":"addressregistered","type":"event"}]);
var addresslist = addresslistContract.new(
   {
     from: web3.eth.accounts[0], 
     data: '0x606060405234610000575b610260806100196000396000f30060606040526000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680631832425f14610054578063525af8601461006357806392fecc4714610086575b610000565b34610000576100616100e3565b005b34610000576100706101f1565b6040518082815260200191505060405180910390f35b34610000576100a160048080359060200190919050506101f7565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6001805480600101828181548183558181151161012c5781836000526020600020918201910161012b91905b8082111561012757600081600090555060010161010f565b5090565b5b505050916000526020600020900160005b33909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550506001805490506000819055507feb8ae6c1136c030439e9ea9ffc5cfb3d6daa418c8a5463bc839c4dd4d8382eab33604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a15b565b60005481565b600181815481101561000057906000526020600020900160005b915054906101000a900473ffffffffffffffffffffffffffffffffffffffff16815600a165627a7a723058207e10191d65bf6dfd6a5c15d4fd564ad9b5659a037257ac3d50e20147b3a1fe010029', 
     gas: '4700000'
   }, function (e, contract){
    console.log(e, contract);
    if (typeof contract.address !== 'undefined') {
         console.log('Contract mined! address: ' + contract.address + ' transactionHash: ' + contract.transactionHash);
    }
 })

I then store 10 addresses:

for (var x = 0; x < 10; x++){
    addresslist.registerAddress({from:eth.accounts[x],gas:3000000}) 
}

Finally I attempt to read the MemberAddresses list:

> addresslist.MemberAddresses()
"0x50522be14817f1e774e9077f58e7ef4f8d50137f"

As you can see, it returns a single address; the first element. If I pass a number it will return that element. I'd like a list. Can I return all array elements without a loop, on the geth console?

  • 1
    There is a answer to your question: ethereum.stackexchange.com/a/9635/4575. You can return 15 objects in one call. And ethereum.stackexchange.com/a/9433/4575: But I assume your defined as: MemberAddresses() constant str{ } where AddressList.call. MemberAddresses() does not charge you any cost. – alper Jan 10 '17 at 18:47
  • @Avatar Thanks, I don't understand how the first link answers my question. It talks about the "call stack process imposing a limitation." Is there something obvious I'm missing? – atomh33ls Jan 10 '17 at 19:00
  • Yeah limitation is the answer. You can return 10 values in one call but since there is a limitation you cannot return all array elements in once call if it exceeds the limitation. But using loop won't cost you anything since all State of the contract will stored in the blockchain and if you return value via call().get() it won't cost you. How did you defined your MemberAddresses() ? – alper Jan 10 '17 at 19:08
  • @Avatar I defined it as address[] public MemberAddresses; – atomh33ls Jan 10 '17 at 19:09
  • 2
    @Avatar That's only if you return each address as a separate variable in your return tuple. You can just return all the addresses as a single array of addresses – Tjaden Hess Jan 10 '17 at 19:12
3

You can just add a getter function

function getAddresses() constant returns (address[]){
    return MemberAddresses;      
}

Less importantly, convention is to camelCase variables, and capitalize events:

event AddressRegistered(address addy);

uint public noMembers; 
address[] public memberAddresses;

Note that other contracts will not be able to use this function, since dynamic return sizes are not supported in the EVM. You will still be able to use it from web3, though.

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.