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?
"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 ~
mapping
variable de un contrato existente. Es decir, no es posible crear un segundo contrato con su código para extraer datos de la mapping
variable del primer contrato. Su código debe incluirse en el primer contrato.
Abhishek