<commit_before><!DOCTYPE html>
<html>
<head>
<title>IOTA - как работает криптовалюта для интернета вещей.</title>
<meta  charset="utf-8">
<meta  name="generator" content="Org-mode">
<meta  name="author" content="rigidus">
<link href="/css/style.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="content">
<h1 class="title">IOTA - как работает криптовалюта для интернета вещей.</h1>
<div id="table-of-contents">
<h2>Table of Contents</h2>
<div id="text-table-of-contents">
<ul>
<li><a href="#unnumbered-1">Как работает IOTA</a>
<ul>
<li><a href="#unnumbered-2">Граф транзакций и их подтверждения</a></li>
<li><a href="#unnumbered-3">Предотвращение Double spending</a></li>
<li><a href="#unnumbered-4">Сетевой протокол</a></li>
</ul>
</li>
<li><a href="#unnumbered-5">Сценарии атак</a>
<ul>
<li><a href="#unnumbered-6">Broken tangle</a></li>
<li><a href="#unnumbered-7">Double spending</a></li>
<li><a href="#unnumbered-8">Стабильность</a></li>
</ul>
</li>
<li><a href="#unnumbered-9">Возможные расширения</a>
<ul>
<li><a href="#unnumbered-10">Увеличение количества подтверждений</a></li>
<li><a href="#unnumbered-11">Гарантированное подтверждение</a></li>
</ul>
</li>
<li><a href="#unnumbered-12">Ссылки</a></li>
<li><a href="#unnumbered-13">Критика</a></li>
<li><a href="#unnumbered-14">Вопросы</a></li>
<li><a href="#unnumbered-15">Транзакция</a></li>
</ul>
</div>
</div>

<div id="outline-container-unnumbered-1" class="outline-2">
<h2 id="unnumbered-1">Как работает IOTA</h2>
<div class="outline-text-2" id="text-unnumbered-1">
<p>
IOTA - криптовалюта для интернета вещей. Базовой структурой является, так называемый
<code>tangle</code> - вариант направленного ациклического графа (DAG). Несмотря на то, что "tangle"
означает "клубок", структурно это скорее похоже на связаный шарф.
</p>

<p>
Сеть позиционируется как легковесное решение для устройств, ограниченных в
вычислительной мощности и энергопотреблении.
</p>

<p>
Порядок транзакций не имеет значения, потому что итоговый баланс от него не
зависит. Это улучшает количество транзакций в секунду, которое может быть обработано.
</p>

<p>
Сеть является асинхронной, ноды не обязательно видят один и тот же набор транзакций.
</p>

<p>
Эмиссия отсутствует, все монеты были созданы в первой транзакции. По сценарию в первых
транзакциях они распределяются среди инвесторов.
</p>
</div>

<div id="outline-container-unnumbered-2" class="outline-3">
<h3 id="unnumbered-2">Граф транзакций и их подтверждения</h3>
<div class="outline-text-3" id="text-unnumbered-2">
<p>
Каждый узел (vertex) представляет собой транзакцию, каждое ребро является направленным,
и представляет собой ссылку на хэш ранее созданной транзакции.
</p>

<p>
Из одного вертекса может быть не более двух ссылок на предыдущие транзакции. Очевидно,
первый вертекс не может иметь предшественников, а второй имеет только одного. Первый
вертекс может иметь в полях ссылок нули или ссылаться сам не себя, вертексы, которые
имеют одну ссылку на предшественника помещают хэш этого предшественника в оба ссылочных
поля.
</p>

<p>
Вертексы, на которые есть ссылки называются <code>sites</code>, чтобы не путать их с
<code>nodes</code>. <code>Node</code> - это узел сети (не графа) - устройство, которое посылает и принимает
данные.
</p>

<p>
В момент создания транзакции нода должна сделать три вещи:
</p>
<ul class="org-ul">
<li>Выбрать две других уже созданных транзакции, которые она будет подверждать,
руководствуясь алгоритмом, о котором ниже
</li>
<li>Проверить их, убедиться что они валидные, чтобы не подтверждать невалидных транзакций
</li>
<li>Решить криптографический пазл найдя такой nonce чтобы хэш транзакции с ним содержал
некоторое количество ведущих нулей.
</li>
</ul>

<p>
Узлы, на которые нет ссылок, называются оконечными (<code>tips</code>). Когда новая транзакция
создается, из множества известных узлов выбираются те, хэш которых будет помещен в её
ссылочное поле
</p>

<p>
В каждый момент времени по крайней мере один <code>tip</code> будет существовать, поэтому если
новые транзакции приходят редко, то <code>tangle</code> вырождается в <code>chain</code>, т.е. каждая
следующая транзакция подтверждает только одну предыдущую.
</p>

<p>
<div class="figure"><img src="/img/iota-chain.png" alt="nil"/><p></p></div>
</p>

<p>
Напротив, если множество транзакций приходят одномоментно, то все они будут ссылаться
на один доступный <code>tip</code>, что выглядит как "одуванчик", где этот <code>tip</code> в центре.
</p>

<p>
<div class="figure"><img src="/img/iota-star.png" alt="nil"/><p></p></div>
</p>

<p>
Так как каждый узел при создании захватывает два оконечных узла (если может),
предполагается тенденция уменьшения кол-ва свободных оконечных узлов - в пределе до
одного.
</p>

<p>
В момент создания транзакции необходимо выбрать среди известных узлов те, которые будут
подтверждаться. Можно было бы выбирать случайно, но есть более интересный алгоритм,
который называется <code>unweighted random walk</code>
</p>

<p>
Его суть в следующем: мы помещаем "курсор" в genesis-транзакцию и на каждом шаге он
переходит на одну из транзакций, которая апрувит ту, где он сейчас находится. Если
таких транзакций несколько, то выбор одной из них происходит случайным образом.
</p>

<p>
<div class="figure"><img src="/img/unweighted-random-walk.gif" alt="nil"/><p></p></div>
</p>

<p>
Таким образом, благодаря этому механизму, последние транзакции связываются с
предпоследними и получается именно "вязаный шарф".
</p>

<p>
Однако, при использовании этого алгоритма сеть не может противодействовать появлению
"ленивых оконечных узлов", <code>lazy tips</code>, которые вместо исполнения алгоритма <code>unweighted
random walk</code> просто подтверждают старые, уже много раз подтвержденные транзакции -
такой подход вычислительно дешевле, но не помогает сети, т.к. новые тразакции не
подтверждаются.
</p>

<p>
<div class="figure"><img src="/img/bad-unweighted-random-walk.png" alt="nil"/><p></p></div>
</p>

<p>
Решение состоит в том, чтобы встроить в систему стимулы против подобного поведения,
так, чтобы <code>lazy tips</code> были бы подтверждены сетью с меньшей вероятностью. Введем термин
"совокупный вес", <code>cumulative weight</code>, чтобы отразить важность транзакции. <code>Cumulative
weight</code> данного узла рассчитываестя как количество подтверждений этого узла плюс
один. В приведенном примере транзакция номер 3 имеет совокупный вес равный 5, потому
что ее подтверждают четыре синие транзакции.
</p>

<p>
<div class="figure"><img src="/img/cumulative-weight.png" alt="nil"/><p></p></div>
</p>

