Манекі-неко DUCAT з монетою Monero в лапі
пряма торгівля поруч · специфікація, чернетка 1.1.0-dev13

DUCAT

Veilid для передавання. Monero для розрахунку. Жодного оператора посередині.

Ніде немає сервера DUCAT — контакти, повідомлення, рахунки й чеки це записи в DHT та наскрізно запечатані пакети, а кожен телефон тримає повноцінний вузол Veilid, повертаючи маршрутизацію та сховище, які сам займає.

0 векторів відповідності 0 режимів роботи 0 мов 0 серверів

Підписано в режимі налагодження, лише stagenet. Поки не для справжніх грошей.

Стоїть на

Торгівля, де посередині нікого немає

Дукат шість століть був золотою монетою, яку приймали від Венеції до Відня й до Леванту — жодних стосунків з емітентом, жодного рахунку позаду, жодного дозволу. DUCAT — це те саме, для хвилини, коли ви стоїте перед людиною й домовляєтеся.

🐱

Ніде жодного сервера

Контакти, рахунки, платежі та чеки йдуть як наскрізно запечатані пакети через DHT Veilid. Нема чого викликати до суду, обмежити, зняти з платформи чи вимкнути, бо нічого не працює. Кожен телефон — повноцінний вузол і повертає маршрутизацію та сховище, які займає.

🔑

Особистість — це пара ключів

Створюється на телефоні. Ні пошти, ні номера, нікого, у кого реєструватися — і саме тому ніхто не зможе її вам відновити, і застосунок каже це вголос, а не ховає.

🎫

Картки на одне пред'явлення

Ви даєте людині картку — QR, посилання ducat: або дотик NFC — і вона годиться для однієї людини. Після отримання вона перестає працювати, тож знімок екрана, що потрапив кудись іще, — не вхід.

🔒

Запечатані розмови

Шифрування у формі X3DH, з одноразовими передключами та прямою секретністю. Коли застосунку доводиться відкочуватися на підписаний передключ, він показує вам відкритий замок, а не приховує це.

💬

Розмови, що несуть гроші

Гілки на поштовій скриньці, які працюють, поки одна зі сторін офлайн — вони несуть деталізовані рахунки, рядки яких мусять сходитися з підсумком, інакше повідомлення відхиляється, платежі та чеки, виписані одержувачем і вказані на транзакцію, яку вони підтверджують. Невеликі групи розходяться тими самими парними гілками: ні групового ключа, ні спільного запису, усі властивості гілки недоторкані.

Шість кроків, без облікового запису,
приблизно хвилина

Кожен знімок на цій сторінці — застосунок на телефоні, а не макет. Ніщо тут не просить вас зареєструватися, бо реєструватися нема в кого.

Крок 1 з 6: створіть особистість — пара ключів, зроблена на цьому телефоні, без облікового запису
1 · Особистість — пара ключів, а не реєстрація
Крок 4 з 6: оберіть PIN, з прямо сказаним попередженням, що скинути його не можна
4 · PIN — і жодного способу його скинути, сказано прямо
Крок 5 з 6: як незнайомці довіряють одне одному — обидві сторони вносять заставу, доведення до кінця її повертає
5 · Довіра — пояснена до вашої першої угоди
Крок 6 з 6: резервна копія, яка чесно ще не копія, доки не покинула телефон
6 · Резервна копія — «ще не копія», доки вона не покинула телефон

Ваша особистість — це пара ключів, створена на пристрої: ні пошти, ні номера, нікого, у кого реєструватися, і саме тому ніхто не зможе її вам відновити. Останній крок — резервна копія, бо гаманець, який не можна відновити, — єдиний спосіб тут справді втратити гроші.

Гроші, які ваші

Гаманець Monero у власному володінні, з перерахунком у місцеву валюту всюди, сканований і витрачений вбудованим рушієм monero-oxide — жодного демона гаманця на телефоні.

