Хранилище DApp для данных, отличных от транзакций?

Для иллюстрации предположим, что я хотел бы создать децентрализованную версию Yelp.

Централизованный подход состоял бы в том, чтобы иметь restaurantsтаблицу и reviewsтаблицу в базе данных Mysql. В случае DApp, как лучше всего хранить нетранзакционные данные?

В настоящее время я думаю о Restaurant.solконтракте и Review.solконтракте, каждый из которых имеет сопоставление идентификатора записи в качестве ключа с объектом записи в качестве значения. Каждый раз, когда добавляется ресторан, мы вызываем addRecord()метод в Restaurant, который добавляет новые данные ресторана к его текущему отображению. (аналогичный поток для Review)

Надежен ли такой подход к работе с контрактом как с таблицей РСУБД? Или я что-то упускаю?

Каков предел объема данных, которые могут храниться при отображении контракта?

РЕДАКТИРОВАТЬ: насколько я понимаю, изменение отображения Restaurantконтракта будет стоить эфира. Значит, каждая новая запись, добавляемая в «базу данных», стоит денег? Каков экономически выгодный способ запустить приложение, не требуя от пользователей оплаты?

Пожалуйста, порекомендуйте.

Вы смотрели на IPFS: ipfs.io

Ответы (2)

Во-первых, вы не хотите думать о контрактах как о таблицах. Каждый контракт может содержать несколько отображений информации. У вас может быть один файл ReviewSystem.sol, в котором есть сопоставления как для ресторанов, так и для обзоров, и в соответствии с тем, что вы предлагали ранее, вы могли бы иметь addRestaurant()и addReview()методы, которые добавляли бы записи к сопоставлениям, хранящимся в контракте.

Тем не менее, контракты не имеют очень хороших механизмов для нормализованных реляционных данных. В реляционной базе данных, если у вас есть запись «Ресторан», вы можете выполнить запрос для всех отзывов, относящихся к определенному ресторану, и с помощью индексов и планировщиков запросов получить эту информацию очень быстро. В Ethereum ваши возможности более ограничены. Если у вас нет индекса, вам придется просмотреть каждый отзыв в вашей системе, чтобы увидеть, относится ли он к рассматриваемому ресторану. Если у вас есть индекс, вы увеличиваете затраты на внесение записей в ваш контракт. Вы также можете денормализовать данные для более быстрого поиска, опять же за счет увеличения хранилища контракта.

Один из вариантов — сохранить часть вашей информации вне сети. Например, вы можете сохранить свои рестораны и обзоры в своем контракте с помощью указателя с обзора на ресторан. Отдельно у вас может быть традиционная база данных, которая индексирует связь между отзывами и ресторанами. Когда кто-то добавляет обзор через ваше DApp, в контракте сохраняется каноническая информация, а в отдельной базе данных хранится копия этой информации. Когда кто-то хочет найти отзывы, относящиеся к определенному ресторану, он может запросить API, поддерживаемый базой данных, который может быстро вернуть идентификаторы отзывов, и они могут сами получить отзывы из блокчейна. В этом случае вся важная информация доступна в сети, а индекс вне сети может быть восстановлен из состояния контракта. Чтобы узнать об отслеживании событий контракта вне цепочки,События и журналы .

Как вы отметили в своем редактировании, каждая часть информации, которую вы сохраняете в контракте, стоит газа, а этот газ, в свою очередь, стоит эфира. Запуск такого сервиса, как Yelp, с сотнями тысяч компаний и отзывами в тысячу слов может оказаться очень дорогим. Вы можете уменьшить некоторые расходы, храня больше информации вне сети. Возможно, ончейн-отзыв состоит из звездного рейтинга и хэша письменного отзыва, затем текст отзыва извлекается из внешнего источника, такого как база данных, которую мы обсуждали ранее, или, возможно, из другой децентрализованной системы, такой как ipfs.

Однако в целом я рассматриваю цепочку блоков Ethereum как место, где вы храните информацию, управление которой вы не хотите доверять третьим лицам. Такие вещи, как токены ERC20, ENS и распределенные биржи, являются отличным вариантом использования, потому что в противном случае было бы трудно установить доверие к централизованному объекту. Хотя было бы неплохо иметь что-то вроде децентрализованной службы проверки, стоимость хранения контрактов в сочетании с относительно низким риском доверия третьей стороне для управления этой информацией делают его менее привлекательным вариантом использования блокчейна.