<p>
NB: Возможно это не совсем точно, в пейпере говорится, что совокупный вес определяется
как собственный вес конкретной транзакции плюс сумма собственных весов всех транзакций,
которые прямо или коссвено подтверждают эту транзакцию. Приводится следующая картинка,
с пояснением, что транзакцию <code>F</code> подтверждают транзакции <code>A</code>, <code>B</code>, <code>C</code>, <code>D</code>:
</p>

<p>
<div class="figure"><img src="/img/iota-cum-weight.png" alt="nil"/><p></p></div>
</p>

<p>
Совокупный вес транзакции <code>F</code>, таким образом, равен 9 (3+1+3+1+1). Правда я пока не
очень понимаю, что такое "собственный вес", но в пэйпере говорится, что можно считать
его равным единице. Когда новая транзакция <code>X</code> появляется и подтверждает <code>A</code> и <code>C</code>
(нижний рисунок), <code>X</code> становится единственным <code>tip</code>. Суммарная масса всех других
транзакций увеличивается на 3, собственный вес <code>X</code>.
</p>

<p>
В примере ниже транзакция 16 является <code>lazy tip</code>. Чтобы подтвердить её, <code>unweighted
random walk</code> должен достичь транзакции 7, а затем выбрать транзакцию 16 за
транзакцией 9. Но в модели предпочтения транзакций с большим <code>cumulative weight</code> это
врядли произойдет, потому что транзакция 16 имеет кумулятивный вес равный единице, а
транзакция 9 - кумулятивный вес равный семи. Этот механизм эффективно предотвращает
"ленивое" поведение.
</p>

<p>
<div class="figure"><img src="/img/iota-lazy-prevention.png" alt="nil"/><p></p></div>
</p>

<p>
Нужна ли нам вообще случайность? Мы можем всегда выбирать самую тяжелую транзакцию, без
каких-либо вероятностей. Но тогда мы получим множество побочных транзакций, которые
никогда не будут одобрены:
</p>

<p>
<div class="figure"><img src="/img/super-weighed-walk.png" alt="nil"/><p></p></div>
</p>

<p>
Чтобы избежать этого вводится новый параметр <code>alfa</code> который устанавливает, насколько
важен кумулятивный вес транзакции. Он влияет на вероятность выбора узла. Если <code>alfa</code>
равен нулю - мы возвращаемся к <code>unweighted random walk</code>.
</p>

<p>
<div class="figure"><img src="/img/weighted-random-walk.png" alt="nil"/><p></p></div>
</p>

<p>
Правильный выбор <code>alfa</code> - нетривиальная задача, которая решается методом Markov Chain
Monte Carlo, <code>MCMC</code>. В цепи Маркова каждый шаг не зависит от предыдущего, а следует из
заранее определенног правила.
</p>

<p>
<div class="figure"><img src="/img/mcmc.gif" alt="nil"/><p></p></div>
</p>

<p>
Когда транзакции приходят редко, после того, как транзакция будет одобрена несколько
раз, ее совокупный вес будет расти со скоростью <code>λw</code>, где <code>w</code> - средний вес транзакции,
а <code>λ</code> - скорость появления новых транзакций.
</p>

<p>
Когда транзакции приходят часто, проявляются две фазы. Во-первых, совокупный вес
транзакции растет с увеличением скорости в течение периода адаптации. По окончании
периода адаптации совокупный вес растет со скоростью <code>λw</code> (доказательство в пэйпере).
</p>

<p>
<div class="figure"><img src="/img/iota-cum-weight-adoptation-period.png" alt="nil"/><p></p></div>
</p>
</div>
</div>

<div id="outline-container-unnumbered-3" class="outline-3">
<h3 id="unnumbered-3">Предотвращение Double spending</h3>
<div class="outline-text-3" id="text-unnumbered-3">
<p>
Предотвращение <code>double-spending</code> осуществляется следующим образом:
</p>

<p>
Положим, <code>Алиса</code> имеет на балансе 5 монет и создает две транзакции, в первой из которых
пересылает их <code>Бобу</code>, а во второй - <code>Чарли</code>. В таком случае узел, который видит обе
транзакции, должен отвергнуть как минимум одну из этих транзакций, т.к. в результате
<code>Алиса</code> будет иметь отрицительный баланс.
</p>

<p>
<div class="figure"><img src="/img/iota-double-spending-base.png" alt="nil"/><p></p></div>
</p>

<p>
Если одна из транзакций будет подтверждена одним узлом, а другая - иным, то это
приведет к формированию двух ветвей, одна из которых в конечно счете должна быть
отброшена. При использовании алгоритма <code>weighted random walk</code>, со временем одна из
ветвей станет больше.
</p>

<p>
Доверие к транзакции расчитывается как процент оконечных узлов (<code>tips</code>), которые её
подтверждают. На картинке транзакции с доверием больше 95% показаны с толстой
рамкой. Так например, транзакция 9 подтверждается двумя из четырех <code>tips</code>. Если бы мы
использовали <code>random tip selection</code>, у неё было бы 50%. Тем не менее, оконечные узлы,
которые её подтверждают, по-видимому, более весомы, чем те, которые не подтверждают,
что немного повышает доверие.
</p>

<p>
<div class="figure"><img src="/img/confirmation-confidence.png" alt="nil"/><p></p></div>
</p>

<p>
Как только сделка Алисы достигает некоторого очень высокого доверительного порога,
скажем, 95%, маловероятно, что она будет вытеснена из консенсуса. Однако <code>Алиса</code> может
попытаться сформировать альтернативную ветвь в <code>tangle</code>. Для этого она должна
поддержать double spending транзакцию для <code>Чарли</code>. <code>Алисе</code> придется апрувить две старые
транзакции, которые не ссылаются на ее транзакцию с <code>Чарли</code>. Затем она начнет выдавать
как можно больше транзакций, пытаясь увеличить вес ветки с транзакцией для <code>Чарли</code>.
</p>

<p>
Если у нее будет достаточно вычислительной мощности, она может заставить сеть поверить
ей и последовать за ее веткой, однако, если мы рассчитаем уровень доверия для ветки с
транзакцией для <code>Боба</code>, то увидим, что он снизился с 95% до нуля.
</p>

<p>
<code>Боб</code> может рассчитать доверие пока оно 95% и выполнить свою часть сделки - отправить
товар или оказать услугу, а потом столкнуться с тем, что доверие изменилось - тогда
атака <code>Алисы</code> удалась.
</p>

<p>
Для зрелой и активной сети вычислительные ресурсы для реализации атаки будут слишком
дорогостоящими, но на стадии развития такая атака может быть очень вероятной. Под этим
предлогом IOTA Foundation вводит так называемый "Координатор", который является
централизованным сервером, который каждые две минуты создает <code>milestone</code>-транзакцию,
которая немедленно подтверждает все одобренные ей транзакции на 100%. Они заявляют, что
это временное решение, до тех пор, пока сеть не выйдет на достаточный уровень
мощности.
</p>
</div>
</div>

<div id="outline-container-unnumbered-4" class="outline-3">
<h3 id="unnumbered-4">Сетевой протокол</h3>
<div class="outline-text-3" id="text-unnumbered-4">
<p>
Каждая нода имеет несколько соседей о которых знает.
</p>

<p>
Каждая нода самостоятельно ведет статистику в отношении своих соседей и может исключать
из числа соседей "ленивые ноды", поэтому даже узел, который не создает новые транзакции
имеет мотивацию распространять транзакции дальше по сети.
</p>
</div>
</div>
</div>