Особистий екран: баланс у XMR і місцевій валюті, стан синхронізації, лічильник доступних купюр, плитки режимів і останні рухи
Баланс і купюри, що стоять за ним
Оплата чи запит: сума в місцевій валюті або XMR, арифметика комісій, скільки лишається після
Уся арифметика перш ніж ви погодитесь
Виписка: поточний баланс, пошук по чеках, вивантаження в CSV
Виписка, відновлена з ланцюга
Вибір, кому платити: контакти з відбитками їхніх ключів
Кому ви платите, за відбитком ключа

Під час оплати видно суму, оцінку мережевої комісії, підсумок, скільки лишиться після, скільки купюр буде витрачено і приблизно скільки це триватиме — і можна обрати швидкість. Історія відновлюється з ланцюга: відправлення розпізнаються за key image, решта ніколи не показується як надходження, кожен рядок несе поточний баланс, а всю виписку можна вивантажити в CSV.

Monero витрачає окремі купюри, а не баланс, тож гаманець з однією великою купюрою може не змогти заплатити двічі поспіль. Застосунок рахує купюри, які може витратити, і каже розміняти одну до того, як ви станете біля каси, а не падає вже там.

Розмови, що несуть гроші

Контакт — це пара ключів, а не ідентифікатор. Одне сканування відкриває розмову на поштовій скриньці, яка працює, поки одна зі сторін офлайн — і ці гілки несуть торгівлю, а не лише текст.

Ваша картка: QR на одне пред'явлення, що відкриває розмову, годиться для однієї людини
Ваша картка — годиться для однієї людини
Розмова, що несе гроші: деталізований рахунок із рядком податку, чек, плашка про закрите ескроу
Рахунок, платіж, чек — прямо в гілці
Група з трьох на спільній дошці: один запис на покоління, запитання і відповідь з іншого телефона
Групи — один спільний запис на покоління
Пошук по сказаному, де збіги за іменами стоять вище за збіги в повідомленнях
Шукайте те, що люди справді сказали

Ви даєте людині картку — QR, посиланням ducat: або дотиком NFC — і вона годиться для однієї людини: після отримання перестає працювати, тож знімок екрана, що потрапив кудись іще, — не вхід.

Група — це список, який лише зростає, а її слова їдуть на одному спільному записі дошки на покоління (§16.24): кожен учасник пише власні сторінки під груповим ключем, який несе сам список, тож повідомлення п'ятьом — це один запис замість п'яти, і мережа не відрізнить цей запис від жодного іншого. Видати себе за іншого не вийде, а вихід — справа локальна. Група вміє ділити рахунок: один підсумок стає окремим запитом до кожного плюс фразою, за якою всі можуть перевірити арифметику, і кожен запит переходить у «сплачено», щойно надходить його підтвердження.

Ваш телефон — це вся справа

Оберіть один із дев'яти режимів, і застосунок цілком передає керування — власні вкладки, нічого від гаманця. Майже нічому з цього не знадобився новий об'єкт протоколу, і це фраза, якою специфікація пишається найбільше.

Режими роботи: особистий, каса, відкритий рахунок, таксі, пожертви, ринок, оренда, найм допомоги, кіоск
Дев'ять режимів, один протокол
Каса: пробиті позиції з порахованим рядком податку
Каса — з порахованим податком
Один код для сканування покупцем; деталізований рахунок приходить на його телефон
Один код — рахунок приходить при скануванні
Відкриті рахунки: відкриті, виставлені й у очікуванні, закриваються одним рахунком
Відкриті рахунки — закриваються з автобуса додому
Режим кіоску, бік покупця: натисніть, що хочете, податок показано до підтвердження
Кіоск — покупець замовляє сам
Панель персоналу кіоску за PIN-кодом: замовлення, меню та ставка податку
Панель персоналу за PIN-кодом
Постійний код для пожертв, з ціною пов'язуваності прямо на екрані
Пожертви — з названою ціною

