Вопрос про транзации Etherium (чтение данных, измененных транзакцией)
От: Lonely Dog Россия  
Дата: 30.10.18 17:24
Оценка:
Привет всем!

Изучаю etherium и solidity, пишу всякие тестовые контракты и не могу понять следующую вещь. Пусть у меня в контракте есть функция:

uint value;
function setValue(uint newValue) public {
  value = newValue;
}

function getValue() public view returns(uint) {
  return value;
}


Контракт задеплоен в geth через truffle. Еще есть клиент на node.js (использующий web3.js). Вызвал я из него setValue. Это ведь транзакция (т.к. изменяет состояние контракта) и выполняется асинхронно. Т.е. когда-нибудь будет замайнена. И я так понимаю, value будет обновлено после этого. Т.е. возможна ситуация, когда вызов getValue вернет старое значение? Если да, то как с этим бороться?

У меня поведение странное. Если я деплою контракт в truffle develop, и в консоли вызываю setValue, потом getValue, я получаю правильное значение. Если же вызываю из JS, то получаю старое значение. Т.е. похоже на то, что я описал выше. Но ведь это бред...

Ладно, ок. Пускай у нас будет другой контракт, скажем вот такой:

uint value = 0;
function init(uint newValue) public {
  value = newValue;
}

function doIt() public  {
  require(value > 0);
  value = value / 2;
}


Здесь то все еще веселее. Вызвал я init(1), транзакция ушла. Но пока она не замайнилась, я не смогу вызвать doIt (т.к. контракт хранит старое значение).

Коллеги, объясните плиз. Или может есть хороший гайд, который это проясняет?

Спасибо
Re: Вопрос про транзации Etherium (чтение данных, измененных транзакцией)
От: vmpire Россия  
Дата: 14.11.18 08:46
Оценка: 6 (1)
Здравствуйте, Lonely Dog, Вы писали:


LD>Контракт задеплоен в geth через truffle. Еще есть клиент на node.js (использующий web3.js). Вызвал я из него setValue. Это ведь транзакция (т.к. изменяет состояние контракта) и выполняется асинхронно. Т.е. когда-нибудь будет замайнена. И я так понимаю, value будет обновлено после этого. Т.е. возможна ситуация, когда вызов getValue вернет старое значение? Если да, то как с этим бороться?

Никак с этим не надо бороться, именно так блокчейн и работает. Ждите в клиенте, пока транзакция не выполнится.

LD>У меня поведение странное. Если я деплою контракт в truffle develop, и в консоли вызываю setValue, потом getValue, я получаю правильное значение. Если же вызываю из JS, то получаю старое значение. Т.е. похоже на то, что я описал выше. Но ведь это бред...

Вы при этом коннектитесь к одной и той же ноде? truffle использует свою тестовую ноду, но может и к другой коннектится. Если JS коннектится к geth, а truffle к своей тестовой ноде, то такое поведение впаолне понятно.

LD>Ладно, ок. Пускай у нас будет другой контракт, скажем вот такой:

...
LD>Здесь то все еще веселее. Вызвал я init(1), транзакция ушла. Но пока она не замайнилась, я не смогу вызвать doIt (т.к. контракт хранит старое значение).
Здесь, похоже, то же самое. Транзакция с init ещё не прошла.
Re[2]: Вопрос про транзации Etherium (чтение данных, измененных транзакцией)
От: Lonely Dog Россия  
Дата: 14.11.18 11:24
Оценка:
Здравствуйте, vmpire, Вы писали:

V>Здравствуйте, Lonely Dog, Вы писали:



LD>>Контракт задеплоен в geth через truffle. Еще есть клиент на node.js (использующий web3.js). Вызвал я из него setValue. Это ведь транзакция (т.к. изменяет состояние контракта) и выполняется асинхронно. Т.е. когда-нибудь будет замайнена. И я так понимаю, value будет обновлено после этого. Т.е. возможна ситуация, когда вызов getValue вернет старое значение? Если да, то как с этим бороться?

V>Никак с этим не надо бороться, именно так блокчейн и работает. Ждите в клиенте, пока транзакция не выполнится.
А как лучше делать это самое ожидание? Причем желательно понимать, что транзакция успешно выполнилась (а завершилась с ошибкой из-за исключения, скажем не выполнено условие в require)

LD>>У меня поведение странное. Если я деплою контракт в truffle develop, и в консоли вызываю setValue, потом getValue, я получаю правильное значение. Если же вызываю из JS, то получаю старое значение. Т.е. похоже на то, что я описал выше. Но ведь это бред...

V>Вы при этом коннектитесь к одной и той же ноде? truffle использует свою тестовую ноду, но может и к другой коннектится. Если JS коннектится к geth, а truffle к своей тестовой ноде, то такое поведение впаолне понятно.
нет, truffle конектился к geth (не к тестовой ноде)
Re[3]: Вопрос про транзации Etherium (чтение данных, измененных транзакцией)
От: vmpire Россия  
Дата: 15.11.18 09:49
Оценка:
Здравствуйте, Lonely Dog, Вы писали:

LD>>>Контракт задеплоен в geth через truffle. Еще есть клиент на node.js (использующий web3.js). Вызвал я из него setValue. Это ведь транзакция (т.к. изменяет состояние контракта) и выполняется асинхронно. Т.е. когда-нибудь будет замайнена. И я так понимаю, value будет обновлено после этого. Т.е. возможна ситуация, когда вызов getValue вернет старое значение? Если да, то как с этим бороться?

V>>Никак с этим не надо бороться, именно так блокчейн и работает. Ждите в клиенте, пока транзакция не выполнится.
LD>А как лучше делать это самое ожидание? Причем желательно понимать, что транзакция успешно выполнилась (а завершилась с ошибкой из-за исключения, скажем не выполнено условие в require)
В API есть метод проверки состояния транзакции, можно его периодически дёргать (getTransactionReceipt вроде бы в эфире).
В некоторых блокчейнах (не знаю точно про эфир) есть ещё евенты о смене состояния реестра, но на 100% полагаться на них не стоит, лучше совмещать с опросом.

LD>>>У меня поведение странное. Если я деплою контракт в truffle develop, и в консоли вызываю setValue, потом getValue, я получаю правильное значение. Если же вызываю из JS, то получаю старое значение. Т.е. похоже на то, что я описал выше. Но ведь это бред...

V>>Вы при этом коннектитесь к одной и той же ноде? truffle использует свою тестовую ноду, но может и к другой коннектится. Если JS коннектится к geth, а truffle к своей тестовой ноде, то такое поведение впаолне понятно.
LD>нет, truffle конектился к geth (не к тестовой ноде)
Тогда этот момент не понятен. Если реестр один и тот же. то и состояние транзакции должно быть одно и то же.
Что-то всё-таки различается.
Нет под рукой рабочего инстанса, проверьте, может в логах ноды есть (или можно включить) показ запросов от клиентов.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.