Переменная состояния солидности сбрасывается в значение по умолчанию внутри функции

Для этого проекта я пишу умные контракты для Ethereum, используя Solidity.

В следующем коде переменная numCertificates должна изначально иметь значение 1. Тем не менее, newCertificateId равен 0 при назначении. Согласно отладчику (я использую remix.ethereum.org), по какой-то причине numCertificates становится равным 0, как только достигается строка, которой назначен newCertificateId.

Я много играл с ремиксом, и, согласно ему, numCertificates равен 1, пока не будет достигнута вышеупомянутая строка. Кроме того, я думаю, что если я изменю numCertificates в другой функции, переменная останется такой же, как и раньше.

Мои попытки выяснить это заставили меня поверить, что когда я получаю доступ к numCertificates, я обращаюсь не к общедоступной переменной состояния, а к чему-то еще.

Почему этот код имеет эту проблему и как ее можно решить?

 pragma solidity ^0.4.21; contract MyToken { struct Certificate { uint64 certificateId; uint64 meterId; uint32 timestamp; uint48 value; address[] owners; mapping (address => uint48) ownershipSplit; bool burned; } mapping (uint64 => Certificate) public certificates; uint64 numCertificates = 1; function MyToken() public { // ... irrelevant stuff } function produceCertificate( uint64 meterId, uint32 timestamp, uint48 value, address owner ) public { // Create the certificate in memory numCertificates;// only for debbuging Certificate storage newCertificate = constructCertificate(meterId, timestamp, carbonMitigationValue, owner); uint64 newCertificateId = numCertificates; newCertificate.certificateId = newCertificateId; // Save the certificate certificates[newCertificateId] = newCertificate; numCertificates++; } function constructCertificate( uint64 meterId, uint32 timestamp, uint48 value, address owner ) internal returns (Certificate storage newCertificate) { newCertificate.meterId = meterId; newCertificate.timestamp = timestamp; newCertificate.value = value; newCertificate.owners.push(owner); newCertificate.ownershipSplit[owner] = value; newCertificate.burned = false; // by default new certificates are fresh return newCertificate; } } 
Здесь сложно помочь, потому что ваш код неполон и невозможно воспроизвести проблему.
@Jaime Выложенный код воспроизводит проблему
Нет, структура сертификата не определена
@ Jaime Мой плохой, ты прав, добавив детали прямо сейчас
@Jaime Я добавил параметры yieldCertificate и структуру Certificate

Ответы (1)

Кажется, проблема заключается в том, как вы используете систему хранения. Я не могу понять, на что вы указываете, когда вы используете:

 Certificate storage newCertificate = constructCertificate(meterId, timestamp, Value, owner); 

Я изменил ваш код на это:

 pragma solidity ^0.4.21; contract MyToken { struct Certificate { uint64 certificateId; uint64 meterId; uint32 timestamp; uint48 value; address[] owners; mapping (address => uint48) ownershipSplit; bool burned; } mapping (uint64 => Certificate) public certificates; uint64 public numCertificates = 1; function MyToken() public { // ... irrelevant stuff } function produceCertificate( uint64 meterId, uint32 timestamp, uint48 value, address owner ) public { // Create the certificate in memory //numCertificates;// only for debbuging Certificate storage newCertificate = certificates[numCertificates]; newCertificate.meterId = meterId; newCertificate.timestamp = timestamp; newCertificate.value = value; newCertificate.owners.push(owner); newCertificate.ownershipSplit[owner] = value; newCertificate.burned = false; // by default new certificates are fresh newCertificate.certificateId = numCertificates; numCertificates= numCertificates +1; } } 

В этом коде вы определяете указатель на структуру, которая является отображением, в положении, указанном в numCertificates (который фактически является идентификатором нового сертификата).

Следовательно, изменения в newCertficate фактически являются изменениями, внесенными в certificates[numCertificates] напрямую.

Обратите внимание, что я удалил функцию produceCertificate для простоты.

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

Спасибо. Знаете ли вы, почему неинициализированный указатель хранилища вызывает проблемы?
возможно, позиции в памяти переменных в структуре пересекались с переменными, которые вы определили изначально.