Каса пробиває позиції або приймає набрану суму, рахує податок з продажів свого регіону й показує один код; рахунок приходить на телефон покупця в мить сканування, а чек вертається, коли він платить. Відкритий рахунок позначає покупцеві кожен напій і закривається одним рахунком. Кіоск віддає телефон покупцеві цілком, з панеллю персоналу за PIN-кодом. Скринька для пожертв дає обидва шляхи: код DUCAT, що відкриває розмову й надсилає чек, щойно гроші дійшли, і постійну адресу, на яку може дати будь-який гаманець Monero, — з ціною пов'язуваності прямо на екрані, а не в правилах.

Поїздка, яку ніхто не розподіляє

Наберіть, куди їдете. Телефон перетворює координати GPS на геокомірку — публічну дошку, адресою якої є саме місце — і вивішує виклик: картку на одне пред'явлення, приблизний район і ціну, пораховану за справжнім маршрутом. Жодне ім'я на дошку не потрапляє — ні на картку, ні в запис за нею. Водії стежать за своєю коміркою й сусідніми та беруть його; перегони судить DHT, і жодного диспетчера не існує.

Зелена лінія — ось суть: тарифи DUCAT приблизно на 15 % нижчі за те, що агрегатор бере з пасажира, і водій забирає все — відсутня частка платформи, віддана їм обом. Згода приходить з обличчям: ім'я, машина, колір, номер, час подачі — запечатане для пасажира й ніколи не показане дошці. Ваше власне ім'я та під'їзд, біля якого ви стоїте, тієї ж миті йдуть назустріч — тому єдиному водієві, який виклик узяв.

Одна поступка, названа прямо на екрані: пошук адрес, побудова маршруту й плитки карти звертаються до OpenStreetMap — єдине місце, де DUCAT відправляє місцеперебування за межі пристрою. Самі дошки ніколи не несуть точність краще ніж ~1,2 км.

Виклик поїздки: маршрут, відстань, час і тариф проти того, що взяв би агрегатор
Виклик, у порівнянні з агрегатором
Лічильник: тариф набрано один раз, код посадки, умови приходять у чат на старті
Лічильник, з умовами прямо в гілці

Продайте, здайте в оренду або запропонуйте годину свого часу

Та сама механіка дощок несе не лише поїздки. Оголошення на ринку, оренда чи година вмілої допомоги вивішуються на дошку, адресовану районом, і незнайома людина поблизу читає її, і ніхто з вас двох не торкається жодної платформи.

Оголошення живуть на більших дошках, ніж виклики — близько п'яти кілометрів упоперек, бо по в'язку ключів люди готові проїхати. Пошук читає вашу дошку й кільце навколо, малюючи результати в міру відповідей, тож щось припарковане поруч з вами з'являється на екрані менш ніж за шість секунд, тоді як «тут нічого не виставлено» займає близько сорока й дорогою позначає перевірені райони.

Перегляд ринку: оголошення, знайдене на дошці, з ціною, заставами та кнопкою запитати
Ринок
Перегляд допомоги: уміння, запропоноване поруч, з ціною за годину
Найняти допомогу
Виставлення автомобіля в оренду: публічна половина, що йде на дошку
Публічна половина — те, що дошка може прочитати
Лише для того, хто забронює: адреса й деталі передання ніколи не потрапляють на дошку
Приватна половина — ніколи на дошці
Пошук спорядження поруч: живе оголошення з ціною за день і заставою
Знайти — ціна, застава й спосіб запитати

Форма оголошення розрізана надвоє, і застосунок каже, яка половина яка: усе з першої частини йде на публічну дошку, яку може прочитати будь-хто поблизу, а адреса, місце, де лежать ключі, і номер авто йдуть у другу, яка не покидає ваш телефон, доки бронювання не стане справжнім.

Дім, стрічка
і власна полиця

Записи, що несуть рахунок, так само добре несуть сторінку. Твій ключ уже сам по собі адреса, тож написаному є де жити, ні в кого не просячи місця.

Стрічка: дописи людей, яких ти тримаєш, і твій власний дім
Стрічка — дописи людей, яких ти тримаєш
Бібліотека: випуски, розкладені за видавцями, збережені назовні, а не відкриті
Бібліотека — випуски, розкладені за видавцями
Увесь світ: видання на тематичних дошках, де «Усе» читає кожну полицю разом
Увесь світ — тематичні дошки, усі полиці разом
Відкрите оголошення: світлини з його набору, опис продавця, набрана ціна поряд із сьогоднішнім курсом
Відкрите оголошення — його світлини й набрана ціна

