So geben Sie alle Daten aus der Mapping-Variable des Vertrags aus

Solidity ermöglicht die Verwendung assoziativer Arrays mit mapping:

mapping(address => uint256) balances;

Code kann geschrieben werden, um dieses assoziative Array zu durchlaufen. Aber wie können alle Schlüssel und Werte auf einem Terminal, einer Webseite oder einer herunterladbaren Datei ausgegeben werden?

Sie können eine Vertragsmethode schreiben, um Daten zurückzugeben. Verwenden Sie die Truffle-Konsole, um die Methode zum Anzeigen des Ergebnisses auf der Konsole aufzurufen, verwenden Sie die Web3-API, um das Ergebnis auf der Webseite anzuzeigen.

Antworten (2)

"Solidity ermöglicht die Verwendung von assoziativen Arrays mit Zuordnung:

Zuordnung (Adresse => uint256) Salden; Code kann geschrieben werden, um dieses assoziative Array zu durchlaufen."

Ich glaube nicht, dass wir einen vordefinierten Iterator haben, der die Zuordnung in Solidität durchläuft. Die Antwort stammt aus dem folgenden Link, wo ein Index eingeführt wird, um die Zuordnung zu durchlaufen.

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]]);
    }
}

Im obigen Fall ist accountIndex der Index, der den sequentiellen Zugriff ermöglicht.

Aber wie können alle Schlüssel und Werte auf einem Terminal, einer Webseite oder einer herunterladbaren Datei ausgegeben werden?

Es gibt verschiedene Möglichkeiten, dies zu tun. Sie können entweder Ihren Vertrag mit Web3 verbinden, wenn Sie es für das Web benötigen, und wenn es sich um eine Konsole handelt, können Sie möglicherweise die Truffle-Konsole verwenden.

Rangesh zeigt einen Hauptpunkt, und dann bekomme ich eine einfache Demo. Zunächst erstellen wir einen einfachen Vertrag 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;
  } 

}

und dann den Vertrag von geth kompilieren und bereitstellen. Jetzt entsperren wir das Konto und führen dann die Put-Funktion aus

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')})

jetzt warten zwei txs darauf, abgebaut zu werden, dann führe meine op aus

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

Zwei TXs wurden in einen neuen Block gepackt, jetzt führen wir die Interator- Funktion aus, um das Ergebnis anzuzeigen

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

Es ist dasselbe wie bei der Funktion remove, contains, indexOf.

Für JSON RPC gibt Ihnen How to call a contract method using the eth_call JSON-RPC API einen detaillierten Schritt.

Hoffe das hilft dir ~

Danke für so eine ausführliche Antwort. Gehe ich richtig davon aus?: 1) Es kann an ein Terminal oder Web ausgegeben werden, aber nicht als herunterladbare Datei; 2) Ihr Code wäre nicht in der Lage, Daten aus der Variablen eines bestehenden Vertrags zu extrahieren mapping. Das heißt, es ist nicht möglich, mit Ihrem Code einen zweiten Vertrag zu erstellen, um Daten aus der Variablen des ersten Vertrags zu extrahieren mapping. Ihr Code muss im 1. Vertrag enthalten sein.