Перевод Субадреса

Тема в разделе "Статьи", создана пользователем Маша, 3 ноя 2017.

  1. Маша

    Команда форума Редактор

    Регистрация:
    20 окт 2017
    Сообщения:
    10
    Симпатии:
    4
    Примечание. Этот запрос на изменение (Pull Request) заменяет #1753. Самое главное отличие в том, что идея одноразовых адресов была отброшена из-за потенциальной опасности неправильного использования неопытными пользователями. Смотрите соответствующую дискуссию здесь.

    GUI-версия

    1. Мотивация


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

    Еще один возможный сценарий — допустим, вы хотите анонимно купить Monero через ShapeShift. Если вы неоднократно использовали один и тот же адрес для нескольких заказов, ShapeShift будет знать, что один и тот же человек купил определенное количество Monero с помощью этих заказов (хотя они не узнают вашу контактную информацию, так как не требуют регистрации). Вы можете сделать процесс анонимным, создавая временный кошелек для каждого заказа и после этого переводя средства на ваш основной кошелек. Это возможно, но утомительно.

    Схема, предложенная в этом запросе на изменение (Pull Request), обеспечивает эффективное решение для таких сценариев, где получатель может создать несколько «субадресов» кошелька, которые выглядят не связанными друг с другом для внешнего наблюдателя, а также принять все переводы на эти субадреса почти без дополнительной комиссии. Заметьте, что эта схема только включает в программу кошелька дополнительные процедуры создания и интерпретации транзакций, не требуя никаких изменений в правиле консенсуса (таким образом, не требуя хардфорка).

    2. Как это работает с точки зрения криптографии

    Предположим, адрес кошелька Боба - (A, B) = (a * G, b * G), где a и b – это его ключ для просмотра и ключ для траты соответственно. Аналогично, адрес Алисы - (X, Y) = (x * G, y * G). Боб получает Monero от Алисы, но хочет делать это, не используя свой реальный адрес (A, B), чтобы Алиса не знала, что он является получателем. В вышеприведенном примере с ShapeShift Боб — это вы, а Алиса - это ShapeShift.

    2.1.Создание субадресов

    Боб создает свой i-th субадрес (i = 1,2,...) как пару публичных ключей (C, D), где:

    m = Hs (a || i)
    M = m * G
    D = B + M
    C = a * D

    Индекс субадреса называется i . Заметьте, что (A, B) и (C, D) невозможно связать без знания секретного ключа для просмотра a. Затем Боб записывает D в хэш-таблицу, которая хранится в кэше его кошелька (по типу схемы агрегации адресов):

    T[D] <- i

    Чтобы распоряжаться своим основным адресом вместе с субадресами, Боб также записывает B в хэш-таблицу:

    T <- 0

    Другими словами, индекс 0 в этой схеме играет роль частного случая, представляя собой изначальный стандартный адрес.

    2.2 Отправка средств на субадреса

    Когда Алиса создает транзакцию, которая перемещает некоторые средства на субадрес (C, D), она сначала выбирает случайный скаляр s и генерирует публичный ключ tx:

    R = s * D

    Заметьте, что публичный ключ tx r такой, что R = r * G неизвестен Алисе, поскольку она не знает приватный ключ D. Затем она вычисляет выходной публичный ключ для направления:

    P = Hs (s * C) * G + D

    Наконец, она вычисляет выходной публичный ключ для своего остатка:

    Важно, что, не зная секретный tx ключ r, как показано выше, Алиса может включить выход ее остатка в транзакцию только потому, что она знает свой собственный приватный ключ для просмотра x. [Другими словами, в этой схеме возможны переводы только в одном направлении, а переводы в нескольких направлениях требуют использования стандартных адресов.]
    Теперь эта схема поддерживает и переводы в нескольких направлениях посредством введения дополнительных ключей tx.
    Заметьте также, что Алиса может подтвердить свой платеж Бобу, используя s.

    2.3.Получение средств на субадреса

    Боб проверяет, принадлежит ли ему выходной публичный ключ P, с помощью вычислений:

    D' = P - Hs (a * R) * G

    и поиска D' в хэш-таблице. Если транзакция действительно была привязана к субадресу Боба (C, D), то D' должно равняться D, потому что:

    a * R = a * s * D
    = s * a * D
    = s * C

    Следовательно, у Боба должно получиться найти D' в хэш-таблице:

    i <- T [D']

    и получить личный ключ P:

    p = { Hs (a * R) + b i == 0
    { Hs (a * R) + b + Hs (a || i) иначе


    2.4 Объединение субадресов

    Посылая средства на субадрес Боба (C, D), Алиса может послать остаток на свой і - субадрес (X_i, Y_i) вместо своего основного адреса (X, Y), поставив Y_i вместо Y, извлекая выходной публичный ключ остатка:

    Q = Hs (x * R) * G + Y_i

    Теперь с помощью этой схемы можно поддерживать баланс субадресов по отдельности, потому что они будут виртуально функционировать как отдельные кошельки. Чтобы владение субадресами было организованным, мы предлагаем простую схему группирования субадресов: мы определяем индекс субадресов как пару индексов (I, j), где і, главный индекс, представляет группу субадресов (которая называется аккаунт), а j, второстепенный индекс, представляет определенный субадрес в этом аккаунте. Входящие переводы на субадреса, принадлежащие одному и тому же аккаунту (і, 0), (і, 1), ... суммируются, образуя один баланс, и любая трата этих выходов переведет остаток на основной субадрес (і,0). Индекс (0, 0) представляет изначальный стандартный адрес.

    3. Как это работает в CLI

    3.1. Синопсис

    Существующие команды с обновленным синтаксисом:
    Новые команды:
    3.2 Управление аккаунтами

    Изначально кошелек имеет только один аккаунт, соответствующий главному индексу 0. Индекс аккаунта обозначен как число после / в командной строке:

    Вы можете создать новый аккаунт, используя команду account new:
    Обратите внимание на изменение адреса. Команда account switch позволяет вам переключаться с одного аккаунта на другой:

    Команда account без аргументов выводит список всех аккаунтов и их баланс:
    В любое время пользователь совершает действия в выбранном на настоящий момент аккаунте и обозначает второстепенный индекс в различных командах, когда это необходимо, с помощью параметра index; то есть в последующем описании мы используем термин «индекс», имея в виду второстепенный индекс.

    3.3.Создание субадреса

    Команда address показывает «основной» адрес, где index = 0 (что соответствует изначальному стандартному адресу, когда выбранный в настоящее время аккаунт находится на index = 0). Команда address new позволяет вам создать новый адрес на один индекс ниже верхнего из существующих на настоящий момент индексов, связанных с этим аккаунтом. Если необходимо, вы можете приписать название (label) адресу:
    Обратите внимание, что эта команда должна быть использована для создания «одноразовых» адресов; то есть, когда вы просто хотите получить новый адрес для получения средств на аккаунт, выбранный вами в настоящее время (например, когда вы обмениваете XMR через ShapeShift). Если вместо этого вы хотите иметь отдельный баланс, привязанный к новому адресу, создайте новый аккаунт с помощью команды account new.

    Команды address all и address <index_min> [<index_max>] показывают списки адресов, которые были созданы к настоящему моменту:
    Команда address_label позволяет вам установить название (label) адреса:
    Обратите внимание, что название основного адреса становится названием выбранного в настоящее время аккаунта. Вы можете поменять аккаунт, используя address label или account label:
    3.4 Проверка средств и баланса

    Здесь кошелек находит несколько входящих переводов с помощью некоторых субадресов (обозначенных парами главных-второстепенных индексов):
    Команда balance показывает общий баланс всех средств, полученных на все адреса, принадлежащие выбранному в настоящее время аккаунту. Вы можете увидеть подробности о количестве средств, полученных на каждый адрес, добавив аргумент detail:
    Другие команды для вывода подробной информации о средствах имеют некоторые изменения в синтаксисе:
    3.5.Перевод средств

    Вроде бы несвязанные адреса можно связать статистически, если средства, переведенные на разные адреса, используются вместе как входы в новые транзакции. Например, предположим, что Боб опубликовал два субадреса (C1, D1) и (C2, D2) в разных местах, и Алиса неоднократно переводила средства на эти адреса, не зная, что оба принадлежат Бобу. Если Боб неоднократно использовал выходы, полученные этими субадресами вместе в качестве входов в новые транзакции, Алиса заметит несколько случаев транзакций, где каждая из входных кольцевых подписей содержит выход, который она сама создала для платежей на эти субадреса. Вероятность случайного появления подобных транзакций была бы очень низкой, поэтому она могла бы с уверенностью предположить, что эти субадреса принадлежат одному человеку.

    С целью предотвращения подобных рисков кошелек делает все возможное, чтобы избежать использования выходов, принадлежащих разным субадресам, вместе в качестве входов в новых транзакциях. Если существуют какие-либо субадреса с достаточным балансом для запрашиваемого перевода, кошелек использует минимальное количество субадресов, чтобы набрать требуемую сумму, при этом показывая предупреждение. Вы также можете самостоятельно установить, из каких субадресов должны быть взяты выходы, используя аргумент index=<N1>[,<N2>,...]:
    Команда sweep_all имеет похожий синтаксис:

    sweep_all [index=<N1>[,<N2>,...]] [<mixin_count>] <address> [<payment_id>]

    Если вы опустите параметр index, то один субадрес, который будет пропущен, выбирается случайно (индекс 0 выбирается последним). Вы можете использовать index=<N> чтобы уточнить, какой именно субадрес должен быть пропущен. Вы также можете использовать index=<N1>,<N2>,... чтобы пропустить баланс нескольких или всех субадресов.
    Заметьте, что остаток всегда идет на основной субадрес на index = 0:
    3.6. Восстановление кошелька из seed-фразы

    Одно небольшое неудобство в этой схеме — когда вы восстанавливаете кошелек из seed-фразы, кошелек может пропустить переводы на субадреса, если они еще не хранятся в хэш-таблице. Чтобы справиться с этой проблемой, кошелек хранит для каждого аккаунта 200 (постоянная SUBADDRESS_LOOKAHEAD_MINOR, определенная в wallet2.h ) субадресов с индексами выше верхнего индекса из созданных к настоящему моменту. Кошелек также генерирует 50 (постоянная SUBADDRESS_LOOKAHEAD_MAJOR, определенная в wallet2.h ) аккаунтов выше верхнего индекса из созданных к настоящему времени. Это значит, что в процессе восстановления кошелька есть гарантия, что входящие переводы на субадреса будут найдены, пока главные и второстепенные индексы использованных субадресов отличаются на меньшее число, чем эти предопределенные числа. Обратите внимание, что кошелек расширяет хэш-таблицу самостоятельно, как только находит входящие переводы на субадреса, имеющие более высокие индексы, поэтому обычно пользователю не приходится беспокоиться об управлении хэш-таблицей. Даже если разницы индексов больше, чем эти предопределенные числа, вы все еще можете заставить кошелек распознать входящие переводы, вручную расширив хэш-таблицу и заново просканировав блокчейн.

    Вот пример: сначала мы генерируем 360 новых адресов для первого аккаунта:
    Затем мы генерируем 70 аккаунтов и печатаем основные адреса 15-го и 70-го аккаунтов:
    После этого мы посылаем средства на эти адреса (под индексами 1/150, 1/360, 15/0, 70/0) с другого кошелька:
    Теперь мы удаляем кэш кошелька-получателя 9uPkEU и заново генерируем его, снова сканируя блокчейн (тот же эффект, что и при восстановлении кошелька из seed-фразы):
    Обратите внимание, что на этом этапе кошелек мог успешно распознавать входящие переводы на индексы 1/150 и 15/0, но не смог распознать входящие переводы на индексы 1/360 и 70/0, потому что 360 > 150 + SUBADDRESS_LOOKAHEAD_MINOR и 70 > 15 + SUBADDRESS_LOOKAHEAD_MAJOR. Вы можете заставить кошелек распознавать эти входящие переводы, вручную расширяя хэш-таблицу и заново просканировав блокчейн:
    4. Список запланированных дел
    • Пересмотр проделанной работы
    • Тестирование модулей и производительности
    • Обновление MRL-0006
    5. Ссылки по теме
    Благодарности

    @JollyMort за первые обсуждения с самого начала
    @knaccc за концепт субадресов с идеей об обмене модифицированных Диффи-Хеллман ключей, а также за указание на тот факт, что остаток можно послать на любой субадрес
    @RandomRun за идею обмена Диффи-Хеллман ключей второго поколения, которая решает проблему обнаружения ключей основного кошелька
    @luigi1111 за различные предложения и руководство

    Источник: Subaddresses #2056

    Перевод:
    Маша (@god592)
    Редактирование:
    Mr. Pickles (@v1docq47)
    Коррекция:
    Kukima (@Kukima )
     
    #1 Маша, 3 ноя 2017
    Последнее редактирование модератором: 12 дек 2017
    TheFuzzStone нравится это.
  • О нас

    Наш сайт является одним из уникальных мест, где русскоязычное сообщество Monero может свободно общаться на темы, связанные с этой криптовалютой. Мы стараемся публиковать полезные мануалы и статьи (как собственные, так и переводы с английского) о криптовалюте Monero. Если вы хорошо владеете английским (или можете писать собственные статьи/мануалы) и хотите помочь в переводах и общем развитии Monero для русскоязычной аудитории - свяжитесь с одним из администраторов.