Дім персони стоїть за адресою, яку називає її власний ключ, а стрічка — це хронологія людей, яких ти тримаєш: допис може нести картинку й файл, а серця повертаються. Сайти роздає з власного диска той, хто їх опублікував, і відкриваються вони в запечатаній кімнаті, тож читання одного нічого не тягне звідкись іще.

Видання — газета, серія, програма — продаються по всьому світу на тематичних дошках, а не за районом: допис лягає і на дошку теми, і на дошку своєї мови, а «Усе» читає всі шість полиць поруч. Оголошення забирає свій набір із телефона продавця — до 24 світлин у повний розмір, опис, характеристики й вкладені файли — і цілком відхиляється на будь-якому ключі, якого не називає, щоб поганий документ не міг сховати добрі світлини.

Ви обоє вносите заставу.
Доведете до кінця — вона повернеться.

Посередині немає компанії, яка могла б стати на чийсь бік, тож DUCAT робить простіше. Гроші лежать за адресою, яку можете відкрити тільки ви вдвох, а розблокування повертає кожній стороні її власну заставу, поіменно. Забрати заставу не може ніхто — включно з нами, бо немає жодних нас, кому платити.

~10 % поїздка коротка, мало ризику шкоди
~20 % ночівля ключі від чийогось дому
~30 % автомобіль шкода може перевищити ціну

Ці числа обґрунтовані, а не вгадані — модель Bisq «2 з 2» без зберігача це найближчий робочий прецедент, а література про подвійний депозит доводить, що в рівновазі схема захищена від обману. Звідси дві межі: застава, що коштує менше за комісію за її повернення, стає нулем, а не оздобою, і жодна не перевищує половини ціни. Вразливіша сторона вносить другою, щоб її гроші ніколи не лежали в спільній адресі самі.

⅔

Ескроу, за яким не стоїть жодна компанія

Коли угода потребує більшого, ніж застава: пасажир, водій і взаємно довірений контакт-арбітр проводять запечатаною гілкою розподілену генерацію ключів — три пристрої виводять одну адресу Monero, кожен тримає лише частку, будь-які двоє можуть підписати, і ніде немає роздавача. Щасливий шлях — два дотики.

Усе інше — угода: одна сторона пропонує поділ, друга підписує або пропонує зустрічне. Хто застряг, звертається до арбітра, чий підпис і є рішенням — захоплений арбітр у найгіршому разі може обрати між названими сторонами, але ніколи заплатити собі. Доведено в ланцюгу, на stagenet, у всіх формах, включно зі звільненням FROST з двома входами.

∅

Чого коштувало ім'я

Перш ніж з'явиться будь-яка угода, є незнайомець, і питання в тому, чого коштувало йому його ім'я. Персона може спалити Monero — надіслати їх на адресу, ключів від якої немає ні в кого, виведену з хешу, який кожен може перерахувати сам, — і нести при цьому власний доказ платежу Monero. Ваш клієнт перевіряє цей доказ на власному вузлі, питає другий вузол, чи потрапила транзакція в блок, і відтоді показує персону словами скрізь, де ви щось вирішуєте: спалено 0,01 XMR, з блоку N. Ніколи оцінкою. Правило, яке важить, — це попередження: коли те, чим ви збираєтеся ризикнути, варте більше, ніж вони спалили, застосунок так і каже, бо імені, яке нічого не коштувало, нічого втрачати, зникаючи.

Після закритої угоди будь-яка зі сторін може підписати чек з оцінкою, а кожен, кого ви зустрічали особисто, може підписати поручительство. І те й те їде запечатаною гілкою, і те й те зважує лише той, хто читає — один голос на підписанта, рахуючи тільки тих підписантів, чиє власне спалення ви перевірили, і рахуючи поручительство лише від людей, які вже є у ваших контактах. Один крок, жодного графа, ніде нічого не опубліковано. Репутація, яка коштує грошей, а не приватності.

