1

mapping(address => uint256) public something;

I would like to copy the data in the mapping above into a new mapping in a new contract. Kinda like exporting the data. Any ideas?

  • I don't think it is possible with an easy and clean way. – Florian Castelain Jan 26 '18 at 4:28
  • Any way to communicate with the data stored in it in an external way? Just interacting with the data at least. The mapping is public. – enriquejr99 Jan 26 '18 at 4:42
  • The problem is that a mapping is a deep complexe type. You can't return all the value of a mapping at once. – Florian Castelain Jan 26 '18 at 4:48
  • 1
    @Andromelus It is possible to return all values of mapping but since mapping can assimilate large amount of data, \the transaction may run out of gas if lot of data is being returned by mapping – Ayushya Jan 26 '18 at 6:34
  • Yes, sorry. What I meant was : "You can't return directly the mapping itself". You have to keep track of it size and loop trhough it, and as you said, yes, it can cost a lot. I think the best solution for this question is the one of hextet :) – Florian Castelain Jan 26 '18 at 6:51
1

So there's no real way to natively iterate through a mapping in solidity so I'll propose a useful pattern

contract Test {
    address[] public addrs;
    mapping (address => uint256) public something;
    mapping (address => bool) public registered;
    function registerSomething(address _addr, uint256 _value) {
        require(!registered[_addr]);
        registered[_addr] = true;
        addrs.push(_addr);
        something[_addr] = _value;
    }
}

So using the above pattern everytime you register an address with a contract for the first time, it would be pushed onto the addrs array. You can then use this array to pull a list of ALL addresses who have an entry in your something mapping, query the mapping with your desired addresses returning the uint256.

Note due to block gas limit issues, I'd recommend against implementing the looping logic through your smart contract, and instead, implement it off-chain with a web3 script written in a language like JS or Python.

edit:

Alternate Solution

You could also use an event which is triggered when an address is registered with your something mapping, and then have a web3 script off-chain that listens to the events, and record the address locally.

Note that this solution has the disadvantage that during a hard fork, event logs are lost so I'd probably opt for the initial solution I proposed.

0

You can make the mapping iterable and then use a function to get values of all the data stored in mapping. Below code creates two mappings, one to store the sequence number of account and another to store balance of account.

pragma solidity ^0.4.18;
contract oldContract{

  mapping(address => uint256) oldAccounts;
  mapping(uint256 => address) public accountSequence;
  //by default any new account will show false for registered mapping
  mapping(address => bool) registered;

  address[] listOfAddresses;
  uint256 public numberOfAccounts = 0;

  function registerAccount(address user) public {
    //only unregistered users will be registered
    require(!registered[user]);
    accountSequence[numberOfAccounts++] = user;
    listOfAddresses.push(user);
    registered[user] = true;
  }
}
  • You can use the publicly available numberOfAccounts to find out how many addresses have been stored.
  • The accountSequence function will be a getter function, which you can call from outside of blockchain, starting loop from 0 to numberOfAccounts and get all accounts that have been registered.

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.