Web3: Vertragsfunktion ausführen, aber nur Transaktionshash oder falschen Wert erhalten

Ich versuche, eine Funktion in meinem eigenen Geth-Testnetz zu demonstrieren. Ich habe einen Mustervertrag bereitgestellt, den ich unter http://solidity.readthedocs.io/en/develop/types.html?highlight=crowdfunding gefunden habe .

pragma solidity ^0.4.11;

contract CrowdFunding {
    // Defines a new type with two fields.
    struct Funder {
        address addr;
        uint amount;
    }

    struct Campaign {
        address beneficiary;
        uint fundingGoal;
        uint numFunders;
        uint amount;
        mapping (uint => Funder) funders;
    }

    uint numCampaigns;
    mapping (uint => Campaign) campaigns;

    function newCampaign(address beneficiary, uint goal) returns (uint campaignID) {
        campaignID = numCampaigns++; // campaignID is return variable
        // Creates new struct and saves in storage. We leave out the mapping type.
        campaigns[campaignID] = Campaign(beneficiary, goal, 0, 0);
    }

    function contribute(uint campaignID) payable {
        Campaign storage c = campaigns[campaignID];
        // Creates a new temporary memory struct, initialised with the given values
        // and copies it over to storage.
        // Note that you can also use Funder(msg.sender, msg.value) to initialise.
        c.funders[c.numFunders++] = Funder({addr: msg.sender, amount: msg.value});
        c.amount += msg.value;
    }

    function checkGoalReached(uint campaignID) returns (bool reached) {
        Campaign storage c = campaigns[campaignID];
        if (c.amount < c.fundingGoal)
            return false;
        uint amount = c.amount;
        c.amount = 0;
        c.beneficiary.transfer(amount);
        return true;
    }
}

„Vertrag“ verweist auf den bereitgestellten Vertrag. Ich habe mein Standardkonto eingerichtet und die newCampaign-Funktion ausgeführt:

> contract.newCampaign(eth.accounts[0], 100)
"0x0122973cbcb7df227e8d625c6ee4a831d716b8b69398e4431ec14f89951fdc25"

Also habe ich den TransactionHash. Und für die mit meinem Konto verknüpfte Adresse sollte eine neue Kampagne erstellt worden sein. Aber wenn ich versuche, die Funktion "checkGoalReached" aufzurufen, bekomme ich immer "true", obwohl sie für meine Kampagne "false" zurückgeben sollte, da niemand beigetragen hat.

(Ich habe sowohl 0 als auch 1 ausprobiert, weil es auf der ID basiert)

> contract.checkGoalReached.call(0)
true
> contract.checkGoalReached.call(1)
true

Dann habe ich versucht, die Transaktion zu senden und das Ergebnis für diese Funktion zu protokollieren:

> contract.checkGoalReached(0, function(e, result) {console.log(result)})
0xe1bf7a275a62fb3bc2cdd12ff280cde5e9064ddbfeb51ba6713a713cd356c8cc
undefined
> contract.checkGoalReached(1, function(e, result){console.log(result)})
0x613c5973733cde57d4b7325bbab2d841d2fa6c95e371e77ca24a2f5a54768fd3
undefined

"false" sollte zurückgegeben werden, also muss ich in der web3-Konsole etwas falsch machen. Wie teste ich diese Funktionen in der Konsole richtig?

Antworten (1)

Ich habe mit Ihrem Vertrag in Remix herumgespielt, um zu bestätigen, dass er tut, was er zu tun scheint. Aufgrund der Datenstruktur weist es ein unerwartetes Verhalten auf. Beispielsweise wird für jeden undefinierten Vertrag zurückgegeben, trueweil 0nicht kleiner als ist 0.

Mit "streng" meine ich, dass eine Untersuchung einer nicht existierenden Kampagne wahrscheinlich throwim Gegensatz zu einem irreführenden Ergebnis erfolgen sollte. Sie könnten erwägen, dies zu verschärfen, indem Sie eine zugeordnete Struktur mit Index verwenden. ( Gibt es gut gelöste und einfache Speichermuster für Solidity? ).

Auf jeden Fall habe ich bestätigt, dass es falsewie erwartet mit einer brandneuen Kampagne mit einem Ziel von zurückkehrt 100. Dies unterscheidet sich von den Ergebnissen, die Sie beim Aufrufen erhalten, und ich denke, das hat mit dem Versuch zu tun, es synchron zu verwenden.

Grundsätzlich müssen Sie auf Ergebnisse warten oder es führt in die Irre. Zum Beispiel:

var contract;
MyContract.deployed().then(function(instance) { contract = instance; });

Jetzt können Sie mit der Darstellung Ihres bereitgestellten Vertrags fortfahren contract. Sie müssen auf die Rückkehr der Versprechen warten, also versuchen Sie es auf diese Weise:

contract.checkGoalReached().call(0).then(function(response) { console.log(response); });

Ich bin davon ausgegangen, dass Sie Truffle verwenden. :-)

Ich hoffe es hilft.