Во-первых, чтобы ответить на ваши вопросы:

«Надежен ли такой подход к работе с контрактом как с таблицей СУРБД? Или я что-то упускаю?»

Да, это надежное решение , если вы имеете в виду надежное или «будет ли оно работать каждый раз». На самом деле надежность — одна из самых привлекательных черт написания контрактов, которые работают на блокчейне Ethereum: у вас больше избыточности, чем кому-либо когда-либо понадобится. Сейчас есть 25,5xxузлы [ 1 ]. Каждый из этих узлов хранит копию ваших данных, вашего кода и выполняет каждую строку кода в вашем контракте.

«Каков предел объема данных, которые могут храниться при отображении контракта?»

На этот вопрос отвечает здесь авторитетная фигура в сообществе Ethereum, поэтому я воздержусь от ответа на него, за исключением того, что скажу, что либо у вас, вероятно, не так много данных, либо, конечно, вы не можете позволить себе хранить столько, сколько может блокчейн». брать". Тем не менее, поскольку каждый узел хранит копию данных блокчейна, если бы вы могли себе это позволить, вы бы обременяли каждый из узлов и, возможно, создавали бы меньше узлов, поскольку запуск узла стоил бы дороже, потому что размер данных был бы таким большим. огромный.

«Насколько я понимаю, изменение отображения контракта Ресторана будет стоить эфира. Значит, каждая новая запись, добавляемая в «базу данных», стоит денег?»

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

Каков экономически выгодный способ запустить приложение, не требуя от пользователей оплаты?

У вас есть несколько вариантов:

  1. ~~Заряжайте своих пользователей газом~~
  2. Компенсируйте своих пользователей дополнительными единицами собственного токена приложения, если у вас есть гибкая поставка вашего токена.
  3. В организации, которую я вношу, мы храним хеш, который является криптографическим доказательством данных вне сети, и мы храним только хэш IPFS в цепочке. Хэши IPFS, к сожалению, больше, чем 32-байтовое слово EVM (см. этот очень информативный ответ о хранении хэшей IPFS в цепочке в структуре).
    • Что интересно в этом решении, так это то, что пользователи могут позже независимо проверить данные, на которые указывает хэш, и что они должны были быть фактически сохранены в цепочке, запустив ту же хеш-функцию для возвращенных данных.

Выводы для хранения данных Ethereum/Dapp

  • Хранение данных в сети очень дорого по сравнению с централизованными решениями.
  • Хранение 1 кБ стоит 640,000газа
  • 640,000расходы на газ $0.08- $0.90с использованием текущих цен на эфир в зависимости от того, как быстро вы хотите, чтобы ваша транзакция была добыта/подтверждена
  • Если цена эфира продолжит расти, цена хранения ваших данных будет расти вместе с ней, при условии, что не произойдет соразмерного снижения цены принятого газа, которую майнеры готовы брать.
  • Каждое изменение в блокчейне, каким бы малым оно ни было, стоит газа (или «денег» на традиционном языке).

    • Например, отправка эфира встроенным send()методом стоит 21,000газа .
    • Из желтой бумаги 4 : Gtransaction 21000 Paid for every transaction.Таким образом, каждая передача стоит как минимум 21,000-- это минимальная стоимость.
  • Однако получение данных из блокчейна бесплатно:

    • Мы можем получить данные из блокчейна несколькими способами:
      • Getter-функции , которые автоматически создаются для нас для каждой publicпеременной в наших контрактах
        • Например, строка: uint public numRestaurants = 42;создает функцию, которую мы можем вызвать из нашего контракта .this.numRestaurants()
        • В web3клиенте мы могли бы вызвать эту функцию с помощьюcontractInstance.numRestaurants.call()
      • Контрактные функции , которые обещают не изменять состояние, могут быть объявлены constantили viewфункции
        • function f(uint a, uint b) view returns (uint) { return a * (b + 42) + now; // does math but doesn't change state! }
      • События — это данные, которые хранятся в блокчейне.
        • LogUpdateRestaurant('mandalay', 8.7, 'restaurant')в функции, которая будет хранить данные вашего ресторана
        • Мы определяем события с помощьюevent LogUpdate(indexed string restaurantName, uint8 rating, TypeEnum type);

    Я расскажу больше о том, как мы подошли к хранению наших данных в почти полностью децентрализованном приложении, позже. И спасибо, что научили меня тому, что я узнал, написав этот ответ (например view, теперь это псевдоним для constant)