<div id="outline-container-unnumbered-5" class="outline-2">
<h2 id="unnumbered-5">Сценарии атак</h2>
<div class="outline-text-2" id="text-unnumbered-5">
</div><div id="outline-container-unnumbered-6" class="outline-3">
<h3 id="unnumbered-6">Broken tangle</h3>
<div class="outline-text-3" id="text-unnumbered-6">
<p>
Идея состоит в том, чтобы выпустить N конфликтующих транзакций, две из которых не могут
подтвердить другие узлы в сети, эффективно разбивая tangle на N сегментов. В конце
концов один выигрывает, но все, кто отправил транзакции на отвергнутый сегмент, должны
будут повторно отправить их, и к тому времени злоумышленник мог выпустить еще один
набор конфликтных транзакций.
</p>

<p>
Цель состоит в том, чтобы предотвратить подтверждение большинства транзакций (отказ в
обслуживании)
</p>
</div>
</div>

<div id="outline-container-unnumbered-7" class="outline-3">
<h3 id="unnumbered-7">Double spending</h3>
<div class="outline-text-3" id="text-unnumbered-7">
<p>
Злоумышленник пытается опередить сеть. Общий сценарий выглядит так:
</p>
<ul class="org-ul">
<li>Злоумышленник отправляет платеж продавцу и получает товар после того, как продавец
решает, что транзакция набрала достаточно большой совокупный вес.
</li>
<li>Злоумышленник выдает double-spending транзакцию.
</li>
<li>Злоумышленник использует свою вычислительную мощность для выпуска многих небольших
транзакций, которые подтверждают double-spending транзакцию, но не подтверждают
первоначальную транзакцию. Или Злоумышленник выпускает две транзакции, одобряя
сначала одну из них, а после получения товара - вторую.
</li>
<li>Злоумышленник может иметь множество Сивилл-нод, которые не обязаны подтвержать
оконечные транзакции.
</li>
<li>Злоумышленник надеется, что его нечестный subtangle опередит честный subtangle. Если
это произойдет, tangle продолжает расти из double-spendign транзакции, а правильная
ветвь с первоначальным платежом торговцу становится "осиротевшей".
</li>
</ul>

<p>
Следующий пример иллюстрирует атаку на временную неконсистентность tangle:
</p>

<p>
Обычный узел большую часть времени получает транзакции и обменивается ими с
соседями. Он заботится о топологии графа только тогда, когда пришло время произвести
транзакцию или принять платеж.
</p>

<p>
<div class="figure"><img src="/img/iota-double-spending.png" alt="nil"/><p></p></div>
</p>

<p>
Сейчас 16:04, и <code>Боб</code> решает отправить транзакцию, которая ссылается на 2 транзакции:
</p>
<ul class="org-ul">
<li>1 йота на адрес <code>Алисы</code>
</li>
<li>1 йоту от адреса <code>Алисы</code>
</li>
</ul>

<p>
Это не приводит к <code>double</code> spending, поэтому в 16:07 он завершает создание транзакции.
</p>

<p>
Через 90 минут плохой парень <code>Чарли</code> решает сослаться на сделку <code>Боба</code> и другую сделку,
которая тратит 1 йоту с адреса <code>Алисы</code>
</p>

<p>
В 17:44 он завершает создание транзакции, которая ссылается на subtangle с искаженным
состоянием.
</p>

<p>
Никто из нас не заботится об этом, мы не знаем о плохом парне <code>Чарли</code>, потому что наши
узлы продолжают получать все транзакции и делиться ими.
</p>

<p>
В 19:15 хорошая девочка <code>Диана</code> решает отправить деньги своей матери, она анализирует
<code>Tangle</code> и видит, что она не должна ссылаться на транзакцию Чарли, поэтому вместо этого
ссылается на транзакцию <code>Боба</code>.
</p>

<p>
Ее транзакция не является особенной, поэтому она не показана на картинке.
</p>

<p>
Спустя несколько минут умная девушка <code>Ева</code> решает отправить сообщение своему парню. Она
тоже умна и решает потролить плохого парня <code>Чарли</code>. Она находит транзакцию, которая
посылает 1 йоту на адрес <code>Алисы</code>. Она ссылается на эту сделку, а также на сделку
<code>Чарли</code>. Мы видим сделку <code>Евы</code> в 19:21
</p>

<p>
Позже кто-то другой, производящий транзакцию, будет ссылаться на транзакцию <code>Евы</code> без
каких-либо проблем, потому что она «исправила» проблему, созданную <code>Чарли</code>.
</p>

<p>
Как мы можем видеть в этом сценарии в течение какого-то периода времени, реестр может
быть неконсистентным.
</p>
</div>
</div>

<div id="outline-container-unnumbered-8" class="outline-3">
<h3 id="unnumbered-8">Стабильность</h3>
<div class="outline-text-3" id="text-unnumbered-8">
<p>
Есть предположение, что в момент резкого увеличения объема транзакций значительное
количество <code>tips</code> может остаться неподтвержденными. Поэтому было бы интересно
смоделировать ситуацию, когда транзакции не поступают равномерно, а идут волнами -
можно предположить, что сеть в среднем хуже будет справляться с таким сценарием, что
позволяет комбинировать этот способ с другими видами атак на отказ в обслуживании.
</p>
</div>
</div>
</div>

<div id="outline-container-unnumbered-9" class="outline-2">
<h2 id="unnumbered-9">Возможные расширения</h2>
<div class="outline-text-2" id="text-unnumbered-9">
</div><div id="outline-container-unnumbered-10" class="outline-3">
<h3 id="unnumbered-10">Увеличение количества подтверждений</h3>
<div class="outline-text-3" id="text-unnumbered-10">
<p>
Технически возможно увеличить количество возможных ссылок подтверждения - например
использовать 3 вместо 2, или даже иметь неограниченное количество ссылок - тогда одна
транзакция могла бы подтвердить много более ранних транзакций.
</p>

<p>
При этом, возрастают накладные расходы на проверку путей такой транзакции, но
открываются дополнительные возможности:
</p>
<ul class="org-ul">
<li>"упорядочивающее подтверждение", которое добавляет отношение частичной
упорядоченности для подтверждаемых транзакций. Это может быть полезно в задачах
частичного подсчета состояния сети, что позволяет узлам хранить меньше данных.
</li>
<li>"чекпойнт", который позволяет фактически создавать новые genesis-узлы по запросу, что
позволяет сократить вычисление путей (для свернутых маршрутов) до последнего
genesis-элемента. Таким образом можно обеспечить высокую производительность для
узлов, которые присоединяются к сети, не деградирующую с ростом размера сети.
</li>
</ul>
</div>
</div>

<div id="outline-container-unnumbered-11" class="outline-3">
<h3 id="unnumbered-11">Гарантированное подтверждение</h3>
<div class="outline-text-3" id="text-unnumbered-11">
<p>
В процессе работы сети, какое-то количество транзакций не получают подтверждения - это
могут быть как ошибочно сформированные транзакции, так и валидные транзакции, которым
"не повезло".
</p>

<p>
Узел, который отправил такую транзакцию, заинтересован в ее подтверждении. В текущей
реализации ему предлагается отправить транзакцию еще раз, но существует возможность
находить такие валидные транзакции и подтверждать их "гарантированно" - для этого
необходимо существование особых правил для узлов, к которым можно обратиться за
гарантированным подтверждением. Такие узлы могут работать за плату и предоставлять
гарантированное подтверждение по особым правилам.
</p>
</div>
</div>
</div>

