Vertragsarbeit an Remix, aber nicht mit Trüffel

Ich habe einen einfachen Zertifizierungsvertrag, der eine Zertifizierung an die Blockchain sendet. Dies ist der vollständige Vertrag:

    pragma solidity ^0.4.2;

/// @title Sending and storing certifications to the blockchain
contract CertificationStore {

struct Certification {
    string firstName;
    string lastName;
    string certName;
    string institution;
    string description;
    uint year;
    // address account;
    uint month;
    uint day;
}

mapping (address => Certification) public certifications;

Certification[] public certArray;
address[] public addressIdx;

uint numCerts;

event Send(address indexed _from);
event logIdx(address indexed _from, string location, uint idxToLog);
event logString(address indexed _from, string location, string msg);

function CertificationStore() {
    numCerts = 0;
}

function getCertArrayLength() constant returns(uint) {
    return certArray.length;
}

function getAddressIdxLength() constant returns(uint) {
    return addressIdx.length;
}

function getNumberOfCerts() constant returns(uint) {
    return numCerts;
}

function sendCert(address acct, string fn, string ln, string cn, 
    string ins, string desc, uint yy, uint mm, uint dd) returns(uint) {

    certifications[acct] = Certification({
            firstName: fn,
            lastName: ln,
            institution: ins,
            description: desc,
            certName: cn,
            year: yy,
            month: mm,
            day: dd
        });


    numCerts++;

    addressIdx.push(acct);
    certArray.push(Certification({
            firstName: fn,
            lastName: ln,
            institution: ins,
            description: desc,
            certName: cn,
            year: yy,
            month: mm,
            day: dd
        }));
    logString(acct, "in Send Cert", "pushed to both arrays");
    logIdx(acct, "in Send Cert. numCerts ", numCerts);
    Send(acct);

    return numCerts;
}

function getFirstName(address _from) constant returns(string) {

    for (uint i = 0; i < certArray.length; i++) {
        Certification cert = certArray[i];
        string name = cert.firstName;
        logIdx(_from, "at index in getFirstName", i);
        address acct = addressIdx[i];
        if(acct == _from) {
            return name;
        }
    }

    return ("no name found");
}
}

Bei Trüffel schicke ich den Vertrag so:

sendCert: function() {
var self = this;
this.setStatus("Initiating certification... (Please wait)");

var meta;
var myEvent;

CertificationStore.deployed().then(function(instance) {
  meta = instance;
  var firstName = document.getElementById("first").value;
  var lastName = document.getElementById("last").value;
  var certName = document.getElementById("cert_name").value;
  var date = document.getElementById("date").value;
  var description = document.getElementById("description").value;
  var institution = document.getElementById("institution").value;

  var tempDate = new Date(date);

  return meta.sendCert(account, firstName, lastName, certName, institution, description, tempDate.getFullYear(), tempDate.getMonth()+1, tempDate.getDay(), {from: account});
}).then(function(result) {
  // on success
  alert("Your certification was successfully sent for account: " + account);
  console.log("result of your deployment ", result);
  self.setStatus("Sent your certification successfully for account: " + account);
}).catch(function(e) {
  // on error set status
  console.log(e);
  self.setStatus("Error sending certification; see log.");
});
 }, 

Ich habe erwartet, dass das Ergebnis die von mir festgelegte numCerts-Variable ist, die sich pro hinzugefügtem Vertrag erhöht. Es wurde jedoch das vollständige Transaktionsergebnis zurückgegeben, aber das ist in Ordnung. Mein Problem ist, dass Remix dieses Transaktionsergebnis zurückgibt:

tx auf Remix

Beachten Sie, wie es auch die Protokolle speichert, die ich in dieser Transaktion habe.

Wenn ich den obigen Code verwende, um Zertifizierungen lokal hinzuzufügen, ist dies das Ergebnis, das ich zurückbekomme:

tx lokale Bereitstellung

Wenn ich diesen Vertrag daher auf Remix bereitstelle und die Funktionen „getCertArrayLength“ und „getNumCert“ ausführe, gibt er den richtigen Wert zurück: Er wird jedes Mal erhöht, wenn ein Vertrag hinzugefügt wird. Lokal bleiben diese Werte jedoch 0, obwohl ich ein Ergebnis von Truffle zurückbekomme, das besagt, dass mein Vertrag erfolgreich auf der Blockchain bereitgestellt wurde.

Ich habe zwei Hauptverwirrungen damit

1) Gibt es einen Grund, warum mein Protokollarray für die lokale Entwicklung jedes Mal leer ist?

2) Gibt es einen Unterschied, wie remix die Funktionen des Vertrags aufruft und wie ich ihn in Javascript aufrufe?

Vielen Dank im Voraus für Ihre Hilfe

Antworten (1)

Q1. Einfach zu viel Code.

Q2. Ja, es gibt einen Unterschied.

Diese Linie:

return meta.sendCert(account, firstName, lastName, certName, institution, description, tempDate.getFullYear(), tempDate.getMonth()+1, tempDate.getDay(), {from: account});
}).then(function(result) {

Die Welt könnte damit mehr Sinn ergeben:

then(function(txn) { ...

Wenn Sie eine Transaktion senden, erhalten Sie nicht das Ergebnis, sondern die Transaktion .

Wenn Sie die Antwort wie Remix-Shows wünschen, fügen Sie hinzu.call()

meta.sendCert.call(...

Dies gibt das Ergebnis einer lokalen Berechnung auf der lokalen Kopie der Kette zurück. Es gibt einen Haken. Es ist eine schreibgeschützte Transaktionsprobe. Der Status ändert sich nicht, aber Sie sehen die Antwort.

Also ändern wir entweder den Status und sehen die Transaktion, aber nicht das Ergebnis, oder wir können die Antwort sehen, aber sie bleibt nicht erhalten und ist bei der nächsten Überprüfung nicht vorhanden. Unangenehm.

Es gibt mehr als einen Weg, dies anzugehen. Remix macht .callzuerst und dann wirklich. Es ist vielleicht nicht klug, das nachzuahmen. Wenn mehrere Transaktionen im Gange sind, entspricht das tatsächliche Ergebnis nicht unbedingt dem, was bei der Probe vorhergesagt wurde. Aus diesem Grund bevorzuge ich es normalerweise, eine Transaktion zu senden und dann Getter zu inspizieren (für Tests) oder die Transaktionsprotokolle abzuhören, um Ergebnisse zu entdecken (für Clients).

Ich hoffe es hilft.

Danke für deinen Rat! Als ich mit den oben genannten Gettern getNumberOfCertsund dergleichen nachsah, gaben sie alle 0 zurück, was darauf hindeutet, dass die Anzahl der Zertifizierungen nicht aktualisiert wurde (obwohl die Zertifizierung gesendet und die Kette anscheinend aktualisiert wurde). Das ist mir seltsam, da sie auf Remix aktualisiert werden und den richtigen Wert zurückgeben. Ich verwende .calldiese Methoden, da dies ebenfalls schreibgeschützt ist.