Контракт работает над ремиксом, но не с трюфелем

У меня есть простой контракт на сертификацию, который отправляет сертификацию в блокчейн. Это полный контракт:

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

С трюфелем я отправляю контракт так:

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.");
});
 }, 

Я ожидал, что результатом будет установленная мной переменная numCerts, которая увеличивается на добавленные контракты. Однако он вернул полный результат транзакции, но это нормально. Моя проблема в том, что в Remix он возвращает этот результат транзакции:

TX на ремикс

Обратите внимание, как он хранит журналы, которые у меня есть в этой транзакции.

Когда я использую приведенный выше код для локального добавления сертификатов, я получаю следующий результат:

локальное развертывание tx

следовательно, когда я развертываю этот контракт в Remix и запускаю функции «getCertArrayLength» и «getNumCert», он возвращает правильное значение: оно увеличивается каждый раз, когда добавляется контракт. Однако локально эти значения остаются равными 0, даже несмотря на то, что я получаю результат от трюфеля, в котором говорится, что мой контракт был успешно развернут в цепочке блоков.

У меня есть две основные путаницы с этим

1) есть ли причина, по которой мой массив журналов при локальной разработке каждый раз пуст?

2) есть ли разница в том, как ремикс вызывает функции контракта и как я вызываю его в javascript?

Заранее спасибо за вашу помощь

Ответы (1)

Q1. Просто слишком много кода.

Q2. Да, есть разница.

Эта строка:

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

Мир может иметь больше смысла с этим:

then(function(txn) { ...

Когда вы отправляете транзакцию, вы не получаете результат, вы получаете транзакцию .

Если вы хотите получить ответ, как показывает Remix, добавьте.call()

meta.sendCert.call(...

Это вернет результат локального вычисления в локальной копии цепочки. Есть подвох. Это репетиция транзакции только для чтения. Он не меняет состояние, но вы увидите ответ.

Таким образом, мы либо меняем состояние и видим транзакцию, но не результат, либо видим ответ, но он не фиксируется и его не будет в следующий раз, когда мы проверим. Неуклюжий.

Есть несколько способов приблизиться к этому. Ремикс .callсначала делает, а потом делает по-настоящему. Возможно, было бы неразумно подражать этому. Когда выполняется несколько транзакций, фактический результат не обязательно будет таким, как предсказывала репетиция. Вот почему я обычно предпочитаю отправлять транзакцию, а затем проверять геттеры (для тестов) или прослушивать журналы транзакций, чтобы обнаружить результаты (для клиентов).

Надеюсь, поможет.

Спасибо за ваш совет! Когда я проверил использование геттеров выше getNumberOfCertsи т. д., все они вернули 0, предполагая, что количество сертификатов не обновлялось (даже несмотря на то, что сертификат был отправлен, и цепочка, по-видимому, обновилась). Это странно для меня, так как они обновляются в Remix и возвращают правильное значение. Я использую .callэти методы, так как они также доступны только для чтения.