<div id="outline-container-unnumbered-12" class="outline-2">
<h2 id="unnumbered-12">Ссылки</h2>
<div class="outline-text-2" id="text-unnumbered-12">
<ul class="org-ul">
<li>whitepaper <a href="https://iota.org/IOTA_Whitepaper.pdf">https://iota.org/IOTA_Whitepaper.pdf</a>
</li>
<li>референсная реализация: <a href="https://github.com/iotaledger/iri">https://github.com/iotaledger/iri</a>
</li>
<li>демонстрашка на js: <a href="https://public-rdsdavdrpd.now.sh/">https://public-rdsdavdrpd.now.sh/</a>
</li>
<li>демонстрашка unweighted random walk: <a href="https://public-xnmzdqumwy.now.sh/">https://public-xnmzdqumwy.now.sh/</a>
</li>
<li>демонстрашка mcmc <a href="https://public-qnbiiqwyqj.now.sh/">https://public-qnbiiqwyqj.now.sh/</a>
</li>
<li>демо confirmation confidence <a href="https://public-krwdbaytsx.now.sh/">https://public-krwdbaytsx.now.sh/</a>
</li>
</ul>
</div>
</div>

<div id="outline-container-unnumbered-13" class="outline-2">
<h2 id="unnumbered-13">Критика</h2>
<div class="outline-text-2" id="text-unnumbered-13">
<ul class="org-ul">
<li><a href="https://casey.github.io/iota/">https://casey.github.io/iota/</a>
</li>
</ul>
</div>
</div>

<div id="outline-container-unnumbered-14" class="outline-2">
<h2 id="unnumbered-14">Вопросы</h2>
<div class="outline-text-2" id="text-unnumbered-14">
<ul class="org-ul">
<li>Топология сети?
</li>
<li>Протокольный уровень правило взаимодействия узлов?
</li>
<li>Как работают консенсус и валидация блоков? Кто проверяет?
</li>
<li>Механизмы хранения данных как устроены хранилища?
</li>
<li>Смарт-контракты: да, нет, другие подходы
</li>
</ul>
</div>
</div>

<div id="outline-container-unnumbered-15" class="outline-2">
<h2 id="unnumbered-15">Транзакция</h2>
<div class="outline-text-2" id="text-unnumbered-15">
<p>
Я взял кусок класса транзакции из сорцов:
</p>

<div class="org-src-container">

<pre class="src src-java"><span style="color: #af00ff;">public</span> <span style="color: #af00ff;">class</span> <span style="color: #008700;">Transaction</span> <span style="color: #af00ff;">implements</span> <span style="color: #008700;">Persistable</span> {
    <span style="color: #af00ff;">public</span> <span style="color: #af00ff;">static</span> <span style="color: #af00ff;">final</span> <span style="color: #008700;">int</span> <span style="color: #af5f00;">SIZE</span> = 1604;

    <span style="color: #af00ff;">public</span> <span style="color: #008700;">byte</span>[] <span style="color: #af5f00;">bytes</span>;

    <span style="color: #af00ff;">public</span> <span style="color: #008700;">Hash</span> <span style="color: #af5f00;">address</span>;
    <span style="color: #af00ff;">public</span> <span style="color: #008700;">Hash</span> <span style="color: #af5f00;">bundle</span>;
    <span style="color: #af00ff;">public</span> <span style="color: #008700;">Hash</span> <span style="color: #af5f00;">trunk</span>;
    <span style="color: #af00ff;">public</span> <span style="color: #008700;">Hash</span> <span style="color: #af5f00;">branch</span>;
    <span style="color: #af00ff;">public</span> <span style="color: #008700;">Hash</span> <span style="color: #af5f00;">obsoleteTag</span>;
    <span style="color: #af00ff;">public</span> <span style="color: #008700;">long</span> <span style="color: #af5f00;">value</span>;
    <span style="color: #af00ff;">public</span> <span style="color: #008700;">long</span> <span style="color: #af5f00;">currentIndex</span>;
    <span style="color: #af00ff;">public</span> <span style="color: #008700;">long</span> <span style="color: #af5f00;">lastIndex</span>;
    <span style="color: #af00ff;">public</span> <span style="color: #008700;">long</span> <span style="color: #af5f00;">timestamp</span>;

    <span style="color: #af00ff;">public</span> <span style="color: #008700;">Hash</span> <span style="color: #af5f00;">tag</span>;
    <span style="color: #af00ff;">public</span> <span style="color: #008700;">long</span> <span style="color: #af5f00;">attachmentTimestamp</span>;
    <span style="color: #af00ff;">public</span> <span style="color: #008700;">long</span> <span style="color: #af5f00;">attachmentTimestampLowerBound</span>;
    <span style="color: #af00ff;">public</span> <span style="color: #008700;">long</span> <span style="color: #af5f00;">attachmentTimestampUpperBound</span>;

    <span style="color: #af00ff;">public</span> <span style="color: #008700;">int</span> <span style="color: #af5f00;">validity</span> = 0;
    <span style="color: #af00ff;">public</span> <span style="color: #008700;">int</span> <span style="color: #af5f00;">type</span> = <span style="color: #008787;">TransactionViewModel</span>.PREFILLED_SLOT;
    <span style="color: #af00ff;">public</span> <span style="color: #008700;">long</span> <span style="color: #af5f00;">arrivalTime</span> = 0;

    <span style="color: #af0000;">//</span><span style="color: #af0000;">public boolean confirmed = false;</span>
    <span style="color: #af00ff;">public</span> <span style="color: #008700;">boolean</span> <span style="color: #af5f00;">parsed</span> = <span style="color: #008787;">false</span>;
    <span style="color: #af00ff;">public</span> <span style="color: #008700;">boolean</span> <span style="color: #af5f00;">solid</span> = <span style="color: #008787;">false</span>;
    <span style="color: #af00ff;">public</span> <span style="color: #008700;">long</span> <span style="color: #af5f00;">height</span> = 0;
    <span style="color: #af00ff;">public</span> <span style="color: #008700;">String</span> <span style="color: #af5f00;">sender</span> = <span style="color: #87005f;">""</span>;
    <span style="color: #af00ff;">public</span> <span style="color: #008700;">int</span> <span style="color: #af5f00;">snapshot</span>;

    ...
}
</pre>
</div>
</div>
</div>
</div>
</body>
</html>
<commit_msg>export<commit_after><!DOCTYPE html>
<html>
<head>
<title>IOTA - как работает криптовалюта для интернета вещей.</title>
<meta  charset="utf-8">
<meta  name="generator" content="Org-mode">
<meta  name="author" content="rigidus">
<link href="/css/style.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="content">
<h1 class="title">IOTA - как работает криптовалюта для интернета вещей.</h1>
<div id="table-of-contents">
<h2>Table of Contents</h2>
<div id="text-table-of-contents">
<ul>
<li><a href="#unnumbered-1">Как работает IOTA</a>
<ul>
<li><a href="#unnumbered-2">Граф транзакций и их подтверждения</a></li>
<li><a href="#unnumbered-3">Предотвращение Double spending</a></li>
<li><a href="#unnumbered-4">Сетевой протокол</a></li>
</ul>
</li>
<li><a href="#unnumbered-5">Сценарии атак</a>
<ul>
<li><a href="#unnumbered-6">Broken tangle</a></li>
<li><a href="#unnumbered-7">Double spending</a></li>
<li><a href="#unnumbered-8">Large weigth</a></li>
<li><a href="#unnumbered-9">Parasite chain</a></li>
<li><a href="#unnumbered-10">Resonance</a></li>
<li><a href="#unnumbered-11">Splitting</a></li>
</ul>
</li>
<li><a href="#unnumbered-12">Возможные расширения</a>
<ul>
<li><a href="#unnumbered-13">Увеличение количества подтверждений</a></li>
<li><a href="#unnumbered-14">Гарантированное подтверждение</a></li>
</ul>
</li>
<li><a href="#unnumbered-15">Ссылки</a></li>
<li><a href="#unnumbered-16">Критика</a></li>
<li><a href="#unnumbered-17">Вопросы</a></li>
<li><a href="#unnumbered-18">Транзакция</a></li>
</ul>
</div>
</div>