І поводиться як застосунок

Інструментом приватності, яким неприємно користуватися, користуються один раз. Цей називає, у що вам обходяться речі, говорить двадцятьма мовами й має темну тему, зроблену не навздогін.

Профіль: ціна пов'язуваності, якщо дозволити контактам платити напряму, названа там, де ви обираєте
Ціну названо в мить вибору
Той самий головний екран у темній темі Mocha
Mocha — темна тема, зроблена як слід
Той самий головний екран арабською: повне дзеркало справа наліво, зі східноарабськими цифрами
Арабська — повне дзеркало справа наліво
Ділова половина налаштувань: тарифний регіон, ставка податку, приватність, резервна копія
Ділова половина налаштувань

У зручності в системі приватності є ціна, і застосунок називає її в мить вибору, а не в правилах, яких ніхто не читає. Дозволити контактам платити вам напряму означає повторно використовувати одну адресу — тож він каже, що будь-хто, хто спостерігає за ланцюгом, побачить, що щоразу платили одній і тій самій людині, включно з тими, хто заплатив вам лише раз, і вказує на альтернативу. Та сама звичка проходить наскрізь: помічене в mempool показується як побачено, але не розраховано; профіль завжди подається як твердження, яким він і є.

Він говорить двадцятьма мовами — кожен екран читає з ресурсів, форми множини складаються, а не склеюються, а арабська й фарсі доводять дзеркало. Чеки — це записи, а не повідомлення: кожен чек живе у власному сховищі, переживає видалення гілки й контакту та їде в зашифрованій резервній копії — яка несе людей так само, як і гроші.

Той самий застосунок на столі

Нативне вікно поверх того самого Rust, що працює на телефоні, — тож каса крамаря, кіоск, прес-кімната, ринок і стрічка виявляються однією реалізацією, а не портом.

Сторінка чату на столі: групи на дошках над парними гілками, з панеллю розмови
Чат — групи на дошках, над парними гілками
Каса на столі: пробитий продаж і відкриті рахунки
Каса — пробитий продаж і відкриті рахунки
Сторінка ринку на столі: оголошення поруч із коміркою з їхніми мініатюрами
Ринок — оголошення поруч із коміркою, з мініатюрами
Сторінка стану на столі: вузол, його таблиця маршрутів, Перепідключити, журнал
Стан — вузол, його таблиця маршрутів, Перепідключити

Він говорить двадцятьма мовами телефона з тих самих ресурсів і перевірений проти телефона в кожному обряді: чат, групи на дошках, рахунки й чеки, замовлення в кіоску, оплачене з телефона, який зі столом раніше не зустрічався, файли й сайти, роздані та отримані, і дзвінки зі справжнім звуком.

Що доведено, а що ні

README веде облік того, що справді пройшло від початку до кінця у справжній мережі та на справжньому stagenet — і називає прогалини, а не закопує їх.

Показано від початку до кінця
  • Дві повні розподілені поїздки телефон↔комп'ютер — від виклику через геокомірку до розрахунку в ланцюгу, чайові й чек — а поїздку із заставою тепер доведено до кінця й на двох телефонах
  • Повна дуга ескроу — два телефони й арбітр за столом незалежно вивели одну адресу «2 з 3»; внести → звільнити → водій отримав гроші
  • Бронювання — господар і гість вносять кожен свою заставу, банк підтверджено власним скануванням гостя, поділ запропоновано, підписано, обидві сторони цілі; воно продовжилося, а не почалося заново, коли посеред прогону вузол Monero не відповів вчасно
  • Відкритий рахунок з телефона на комп'ютер, від рахунку до чека; десять атак відхилено
  • Телефон, стертий дощенту, пройшов налаштування: перша картка, перший платіж, продаж у кіоску, оплачений від початку до кінця, — а потім знову стертий і відновлений із власної копії
  • Усі рейки ескроу через інтерфейс за один день — продаж на ринку, вуличний виклик із живою позицією, що переходить між телефонами, оренда спорядження і замовлення допомоги, перший прогін якого виявив і полагодив справжні перегони
  • Шар довіри, пройдений, а не доведений на словах — спалення доведено й перевірено на власному вузлі незнайомця за 12 с, чек з оцінкою правильно зважено в нуль, чотири комп'ютери дійшли висновку «2 ваших контактів їх знають», і безіменна картка виклику, якій ім'я дали дані, якими поділилися слідом
