Изучаю 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 (чтение данных, измененных транзакцией)
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 (чтение данных, измененных транзакцией)
Здравствуйте, 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 (чтение данных, измененных транзакцией)
Здравствуйте, 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 (не к тестовой ноде)
Тогда этот момент не понятен. Если реестр один и тот же. то и состояние транзакции должно быть одно и то же.
Что-то всё-таки различается.
Нет под рукой рабочего инстанса, проверьте, может в логах ноды есть (или можно включить) показ запросов от клиентов.