<div id="outline-container-unnumbered-1" class="outline-2">
<h2 id="unnumbered-1">Как работает IOTA</h2>
<div class="outline-text-2" id="text-unnumbered-1">
<p>
IOTA - криптовалюта для интернета вещей. Базовой структурой является, так называемый
<code>tangle</code> - вариант направленного ациклического графа (DAG). Несмотря на то, что "tangle"
означает "клубок", структурно это скорее похоже на связаный шарф.
</p>

<p>
Сеть позиционируется как легковесное решение для устройств, ограниченных в
вычислительной мощности и энергопотреблении.
</p>

<p>
Порядок транзакций не имеет значения, потому что итоговый баланс от него не
зависит. Это улучшает количество транзакций в секунду, которое может быть обработано.
</p>

<p>
Сеть является асинхронной, ноды не обязательно видят один и тот же набор транзакций.
</p>

<p>
Эмиссия отсутствует, все монеты были созданы в первой транзакции. По сценарию в первых
транзакциях они распределяются среди инвесторов.
</p>
</div>

<div id="outline-container-unnumbered-2" class="outline-3">
<h3 id="unnumbered-2">Граф транзакций и их подтверждения</h3>
<div class="outline-text-3" id="text-unnumbered-2">
<p>
Каждый узел (vertex) представляет собой транзакцию, каждое ребро является направленным,
и представляет собой ссылку на хэш ранее созданной транзакции.
</p>

<p>
Из одного вертекса может быть не более двух ссылок на предыдущие транзакции. Очевидно,
первый вертекс не может иметь предшественников, а второй имеет только одного. Первый
вертекс может иметь в полях ссылок нули или ссылаться сам не себя, вертексы, которые
имеют одну ссылку на предшественника помещают хэш этого предшественника в оба ссылочных
поля.
</p>

<p>
Вертексы, на которые есть ссылки называются <code>sites</code>, чтобы не путать их с
<code>nodes</code>. <code>Node</code> - это узел сети (не графа) - устройство, которое посылает и принимает
данные.
</p>

<p>
В момент создания транзакции нода должна сделать три вещи:
</p>
<ul class="org-ul">
<li>Выбрать две других уже созданных транзакции, которые она будет подверждать,
руководствуясь алгоритмом, о котором ниже
</li>
<li>Проверить их, убедиться что они валидные, чтобы не подтверждать невалидных транзакций
</li>
<li>Решить криптографический пазл найдя такой nonce чтобы хэш транзакции с ним содержал
некоторое количество ведущих нулей.
</li>
</ul>

<p>
Узлы, на которые нет ссылок, называются оконечными (<code>tips</code>). Когда новая транзакция
создается, из множества известных узлов выбираются те, хэш которых будет помещен в её
ссылочное поле
</p>

<p>
В каждый момент времени по крайней мере один <code>tip</code> будет существовать, поэтому если
новые транзакции приходят редко, то <code>tangle</code> вырождается в <code>chain</code>, т.е. каждая
следующая транзакция подтверждает только одну предыдущую.
</p>

<p>
<div class="figure"><img src="/img/iota-chain.png" alt="nil"/><p></p></div>
</p>

<p>
Напротив, если множество транзакций приходят одномоментно, то все они будут ссылаться
на один доступный <code>tip</code>, что выглядит как "одуванчик", где этот <code>tip</code> в центре.
</p>

<p>
<div class="figure"><img src="/img/iota-star.png" alt="nil"/><p></p></div>
</p>

<p>
Так как каждый узел при создании захватывает два оконечных узла (если может),
предполагается тенденция уменьшения кол-ва свободных оконечных узлов - в пределе до
одного.
</p>

<p>
В момент создания транзакции необходимо выбрать среди известных узлов те, которые будут
подтверждаться. Можно было бы выбирать случайно, но есть более интересный алгоритм,
который называется <code>unweighted random walk</code>
</p>

<p>
Его суть в следующем: мы помещаем "курсор" в genesis-транзакцию и на каждом шаге он
переходит на одну из транзакций, которая апрувит ту, где он сейчас находится. Если
таких транзакций несколько, то выбор одной из них происходит случайным образом.
</p>

<p>
<div class="figure"><img src="/img/unweighted-random-walk.gif" alt="nil"/><p></p></div>
</p>

<p>
Таким образом, благодаря этому механизму, последние транзакции связываются с
предпоследними и получается именно "вязаный шарф".
</p>

<p>
Однако, при использовании этого алгоритма сеть не может противодействовать появлению
"ленивых оконечных узлов", <code>lazy tips</code>, которые вместо исполнения алгоритма <code>unweighted
random walk</code> просто подтверждают старые, уже много раз подтвержденные транзакции -
такой подход вычислительно дешевле, но не помогает сети, т.к. новые тразакции не
подтверждаются.
</p>

<p>
<div class="figure"><img src="/img/bad-unweighted-random-walk.png" alt="nil"/><p></p></div>
</p>

<p>
Решение состоит в том, чтобы встроить в систему стимулы против подобного поведения,
так, чтобы <code>lazy tips</code> были бы подтверждены сетью с меньшей вероятностью. Введем термин
"совокупный вес", <code>cumulative weight</code>, чтобы отразить важность транзакции. <code>Cumulative
weight</code> данного узла рассчитываестя как количество подтверждений этого узла плюс
один. В приведенном примере транзакция номер 3 имеет совокупный вес равный 5, потому
что ее подтверждают четыре синие транзакции.
</p>

<p>
<div class="figure"><img src="/img/cumulative-weight.png" alt="nil"/><p></p></div>
</p>

<p>
NB: Возможно это не совсем точно, в пейпере говорится, что совокупный вес определяется
как собственный вес конкретной транзакции плюс сумма собственных весов всех транзакций,
которые прямо или коссвено подтверждают эту транзакцию. Приводится следующая картинка,
с пояснением, что транзакцию <code>F</code> подтверждают транзакции <code>A</code>, <code>B</code>, <code>C</code>, <code>D</code>:
</p>

<p>
<div class="figure"><img src="/img/iota-cum-weight.png" alt="nil"/><p></p></div>
</p>

<p>
Совокупный вес транзакции <code>F</code>, таким образом, равен 9 (3+1+3+1+1). Правда я пока не
очень понимаю, что такое "собственный вес", но в пэйпере говорится, что можно считать
его равным единице. Когда новая транзакция <code>X</code> появляется и подтверждает <code>A</code> и <code>C</code>
(нижний рисунок), <code>X</code> становится единственным <code>tip</code>. Суммарная масса всех других
транзакций увеличивается на 3, собственный вес <code>X</code>.
</p>

