Cómo generar todos los datos de la variable de mapeo del contrato

Solidity permite el uso de matrices asociativas con mapping:

mapping(address => uint256) balances;

El código se puede escribir para iterar a través de esta matriz asociativa. Pero, ¿cómo se pueden enviar todas las claves y valores a un terminal, una página web o un archivo descargable?

Puede escribir un método de contrato para devolver datos. Use la consola truffle para invocar el método para mostrar el resultado en la consola, use la API web3 para mostrar el resultado en la página web.

Respuestas (2)

"Solidity permite el uso de matrices asociativas con mapeo:

mapeo(dirección => uint256) saldos; El código se puede escribir para iterar a través de esta matriz asociativa".

No creo que tengamos un iterador predefinido que recorra el mapeo en solidez. La respuesta es del siguiente enlace, donde se introduce un índice para recorrer el mapeo.

https://forum.ethereum.org/discussion/1995/iterating-mapping-types

mapping (address => uint) accountBalances;
mapping (uint => address) accountIndex;
uint accountCount;
function iterateAccountsBalances()
{
    for(uint i=0;i<accountCount;i++)
    {
        doSomeStuff(accountBalances[accountIndex[i]]);
    }
}

En el caso anterior, accountIndex es el índice que hace posible el acceso secuencial.

Pero, ¿cómo se pueden enviar todas las claves y valores a un terminal, una página web o un archivo descargable?

Hay diferentes formas de hacerlo, puede conectar su contrato con Web3 si lo necesita web y si es una consola, posiblemente podría usar la consola truffle.

Rangesh muestra un punto principal y luego obtengo una demostración simple. Al principio, creamos un contrato simple MappingTest

contract MappingTest {

  CustomMap balances;

  struct CustomMap {
     mapping (address => uint) maps;
     address[] keys;
  }

  function put() payable public {
     address sender = msg.sender;
     uint256 value = msg.value;
     bool contain = contains(sender);
     if (contain) {
       balances.maps[sender] = balances.maps[sender] + value;
     } else {
       balances.maps[sender] = value;
       balances.keys.push(sender);
     }
  }

  function iterator() constant returns (address[],uint[]){
      uint len = balances.keys.length;
      address[] memory keys = new address[](len);
      uint[] memory values = new uint[](len);
      for (uint i = 0 ; i <  len ; i++) {
         address key = balances.keys[i];
         keys[i] = key;
         values[i] = balances.maps[key];
      }
      return (keys,values);
  }

  function remove(address _addr) payable returns (bool) {
      int index = indexOf(_addr);
      if (index < 0) {
          return false;
      }
      delete balances.maps[_addr];
      delete balances.keys[uint(index)];
      return true;
  }

  function indexOf(address _addr) constant returns (int) {
    uint len = balances.keys.length;
    if (len == 0) {
        return -1;
    }
    for (uint i = 0 ; i < len ;i++) {
      if (balances.keys[i] == _addr) {
          return int(i);
      }
    }
    return -1;
  }

  function contains(address _addr) constant returns (bool) {
      if (balances.keys.length == 0) {
         return false;
      }
      uint len = balances.keys.length;
      for (uint i = 0 ; i < len ; i++) {
          if (balances.keys[i] == _addr) {
            return true;
          }
      }
      return false;
  } 

}

y luego compile, implemente el contrato por geth. Ahora, desbloqueamos la cuenta y luego ejecutamos la función put

browser_test_sol_mappingtest.put({from:eth.accounts[0],value:web3.toWei(1,'ether')})
browser_test_sol_mappingtest.put({from:eth.accounts[1],value:web3.toWei(1,'ether')})

ahora, hay dos txs esperando a ser extraídos, luego ejecute la operación mía

miner.start(1);admin.sleepBlock(1);miner.stop()

dos txs se empaquetaron en un nuevo bloque, ahora ejecutamos la función de interacción para mostrar el resultado

> browser_test_sol_mappingtest.iterator()
[["0x0b46c35d2e823f9b1e69ff616f9e9bf2d9d52dd0", "0xc4b232913cb195f649086d1eea0f1eb3fd0ff825"], [1000000000000000000, 1000000000000000000]]

Es lo mismo eliminar, contiene, la función indexOf.

Para JSON RPC, Cómo llamar a un método de contrato usando la API eth_call JSON-RPC le dará un paso detallado.

Espero que esto te ayude ~

Gracias por una respuesta tan elaborada. ¿Estoy en lo correcto al suponer esto?: 1) Se puede enviar a la terminal oa la web, pero no como un archivo descargable; 2) Su código no podría extraer datos de la mappingvariable de un contrato existente. Es decir, no es posible crear un segundo contrato con su código para extraer datos de la mappingvariable del primer contrato. Su código debe incluirse en el primer contrato.