Voreingestellte testRPC-Kontostände werden während der Truffle-Konsolensitzung nicht in der Solidity-Vertragszuordnung angezeigt

Ich bemerke, dass voreingestellte Salden in testrpc wie folgt sind:

unix$ testrpc --account="privKey1,balance1" --account="privKey2,balance2" ...

nicht an diese Solidity-Datenstruktur weitergegeben werden:

mapping(address => uint) public accounts

Hier ist der triviale Code:

pragma solidity ^0.4.7;

contract EtherBank {

    // ---------------------------------------------------------------------------
    // Define variables used in this contract (including in constructor) here.
    // ---------------------------------------------------------------------------
    mapping(address => uint) public accounts;
    // ---------------------------------------------------------------------------

    // ---------------------------------------------------------------------------
    // Constructor (initializer). Runs once upon creation.
    // ---------------------------------------------------------------------------
    function EtherBank() {
        accounts[msg.sender] = 1000;
    }
    // ---------------------------------------------------------------------------

    // ---------------------------------------------------------------------------
    // ---------------------------------------------------------------------------
    function getBalance(address addr) constant returns (uint _balance) {
        return accounts[addr];
    }
    // ---------------------------------------------------------------------------
}

Und hier ist die interaktive Trüffelkonsolensitzung, die zu unterschiedlichen Ergebnissen führt:

truffle(default)> account1 = web3.eth.accounts[0]
truffle(default)> account2 = web3.eth.accounts[1]

truffle(default)> web3.eth.getBalance(account1)
{ [String: '9.99997416659e+22'] s: 1, e: 22, c: [ 999997416, 65900000000000 ] }

truffle(default)> web3.eth.getBalance(account2)
{ [String: '1e+23'] s: 1, e: 23, c: [ 1000000000 ] }

truffle(default)> c = EtherBank.deployed()

truffle(default)> c.getBalance(account1)
{ [String: '1000'] s: 1, e: 3, c: [ 1000 ] } <-- Expected above to be the same as this.

truffle(default)> c.getBalance(account2)  
{ [String: '0'] s: 1, e: 0, c: [ 0 ] }  <-- Expected this to be same as above.

Irgendwelche Ideen? Vielleicht mache ich etwas falsch. Vielen Dank! =:)

Antworten (1)

Diese Ergebnisse sind sinnvoll, da beim Deployment EtherBanknur msg.senderdie Deployment-Transaktion einen Saldo erhält.

Hier gibt es zwei völlig unterschiedliche Arten von Guthaben: Es gibt Ether, die Mittel, mit denen Sie Gas bezahlen können und die als Mining-Belohnungen dienen, und dann gibt es Ihr „Bank“-Guthaben. Wenn Sie die verwenden

--account="privKey1,balance1" --account="privKey2,balance2" ...

Option ordnen Sie Ether den beiden Konten zu, wie Sie mit sehen können

web3.eth.getBalance(account1)

Die nächste Art von Guthaben ist das „EtherBank“-Guthaben, das nur eine Zahl in der Speicherung eines Kontrakts ist.

Wenn der Konstruktor ausgeführt wird:

function EtherBank() {
    accounts[msg.sender] = 1000;
}

Sie können sehen, dass der Vertrag dem Absender der Transaktion, die den Vertrag erstellt hat, einen Saldo von 1000 gibt. Beachten Sie, dass dies nicht 1000 ETH ist, es ist nur so, dass eine Variable im Vertrag auf 1000 gesetzt ist.

Ein möglicher Punkt der Verwirrung ist:

 mapping(address => uint) public accounts;

Der Name accountsist völlig bedeutungslos. Wir könnten dies benennen foound der Vertrag würde sich genauso verhalten.

TestRPC weiß nichts über Ihren Vertrag, der ein völlig willkürliches Konstrukt ist. Es verhält sich im Hauptnetzwerk genauso wie auf TestRPC.

Wenn ich das richtig verstehe, möchten Sie in Ihrem Vertrag Salden voreinstellen (die nur willkürliche Werte sind und außerhalb der ihnen im Vertrag zugewiesenen Bedeutung keine Bedeutung haben). Wenn dies der Fall ist, machen Sie einfach dies zum Konstruktor:

 function EtherBank(address[] addrs, uint[] balances) {
    if(addrs.length != balances.length) throw;
    for(uint i; i < addrs.length; i++){
        accounts[addrs[i]] = balances[i];
    }
}

Ich glaube nicht, dass Konstruktoren in Truffle Argumente annehmen können, also müssen Sie dies möglicherweise zu einer separaten Funktion machen, die nur einmal aufgerufen werden kann.

Ja, mir wurde klar, dass es sich um unterschiedliche Datenstrukturen handelt (das hat meine Frage ausgelöst). Aber können Sie die Unterscheidung näher erläutern? Es wäre hilfreich. Hinweis: Der ursprüngliche Testcode beabsichtigte nicht, irgendwo ein Gleichgewicht zu setzen. Ich habe es einfach hier hinzugefügt, um das Problem zu demonstrieren (Missverständnis oder anderweitig). Was ich beabsichtigte, war, die hier erwähnten "--account" Special Options von testrpc zu verwenden -- github.com/ethereumjs/testrpc -- um Schlüssel/Salden voreinzustellen (und nichts fest zu codieren). Wie simuliert man mit einem nicht fest codierten Vertrag ein Netzwerk aus voreingestellten Schlüsseln/Salden über testrpc?
PS Ich werde dieses Wik und die referenzierten Beispiele weiter lesen: github.com/ethereum/wiki/wiki/JavaScript-API
Möchten Sie Ihren Konten echte ETH geben oder nur ein Guthaben in einem Vertrag?
Ah, okay. Vielen Dank für die entzückende Erweiterung Ihrer ursprünglichen Antwort (die ich ausgewählt habe). Es wird auch für andere hilfreich sein. Zu Ihrem letzten Kommentar, eigentlich beide Arten, aber zunächst in einem Vertrag ausgleichen - nur um meine Füße nass zu machen. =:)