<p>
В примере ниже транзакция 16 является <code>lazy tip</code>. Чтобы подтвердить её, <code>unweighted
random walk</code> должен достичь транзакции 7, а затем выбрать транзакцию 16 за
транзакцией 9. Но в модели предпочтения транзакций с большим <code>cumulative weight</code> это
врядли произойдет, потому что транзакция 16 имеет кумулятивный вес равный единице, а
транзакция 9 - кумулятивный вес равный семи. Этот механизм эффективно предотвращает
"ленивое" поведение.
</p>

<p>
<div class="figure"><img src="/img/iota-lazy-prevention.png" alt="nil"/><p></p></div>
</p>

<p>
Нужна ли нам вообще случайность? Мы можем всегда выбирать самую тяжелую транзакцию, без
каких-либо вероятностей. Но тогда мы получим множество побочных транзакций, которые
никогда не будут одобрены:
</p>

<p>
<div class="figure"><img src="/img/super-weighed-walk.png" alt="nil"/><p></p></div>
</p>

<p>
Чтобы избежать этого вводится новый параметр <code>alfa</code> который устанавливает, насколько
важен кумулятивный вес транзакции. Он влияет на вероятность выбора узла. Если <code>alfa</code>
равен нулю - мы возвращаемся к <code>unweighted random walk</code>.
</p>

<p>
<div class="figure"><img src="/img/weighted-random-walk.png" alt="nil"/><p></p></div>
</p>

<p>
Правильный выбор <code>alfa</code> - нетривиальная задача, которая решается методом Markov Chain
Monte Carlo, <code>MCMC</code>. В цепи Маркова каждый шаг не зависит от предыдущего, а следует из
заранее определенног правила.
</p>

<p>
<div class="figure"><img src="/img/mcmc.gif" alt="nil"/><p></p></div>
</p>

<p>
Когда транзакции приходят редко, после того, как транзакция будет одобрена несколько
раз, ее совокупный вес будет расти со скоростью <code>λw</code>, где <code>w</code> - средний вес транзакции,
а <code>λ</code> - скорость появления новых транзакций.
</p>

<p>
Когда транзакции приходят часто, проявляются две фазы. Во-первых, совокупный вес
транзакции растет с увеличением скорости в течение периода адаптации. По окончании
периода адаптации совокупный вес растет со скоростью <code>λw</code> (доказательство в пэйпере).
</p>

<p>
<div class="figure"><img src="/img/iota-cum-weight-adoptation-period.png" alt="nil"/><p></p></div>
</p>
</div>
</div>

<div id="outline-container-unnumbered-3" class="outline-3">
<h3 id="unnumbered-3">Предотвращение Double spending</h3>
<div class="outline-text-3" id="text-unnumbered-3">
<p>
Предотвращение <code>double-spending</code> осуществляется следующим образом:
</p>

<p>
Положим, <code>Алиса</code> имеет на балансе 5 монет и создает две транзакции, в первой из которых
пересылает их <code>Бобу</code>, а во второй - <code>Чарли</code>. В таком случае узел, который видит обе
транзакции, должен отвергнуть как минимум одну из этих транзакций, т.к. в результате
<code>Алиса</code> будет иметь отрицительный баланс.
</p>

<p>
<div class="figure"><img src="/img/iota-double-spending-base.png" alt="nil"/><p></p></div>
</p>

<p>
Если одна из транзакций будет подтверждена одним узлом, а другая - иным, то это
приведет к формированию двух ветвей, одна из которых в конечно счете должна быть
отброшена. При использовании алгоритма <code>weighted random walk</code>, со временем одна из
ветвей станет больше.
</p>

<p>
Доверие к транзакции расчитывается как процент оконечных узлов (<code>tips</code>), которые её
подтверждают. На картинке транзакции с доверием больше 95% показаны с толстой
рамкой. Так например, транзакция 9 подтверждается двумя из четырех <code>tips</code>. Если бы мы
использовали <code>random tip selection</code>, у неё было бы 50%. Тем не менее, оконечные узлы,
которые её подтверждают, по-видимому, более весомы, чем те, которые не подтверждают,
что немного повышает доверие.
</p>

<p>
<div class="figure"><img src="/img/confirmation-confidence.png" alt="nil"/><p></p></div>
</p>

<p>
Как только сделка Алисы достигает некоторого очень высокого доверительного порога,
скажем, 95%, маловероятно, что она будет вытеснена из консенсуса. Однако <code>Алиса</code> может
попытаться сформировать альтернативную ветвь в <code>tangle</code>. Для этого она должна
поддержать double spending транзакцию для <code>Чарли</code>. <code>Алисе</code> придется апрувить две старые
транзакции, которые не ссылаются на ее транзакцию с <code>Чарли</code>. Затем она начнет выдавать
как можно больше транзакций, пытаясь увеличить вес ветки с транзакцией для <code>Чарли</code>.
</p>

<p>
Если у нее будет достаточно вычислительной мощности, она может заставить сеть поверить
ей и последовать за ее веткой, однако, если мы рассчитаем уровень доверия для ветки с
транзакцией для <code>Боба</code>, то увидим, что он снизился с 95% до нуля.
</p>

<p>
<code>Боб</code> может рассчитать доверие пока оно 95% и выполнить свою часть сделки - отправить
товар или оказать услугу, а потом столкнуться с тем, что доверие изменилось - тогда
атака <code>Алисы</code> удалась.
</p>

<p>
Для зрелой и активной сети вычислительные ресурсы для реализации атаки будут слишком
дорогостоящими, но на стадии развития такая атака может быть очень вероятной. Под этим
предлогом IOTA Foundation вводит так называемый "Координатор", который является
централизованным сервером, который каждые две минуты создает <code>milestone</code>-транзакцию,
которая немедленно подтверждает все одобренные ей транзакции на 100%. Они заявляют, что
это временное решение, до тех пор, пока сеть не выйдет на достаточный уровень
мощности.
</p>
</div>
</div>

<div id="outline-container-unnumbered-4" class="outline-3">
<h3 id="unnumbered-4">Сетевой протокол</h3>
<div class="outline-text-3" id="text-unnumbered-4">
<p>
Каждая нода имеет несколько соседей о которых знает.
</p>

<p>
Каждая нода самостоятельно ведет статистику в отношении своих соседей и может исключать
из числа соседей "ленивые ноды", поэтому даже узел, который не создает новые транзакции
имеет мотивацию распространять транзакции дальше по сети.
</p>
</div>
</div>
</div>

<div id="outline-container-unnumbered-5" class="outline-2">
<h2 id="unnumbered-5">Сценарии атак</h2>
<div class="outline-text-2" id="text-unnumbered-5">
</div><div id="outline-container-unnumbered-6" class="outline-3">
<h3 id="unnumbered-6">Broken tangle</h3>
<div class="outline-text-3" id="text-unnumbered-6">
<p>
Идея состоит в том, чтобы выпустить N конфликтующих транзакций, две из которых не могут
подтвердить другие узлы в сети, эффективно разбивая tangle на N сегментов. В конце
концов один выигрывает, но все, кто отправил транзакции на отвергнутый сегмент, должны
будут повторно отправить их, и к тому времени злоумышленник мог выпустить еще один
набор конфликтных транзакций.
</p>

<p>
Цель состоит в том, чтобы предотвратить подтверждение большинства транзакций (отказ в
обслуживании)
</p>
</div>
</div>

