Jaga-Jaga (OP)
|
|
October 24, 2017, 07:42:59 PM |
|
pragma solidity ^0.4.0;
contract Doubler {
address public owner;
address public lastGamer;
uint public constant GAME_PRICE = 10 * 10 **15;
uint public constant DOUBLE_AMOUNT = GAME_PRICE * 2;
function Doubler() payablee public {
owner = msg.sender; }
function () payablee public { lastGamer = msg.sender;//LINE1 require(msg.value >= GAME_PRICE);//LINE2 lastGamer.send(DOUBLE_AMOUNT);//LINE3 } }
Дедал примитивный даблер и обнаружил возможную проблему: Предположим приходит платеж на контракт и контракт сохраняет адрес отправителя в переменную(//LINE1) и выполняет проверку(//LINE2), а в это время приходит другой платеж и что тогда? адрес предыдущего отправителя будет перезаписан(//LINE1) и после этого дважды выплату получит второй отправитель(//LINE3) Конечно строки //LINE1 и //LINE2 надо поменять местами, но это не даст 100% гарантии защиты целостности данных. Неужели разработчики solidity ничего не предусмотрели для предотвращения подобных случаев?
|
|
|
|
uProRock
Newbie
Offline
Activity: 25
Merit: 0
|
|
October 30, 2017, 11:06:02 AM |
|
Разве может за такое малое время прийти новый платеж? Возможно, в таком случае, стоит отказаться от function() в пользу обычной функции?
|
|
|
|
Mishman
Newbie
Offline
Activity: 21
Merit: 0
|
|
October 30, 2017, 11:50:30 AM |
|
Да, как было отмечено, лучше отказаться от использования function(). Вопрос интересный, но есть большие подозрения, что это так не работает) Всегда можно протестировать.
|
|
|
|
Mishman
Newbie
Offline
Activity: 21
Merit: 0
|
|
October 30, 2017, 05:03:47 PM |
|
Кстати, если ты уверен, что такая ситуация возможна, то можно попробовать перестраховаться с помощью require, типо: address addr = msg.sender; require(addr == msg.sender); А затем уже делать какие-то действия. В случае выполнения условия, последующий код не выполнится. Но вообще, по идее, вызовы функций двумя разными адресами - две разные транзакции.
|
|
|
|
Jaga-Jaga (OP)
|
|
October 30, 2017, 09:00:30 PM |
|
Разве может за такое малое время прийти новый платеж? Возможно, в таком случае, стоит отказаться от function() в пользу обычной функции?
Ну, теоретически это же возможно поэтому надо предусмотреть такой вариант событий. Представьте что такую лотерею рекламируют по телевизору и в этот момент несколько тысяч игроков решает испытать судьбу и случается такой казус. А если еще нода будет сильно загружена то это еще больше усугубит ситуацию.
|
|
|
|
uProRock
Newbie
Offline
Activity: 25
Merit: 0
|
|
October 31, 2017, 09:29:28 AM |
|
По-хорошему от LINE1 можно избавиться вообще. Я, честно говоря, не понимаю как такое может быть теоретически возможно. Если транзакции будут в пределах одного блока то они, наверняка, выполнятся последовательно, а локальные переменные одного инстанса функции будут в любом случае изолированы от всего остального.
|
|
|
|
Mishman
Newbie
Offline
Activity: 21
Merit: 0
|
|
October 31, 2017, 09:30:46 AM |
|
На самом деле выглядит немного диковато) Мне тяжело сообразить как можно вызвать функцию и получить доступ к её локальным переменным во время её выполнения) Другое дело, что в зависимости от вызываемых функций контракта могут изменяться публичные переменные самого контракта. Пожалуй, здесь стоит прояснить сам принцип вызова и исполнения функций смарт-контракта в сети.
|
|
|
|
uProRock
Newbie
Offline
Activity: 25
Merit: 0
|
|
October 31, 2017, 09:36:57 AM |
|
Кстати, да, наверняка в Yellowpaper есть точный ответ на наши догадки - стоит посмотреть там.
|
|
|
|
Jaga-Jaga (OP)
|
|
October 31, 2017, 10:20:49 PM |
|
На самом деле выглядит немного диковато) Мне тяжело сообразить как можно вызвать функцию и получить доступ к её локальным переменным во время её выполнения) Другое дело, что в зависимости от вызываемых функций контракта могут изменяться публичные переменные самого контракта. Пожалуй, здесь стоит прояснить сам принцип вызова и исполнения функций смарт-контракта в сети.
Кстати вероятность изменения публичных переменных мне кажется что гораздо больше чем локальных, хотелось бы разобраться в этом вопросе прежде чем заниматься серьезным проектом на солидити. uProRock, можете дать ссылку на Yellowpaper, это оно? https://ethereum.github.io/yellowpaper/paper.pdf я что то не вижу чтобы там было что то про синхронизацию.
|
|
|
|
uProRock
Newbie
Offline
Activity: 25
Merit: 0
|
|
November 01, 2017, 04:18:05 PM |
|
Да, это оно, там математически строго описано то, как и в каком порядке транзакции выполняются, раздел 4.2. У Вас вопрос именно про это и это, если говорить точно, синхронизацией не является, это просто последовательность выполнения.
|
|
|
|
ivi.jones
Newbie
Offline
Activity: 6
Merit: 0
|
|
November 01, 2017, 06:06:01 PM |
|
Ребят, ну вы чего? Транзакции в эфире проходят последовательно. Не может быть такой ситуации, что "а в это время приходит другой платеж".
|
|
|
|
Mishman
Newbie
Offline
Activity: 21
Merit: 0
|
|
November 01, 2017, 07:56:48 PM |
|
Ну, вроде ясно теперь!)
|
|
|
|
Jaga-Jaga (OP)
|
|
November 04, 2017, 02:08:00 PM |
|
Ребят, ну вы чего? Транзакции в эфире проходят последовательно. Не может быть такой ситуации, что "а в это время приходит другой платеж".
В блокЧЕЙН транзакции пишутся последовательно врядли кто с этим будет спорить, надо понять в какой момент срабатывает вызов функции function () payablee public {} и может ли так случиться что две(или несколько) разные ноды начнут параллельно вызывать один и тот же метод но с параметрами от разных транзакций? Если смарт контракт всегда выполняется одной нодой то по идее проблемы быть не должно.
|
|
|
|
uProRock
Newbie
Offline
Activity: 25
Merit: 0
|
|
November 06, 2017, 01:43:54 PM |
|
По крайней мере в mist мы видим именно так, деплой контракта последовательно подтверждается на 12 узлах с равной скоростью для каждого узла.
|
|
|
|
yokotoka
Member
Offline
Activity: 126
Merit: 23
|
|
November 08, 2017, 12:29:30 PM |
|
А разве Виталики не предусмотрели борьбу с подобными гонками? Ведь не может же оказаться внутри payable-функции msg.sender левым адресом, или только последним, если функцию позвали несколько контрактов в рамках одного блока. Должно выполниться и записаться цепочкой.
|
|
|
|
amaclin1
|
|
November 08, 2017, 02:35:36 PM |
|
Ребят, ну вы чего? Транзакции в эфире проходят последовательно. Не может быть такой ситуации, что "а в это время приходит другой платеж".
В блокЧЕЙН транзакции пишутся последовательно врядли кто с этим будет спорить, надо понять в какой момент срабатывает вызов функции function () payablee public {} и может ли так случиться что две(или несколько) разные ноды начнут параллельно вызывать один и тот же метод но с параметрами от разных транзакций? Если смарт контракт всегда выполняется одной нодой то по идее проблемы быть не должно. Не путайте жопу с пальцем. Контракты исполняются каждой нодой последовательно от первой транзакции в блоке до последней. То что нода А выполняет транзакции блока 100000, а нода Б в то же самое время выполняет транзакции блока 50000 (то есть пока еще не синхронизировалась) вообще никого не колышет. У каждой ноды своё собственное состояниеи друг с другом ноды не интерферируют (то есть не вмешиваются в дела друг друга как могут вмешиваться параллельные процессы на одном компьютере - один процесс срет другому в память) Система блокчейна гарантирует, что если у двух нод одна и та же цепочка блоков (ну то есть грубо говоря одна и та же высота блокчейна)- то и состояние у них будет побайтно одинаковое. Вне зависимости от того как и когда они синхронизировались
|
|
|
|
Jaga-Jaga (OP)
|
|
November 12, 2017, 09:18:13 PM |
|
Ребят, ну вы чего? Транзакции в эфире проходят последовательно. Не может быть такой ситуации, что "а в это время приходит другой платеж".
В блокЧЕЙН транзакции пишутся последовательно врядли кто с этим будет спорить, надо понять в какой момент срабатывает вызов функции function () payablee public {} и может ли так случиться что две(или несколько) разные ноды начнут параллельно вызывать один и тот же метод но с параметрами от разных транзакций? Если смарт контракт всегда выполняется одной нодой то по идее проблемы быть не должно. Не путайте жопу с пальцем. Контракты исполняются каждой нодой последовательно от первой транзакции в блоке до последней. То что нода А выполняет транзакции блока 100000, а нода Б в то же самое время выполняет транзакции блока 50000 (то есть пока еще не синхронизировалась) вообще никого не колышет. У каждой ноды своё собственное состояниеи друг с другом ноды не интерферируют (то есть не вмешиваются в дела друг друга как могут вмешиваться параллельные процессы на одном компьютере - один процесс срет другому в память) Система блокчейна гарантирует, что если у двух нод одна и та же цепочка блоков (ну то есть грубо говоря одна и та же высота блокчейна)- то и состояние у них будет побайтно одинаковое. Вне зависимости от того как и когда они синхронизировались А как исполняются смарт контракты на эфире, как выбирается нода где будет исполняться смарт контракт?
|
|
|
|
amaclin1
|
|
November 12, 2017, 09:36:35 PM |
|
А как исполняются смарт контракты на эфире, как выбирается нода где будет исполняться смарт контракт? Каждая нода имеет "состояние базы" Для биткойна база - это только балансы на неизрасходованных выходах, для эфира это несколько больше информации. Когда нода получает блок - она выполняет код в каждой транзакции. Код меняет состояние базы. Если все скрипты отработали успешно - мы этот блок дописываем в блокчейн. Если не отработали - это невалидный блок. Таким образом если у ноды А миллион блоков в блокчейне и у ноды Б миллион блоков в блокчейне, то и состояние базы у них побайтно одинаковое. Так что ответ на твой вопрос: каждая нода выполняет каждый контракт в блоке. А если транзакция не в блоке - то она и не учитывается никем по сути. Она "еще не выполнилась"
|
|
|
|
Jaga-Jaga (OP)
|
|
November 13, 2017, 07:24:50 PM |
|
Так что ответ на твой вопрос: каждая нода выполняет каждый контракт в блоке. А если транзакция не в блоке - то она и не учитывается никем по сути. Она "еще не выполнилась"
Хорошо, спрошу по другому, например в определенный очень короткий промежуток времени приходит N транзакций на адрес смарт контракта и все эти транзакции помещаются в один блок то что будет со смарт контрактом, он как будет исполняться 1 процессом(потоком) или разные транзакции будут в разных потоках параллельно вызывать фаллбэк функцию?
|
|
|
|
amaclin1
|
|
November 13, 2017, 07:45:35 PM |
|
Хорошо, спрошу по другому, например в определенный очень короткий промежуток времени приходит N транзакций на адрес смарт контракта Да похеру когда они пришли. Одна вчера, вторая сегодня. Попали в один блок. К вам на комп они попадут вообще завтра, когда вы комп включите и синхронизацию запустите и все эти транзакции помещаются в один блок то что будет со смарт контрактом, он как будет исполняться 1 процессом(потоком) Одним процессом выполняются все контракты в блоке, причем по очереди от первой транзакции в блоке до последней или разные транзакции будут в разных потоках параллельно вызывать фаллбэк функцию? Последовательно. Зачем же какой-то параллелизм запускать там где он ни к селу, ни к городу? Впрочем, я тут сейчас выступаю с точки зрения "здравого смысла". Как там Виталя свою VM организовал - смотрите сами в коде. По идее, правильных вариантов у него есть один - тот что я объяснил. А как на самом деле - смотрите, проверяйте.
|
|
|
|
|