Сказано, а не закопано
  • Жодної перевірки кимось поза проєктом — §2.5 і є доказ того, чому це важить; внутрішній прохід по п'яти поверхнях атаки знайшов сорок з гаком речей і полагодив більшість, що важить менше
  • Немає розробника, який ніколи не читав core/
  • NFC перевірено на компіляції, жодного разу не випробувано в полі між двома телефонами — і сам дотик жодного разу не виміряно на телефоні
  • Затримки виміряно на комп'ютері з під'єднаним вузлом, а не на телефоні від батареї
  • Дві рації, дві батареї, двоє незалежних годинників — польовий день усе ще за нами
  • У комп'ютера немає другого фактора — ні блокування пристрою, ні власного секрету, тож перевірка, яку телефон ставить перед витратою, там працювати не може
!

Пре-альфа. Stagenet. Не для справжніх грошей.

Кожна збірка підписана в режимі налагодження й розраховується на stagenet Monero — монети без вартості, так задумано. Специфікація це чернетка 1.1.0-dev13, і вона каже про себе: ніщо тут не остаточне, а §14 — справжній порядок денний. Спробуйте її, зламайте, прочитайте — тільки не фінансуйте.

Специфікація і є продуктом.
Усе інше тримає її чесною.

ducat-protocol.md — головний артефакт: п'ять частин, журнал змін попереду та набір тестів відповідності, який проганяє друга реалізація, щоб документ не міг мовчки розійтися з кодом.

★ ducat-protocol.md   специфікація — чернетка 1.1.0-dev13, зміни попереду
  core/               еталонна реалізація (Rust)
  vectors/            406 випадків відповідності + схема
  conformance/        чотири перевіряльники, на кожен push
  harness/            від початку до кінця справжніми маршрутами Veilid
  sim/                офлайн-симулятор, ринкові сценарії
  applications/       android/ + desktop/ (ті самі джерела)
  mobile/             міст на Rust: гаманець · поштова скринька · вузол
  research/           докази, а не продукт

Чотири перевіряльники, на кожен push

  • Кожен вектор перевірено за schema.json
  • Друга реалізація проганяє всі 406 і мусить збігтися
  • Документ звірено з кодом — так знайшовся нормативний розділ, на який посилалися тричі й який ніколи не було написано, діапазон значень, не оголошений реєстром, і шість видів векторів, яких документ жодного разу не назвав
  • Ніщо імпортоване не лишається незадекларованим

Відповідальність нормативна, а не бажана: §18.7 робить етику Veilid вимогою відповідності — жодних комісій протоколу, жодної оплати вузлам, ніколи. Будуйте з цього коду що завгодно, але клієнт, який заробляє на перенесенні, — не DUCAT.

Поставте на телефон
або на стіл

Нічого не треба ставити заздалегідь — кожна збірка несе власну бібліотеку Rust і JVM. Android на телефоні й той самий застосунок нативним вікном у Linux, Windows і macOS. Збірки для iOS немає; вона дістане теку, коли її заслужить.

🤖 Android

Браузер телефона, найсвіжіша збірка, жодної сторінки релізів. armeabi-v7a лише для телефонів, старших за приблизно 2016 рік; x86_64 — для емуляторів.

🐧 Linux

.deb і .rpm встановлюються пакунками; AppImage просто запускається.

🪟 Windows

Без підпису — Windows попередить при першому відкритті.

🍎 macOS

Збірки для Apple Silicon та Intel. Без підпису — macOS попередить при першому відкритті.

Підписано в режимі налагодження, лише stagenet — не для справжніх грошей.