<div id="outline-container-unnumbered-7" class="outline-3">
<h3 id="unnumbered-7">Double spending</h3>
<div class="outline-text-3" id="text-unnumbered-7">
<p>
Злоумышленник пытается опередить сеть. Общий сценарий выглядит так:
</p>
<ul class="org-ul">
<li>Злоумышленник отправляет платеж продавцу и получает товар после того, как продавец
решает, что транзакция набрала достаточно большой совокупный вес.
</li>
<li>Злоумышленник выдает double-spending транзакцию.
</li>
<li>Злоумышленник использует свою вычислительную мощность для выпуска многих небольших
транзакций, которые подтверждают double-spending транзакцию, но не подтверждают
первоначальную транзакцию. Или Злоумышленник выпускает две транзакции, одобряя
сначала одну из них, а после получения товара - вторую.
</li>
<li>Злоумышленник может иметь множество Сивилл-нод, которые не обязаны подтвержать
оконечные транзакции.
</li>
<li>Злоумышленник надеется, что его нечестный subtangle опередит честный subtangle. Если
это произойдет, tangle продолжает расти из double-spendign транзакции, а правильная
ветвь с первоначальным платежом торговцу становится "осиротевшей".
</li>
</ul>

<p>
Следующий пример иллюстрирует атаку на временную неконсистентность tangle:
</p>

<p>
Обычный узел большую часть времени получает транзакции и обменивается ими с
соседями. Он заботится о топологии графа только тогда, когда пришло время произвести
транзакцию или принять платеж.
</p>

<p>
<div class="figure"><img src="/img/iota-double-spending.png" alt="nil"/><p></p></div>
</p>

<p>
Сейчас 16:04, и <code>Боб</code> решает отправить транзакцию, которая ссылается на 2 транзакции:
</p>
<ul class="org-ul">
<li>1 йота на адрес <code>Алисы</code>
</li>
<li>1 йоту от адреса <code>Алисы</code>
</li>
</ul>

<p>
Это не приводит к <code>double</code> spending, поэтому в 16:07 он завершает создание транзакции.
</p>

<p>
Через 90 минут плохой парень <code>Чарли</code> решает сослаться на сделку <code>Боба</code> и другую сделку,
которая тратит 1 йоту с адреса <code>Алисы</code>
</p>

<p>
В 17:44 он завершает создание транзакции, которая ссылается на subtangle с искаженным
состоянием.
</p>

<p>
Никто из нас не заботится об этом, мы не знаем о плохом парне <code>Чарли</code>, потому что наши
узлы продолжают получать все транзакции и делиться ими.
</p>

<p>
В 19:15 хорошая девочка <code>Диана</code> решает отправить деньги своей матери, она анализирует
<code>Tangle</code> и видит, что она не должна ссылаться на транзакцию Чарли, поэтому вместо этого
ссылается на транзакцию <code>Боба</code>.
</p>

<p>
Ее транзакция не является особенной, поэтому она не показана на картинке.
</p>

<p>
Спустя несколько минут умная девушка <code>Ева</code> решает отправить сообщение своему парню. Она
тоже умна и решает потролить плохого парня <code>Чарли</code>. Она находит транзакцию, которая
посылает 1 йоту на адрес <code>Алисы</code>. Она ссылается на эту сделку, а также на сделку
<code>Чарли</code>. Мы видим сделку <code>Евы</code> в 19:21
</p>

<p>
Позже кто-то другой, производящий транзакцию, будет ссылаться на транзакцию <code>Евы</code> без
каких-либо проблем, потому что она «исправила» проблему, созданную <code>Чарли</code>.
</p>

<p>
Как мы можем видеть в этом сценарии в течение какого-то периода времени, реестр может
быть неконсистентным.
</p>
</div>
</div>

<div id="outline-container-unnumbered-8" class="outline-3">
<h3 id="unnumbered-8">Large weigth</h3>
<div class="outline-text-3" id="text-unnumbered-8">
<p>
Я пока не могу понять как работает эта атака.
</p>
</div>
</div>

<div id="outline-container-unnumbered-9" class="outline-3">
<h3 id="unnumbered-9">Parasite chain</h3>
<div class="outline-text-3" id="text-unnumbered-9">
<p>
Злоумышленник тайно строит subtangle, который иногда ссылается на основной tangle,
чтобы получить более высокий score.  Score честных tips - это примерно сумма всех
собственных весов в основном tangle, в то время как score атакующих tips также содержит
сумму всех собственных весов в цепи злоумышленника. Так как задержки в сети не проблема
для Злоумышленника, который создает свою цепь на своем достаточно мощном компьютере, то
он может получить больший height для своих tips.
</p>

<p>
Более того, Злоумышленник может искусственно увеличить его, путем отправки большого
количества новых транзакций, которые подтвердают его транзакции в паразитной цепи - это
сработает, если некоторые честные узлы используют простые стратегии случайного выбора
среди доступных tips.
</p>

<p>
Алгоритм MCMC будет защищать от подобных атак, если основной tangle обладает большим
хэшрейтом, чем атакующий.
</p>

<p>
Еще один способ решения - ограничить собственный вес транзакции сверху или сделать его
константой.
</p>
</div>
</div>

<div id="outline-container-unnumbered-10" class="outline-3">
<h3 id="unnumbered-10">Resonance</h3>
<div class="outline-text-3" id="text-unnumbered-10">
<p>
В момент резкого увеличения объема транзакций значительное количество <code>tips</code> может
остаться неподтвержденными. Можно смоделировать ситуацию, когда транзакции не поступают
равномерно, сеть в среднем хуже будет справляться с таким сценарием, что позволяет
комбинировать этот способ с другими видами атак на отказ в обслуживании.
</p>
</div>
</div>

<div id="outline-container-unnumbered-11" class="outline-3">
<h3 id="unnumbered-11">Splitting</h3>
<div class="outline-text-3" id="text-unnumbered-11">
<p>
Довольно подробно рассмотрена в пэйпере, нет смысла пересказывать.
</p>
</div>
</div>
</div>

<div id="outline-container-unnumbered-12" class="outline-2">
<h2 id="unnumbered-12">Возможные расширения</h2>
<div class="outline-text-2" id="text-unnumbered-12">
</div><div id="outline-container-unnumbered-13" class="outline-3">
<h3 id="unnumbered-13">Увеличение количества подтверждений</h3>
<div class="outline-text-3" id="text-unnumbered-13">
<p>
Технически возможно увеличить количество возможных ссылок подтверждения - например
использовать 3 вместо 2, или даже иметь неограниченное количество ссылок - тогда одна
транзакция могла бы подтвердить много более ранних транзакций.
</p>

<p>
При этом, возрастают накладные расходы на проверку путей такой транзакции, но
открываются дополнительные возможности:
</p>
<ul class="org-ul">
<li>"упорядочивающее подтверждение", которое добавляет отношение частичной
упорядоченности для подтверждаемых транзакций. Это может быть полезно в задачах
частичного подсчета состояния сети, что позволяет узлам хранить меньше данных.
</li>
<li>"чекпойнт", который позволяет фактически создавать новые genesis-узлы по запросу, что
позволяет сократить вычисление путей (для свернутых маршрутов) до последнего
genesis-элемента. Таким образом можно обеспечить высокую производительность для
узлов, которые присоединяются к сети, не деградирующую с ростом размера сети.
</li>
</ul>
</div>
</div>

<div id="outline-container-unnumbered-14" class="outline-3">
<h3 id="unnumbered-14">Гарантированное подтверждение</h3>
<div class="outline-text-3" id="text-unnumbered-14">
<p>
В процессе работы сети, какое-то количество транзакций не получают подтверждения - это
могут быть как ошибочно сформированные транзакции, так и валидные транзакции, которым
"не повезло".
</p>

<p>
Узел, который отправил такую транзакцию, заинтересован в ее подтверждении. В текущей
реализации ему предлагается отправить транзакцию еще раз, но существует возможность
находить такие валидные транзакции и подтверждать их "гарантированно" - для этого
необходимо существование особых правил для узлов, к которым можно обратиться за
гарантированным подтверждением. Такие узлы могут работать за плату и предоставлять
гарантированное подтверждение по особым правилам.
</p>
</div>
</div>
</div>

<div id="outline-container-unnumbered-15" class="outline-2">
<h2 id="unnumbered-15">Ссылки</h2>
<div class="outline-text-2" id="text-unnumbered-15">
<ul class="org-ul">
<li>whitepaper <a href="https://iota.org/IOTA_Whitepaper.pdf">https://iota.org/IOTA_Whitepaper.pdf</a>
</li>
<li>референсная реализация: <a href="https://github.com/iotaledger/iri">https://github.com/iotaledger/iri</a>
</li>
<li>демонстрашка на js: <a href="https://public-rdsdavdrpd.now.sh/">https://public-rdsdavdrpd.now.sh/</a>
</li>
<li>демонстрашка unweighted random walk: <a href="https://public-xnmzdqumwy.now.sh/">https://public-xnmzdqumwy.now.sh/</a>
</li>
<li>демонстрашка mcmc <a href="https://public-qnbiiqwyqj.now.sh/">https://public-qnbiiqwyqj.now.sh/</a>
</li>
<li>демо confirmation confidence <a href="https://public-krwdbaytsx.now.sh/">https://public-krwdbaytsx.now.sh/</a>
</li>
</ul>
</div>
</div>

<div id="outline-container-unnumbered-16" class="outline-2">
<h2 id="unnumbered-16">Критика</h2>
<div class="outline-text-2" id="text-unnumbered-16">
<ul class="org-ul">
<li><a href="https://casey.github.io/iota/">https://casey.github.io/iota/</a>
</li>
</ul>
</div>
</div>

<div id="outline-container-unnumbered-17" class="outline-2">
<h2 id="unnumbered-17">Вопросы</h2>
<div class="outline-text-2" id="text-unnumbered-17">
<ul class="org-ul">
<li>Топология сети?
</li>
<li>Протокольный уровень правило взаимодействия узлов?
</li>
<li>Как работают консенсус и валидация блоков? Кто проверяет?
</li>
<li>Механизмы хранения данных как устроены хранилища?
</li>
<li>Смарт-контракты: да, нет, другие подходы
</li>
</ul>
</div>
</div>

<div id="outline-container-unnumbered-18" class="outline-2">
<h2 id="unnumbered-18">Транзакция</h2>
<div class="outline-text-2" id="text-unnumbered-18">
<p>
Я взял кусок класса транзакции из сорцов:
</p>

<div class="org-src-container">

<pre class="src src-java"><span style="color: #af00ff;">public</span> <span style="color: #af00ff;">class</span> <span style="color: #008700;">Transaction</span> <span style="color: #af00ff;">implements</span> <span style="color: #008700;">Persistable</span> {
    <span style="color: #af00ff;">public</span> <span style="color: #af00ff;">static</span> <span style="color: #af00ff;">final</span> <span style="color: #008700;">int</span> <span style="color: #af5f00;">SIZE</span> = 1604;

    <span style="color: #af00ff;">public</span> <span style="color: #008700;">byte</span>[] <span style="color: #af5f00;">bytes</span>;

    <span style="color: #af00ff;">public</span> <span style="color: #008700;">Hash</span> <span style="color: #af5f00;">address</span>;
    <span style="color: #af00ff;">public</span> <span style="color: #008700;">Hash</span> <span style="color: #af5f00;">bundle</span>;
    <span style="color: #af00ff;">public</span> <span style="color: #008700;">Hash</span> <span style="color: #af5f00;">trunk</span>;
    <span style="color: #af00ff;">public</span> <span style="color: #008700;">Hash</span> <span style="color: #af5f00;">branch</span>;
    <span style="color: #af00ff;">public</span> <span style="color: #008700;">Hash</span> <span style="color: #af5f00;">obsoleteTag</span>;
    <span style="color: #af00ff;">public</span> <span style="color: #008700;">long</span> <span style="color: #af5f00;">value</span>;
    <span style="color: #af00ff;">public</span> <span style="color: #008700;">long</span> <span style="color: #af5f00;">currentIndex</span>;
    <span style="color: #af00ff;">public</span> <span style="color: #008700;">long</span> <span style="color: #af5f00;">lastIndex</span>;
    <span style="color: #af00ff;">public</span> <span style="color: #008700;">long</span> <span style="color: #af5f00;">timestamp</span>;

    <span style="color: #af00ff;">public</span> <span style="color: #008700;">Hash</span> <span style="color: #af5f00;">tag</span>;
    <span style="color: #af00ff;">public</span> <span style="color: #008700;">long</span> <span style="color: #af5f00;">attachmentTimestamp</span>;
    <span style="color: #af00ff;">public</span> <span style="color: #008700;">long</span> <span style="color: #af5f00;">attachmentTimestampLowerBound</span>;
    <span style="color: #af00ff;">public</span> <span style="color: #008700;">long</span> <span style="color: #af5f00;">attachmentTimestampUpperBound</span>;

    <span style="color: #af00ff;">public</span> <span style="color: #008700;">int</span> <span style="color: #af5f00;">validity</span> = 0;
    <span style="color: #af00ff;">public</span> <span style="color: #008700;">int</span> <span style="color: #af5f00;">type</span> = <span style="color: #008787;">TransactionViewModel</span>.PREFILLED_SLOT;
    <span style="color: #af00ff;">public</span> <span style="color: #008700;">long</span> <span style="color: #af5f00;">arrivalTime</span> = 0;

    <span style="color: #af0000;">//</span><span style="color: #af0000;">public boolean confirmed = false;</span>
    <span style="color: #af00ff;">public</span> <span style="color: #008700;">boolean</span> <span style="color: #af5f00;">parsed</span> = <span style="color: #008787;">false</span>;
    <span style="color: #af00ff;">public</span> <span style="color: #008700;">boolean</span> <span style="color: #af5f00;">solid</span> = <span style="color: #008787;">false</span>;
    <span style="color: #af00ff;">public</span> <span style="color: #008700;">long</span> <span style="color: #af5f00;">height</span> = 0;
    <span style="color: #af00ff;">public</span> <span style="color: #008700;">String</span> <span style="color: #af5f00;">sender</span> = <span style="color: #87005f;">""</span>;
    <span style="color: #af00ff;">public</span> <span style="color: #008700;">int</span> <span style="color: #af5f00;">snapshot</span>;

    ...
}
</pre>
</div>
</div>
</div>
</div>
</body>
</html>

{'fraction_non_alphanumeric': 0.14418716567642104, 'fraction_numerical': 0.02006404205304755, 'mean_word_length': 5.811396873424105, 'pattern_counts': {'":': 0, '<': 1631, '<?xml version=': 0, '>': 1631, 'https://': 28, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3795330', 'n_tokens_mistral': 23143, 'n_tokens_neox': 25083, 'n_words': 5665}