Вы здесь

Метод конфиденциального перевода токенов в Эфириуме

Эфириум не является частным блокчейном. Каждый раз, когда вы переводите токены ERC20 или любой другой цифровой актив, информация может просочиться третьим лицам. Они могут узнать вашу полную финансовую историю, просто зайдя на Etherscan, Blockscout или любой другой блокчейн-обозреватель.

Метод конфиденциального перевода токенов в Эфириуме

Однако не стоит пугаться: есть способы предотвратить утечку. Во-первых, вы могли бы использовать сразу несколько счетов, но для этого вам пришлось бы постоянно следить за тем, чтобы эти счета не пересекались. Для админа это был кошмар наяву. А что, если бы существовал более изящный программируемый способ?

Представляю вашему вниманию AZTEC: протокол конфиденциальности, построенный на базе Эфириума. В этой статье я не буду акцентировать внимание на криптографии, лежащей в основе этого протокола, а сфокусируюсь больше на его практическом применения, а именно: конфиденциальном переводе токенов.

Отказ от ответственности: я работаю в AZTEC в качестве штатного инженера по программному обеспечению.

Необходимые условия

В контексте этой статьи я буду считать, что у вас уже имеется базовое понимание, что такое:

Убедитесь, что на вашей машине стоит node.js и npm и установите Truffle:

$ npm install truffle --global

Ментальные модели

Давайте здесь остановимся и рассмотрим основные технические составляющие.

Протокол

Эфириум – это, условно говоря, деревня, а AZTEC – лес.

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

Картинка ниже – это моя несколько «корявая» попытка визуализировать идею AZTEC. Все происходящее в обычной среде (Эфириум) кристально ясно, но что происходит за ее пределами – скрыто за семью печатями, в нашем случае – лесом (AZTEC).


Примечания

Примечанием в AZTEC является объект, поддерживающий все операции, которые по сути доступны другим объектам (т.н. first-class citizen), и основным примитивом (т.е. операцией) в этом протоколе. Когда вы совершаете сделки с нулевым разглашением, смарт-контракты не хранят какие-либо балансы, а вместо этого работают с точками эллиптической кривой, которые являются просто вычислительным шумом для всех, у кого нет закрытых ключей.

Очень важно провести различие между ERC20 и ERC1724 – стандартами для конфиденциальных токенов в AZTEC. Первый хранит сопоставление между адресами Эфириума и незашифрованными балансами. Последний шифрует балансы. Я нахожу любопытным сравнение примечаний в AZTEC с небольшими входящими платежами, являющимися неизрасходованными выходами в сети Биткоина (так называемыми Bitcoin UTXOs), так как процесс расходования средств в AZTEC очень похож.

Содержание примечаний, которые классифицируются по степени открытости:

Поскольку времени в обрез, мы не станем окунаться в криптографию. Если вы хотите получить больше информации, ознакомьтесь с нашей презентацией.

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

Погнали!

Скопируйте файл в этом файлохранилище и установите модули узла:

$ git clone [email protected]:PaulRBerg/confidential-tokens.git
$ cd confidential-tokens
$ npm install

Если у вас будет много подробных текстовых файлов, связанных с "scrypt" и "keccak", это прекрасно, потому что нам необходим aztec.js, которому требуется файл web3.js, у которого впоследствии будет много криптографических зависимостей.

Перед тем, как запустить демо-версию, нужно выполнить несколько важных шагов:

  1. Создайте файл accounts.js внутри папки src. Всего необходимо установить два счета. В качестве примера приведен счет под названием accounts.js.example.
  2. Создайте файл .env в корне проекта и заполните его данными, приведенными ниже. Опять же, есть пример такого файла, названный .env.example.
  3. Разверните контракт на конфиденциальные токены в Rinkeby. Для этого вы можете воспользоваться Truffle:
$ truffle migrate --network rinkeby

Переменные окружения:

АДРЕС КОНФИДЕНЦИАЛЬНОГО ТОКЕНА: учтите, что фактическое имя контракта – ZKERC20; вы получите его после того, как truffle развернет контракт
МНЕМОНИКА
INFURA_API_KEY

Теперь убедитесь, что ваш проект выглядит следующим образом:

.png

Запускайте демо-версию:

$ npm run demo

На это уйдет некоторое время, потому что транзакции отправляются в Rinkeby. Через несколько минут в консоли должен быть напечатан список квитанций. Ура, вы только что выполнили свою первую конфиденциальную передачу токенов в Эфириуме.

Теперь давайте рассмотрим исходный код в src/demo.js.!

Создание примечаний

aztecAccounts = [...new Array(2)].map(() => aztec.secp256k1.generateAccount());
  notes = [
    aztec.note.create(aztecAccounts[0].publicKey, 5),
    aztec.note.create(aztecAccounts[0].publicKey, 5),
    aztec.note.create(aztecAccounts[1].publicKey, 8),
    aztec.note.create(aztecAccounts[0].publicKey, 2)
  ];

Шаги:

  1. Сгенерируйте серию случайных счетов. Мы должны использовать «secp256k1», потому что AZTEC нужны открытые ключи от счетов, а не только их адреса.
  2. Создайте 4 примечания, причем первые два должны относиться к первому счету, а последние два присваивают 8 токенов от начального общего количества (10) второму счету.

Чтобы лучше понять Шаг 2, вспомните, что примечания в AZTEC по своей природе похожи на UTXOs в Биткоине. Когда человек переводит деньги, оставшиеся суммы должны быть преобразованы в новый набор примечаний: в этом состоит отличие от канонических транзакций в Эфириуме, которые используют модель баланса.

Кроме того, я отделил счета, используемые в Эфириуме (те, что находятся в src/accounts.js) от случайно сгенерированных счетов AZTEC (демо-скрипт генерирует файл под названием aztecAccounts.json).

Создание доказательств

proofs[0] = aztec.proof.joinSplit.encodeJoinSplitTransaction({
    inputNotes: [],
    outputNotes: notes.slice(0, 2),
    senderAddress: accounts[0].address,
    inputNoteOwners: [],
    publicOwner: accounts[0].address,
    kPublic: -10,
    aztecAddress: joinSplit.options.address,
  });

Объект доказательства выше:

  1. Свидетельствует о том, что publicOwner готов перевести 10 токенов ERC20 в форму AZTEC
  2. Делает первый случайно сгенерированный счет AZTEC новым владельцем (напомним, что первые два примечания стоят по 5 токенов и оба принадлежат этому счету в AZTEC)
proofs[1] = aztec.proof.joinSplit.encodeJoinSplitTransaction({
    inputNotes: notes.slice(0, 2),
    outputNotes: notes.slice(2, 4),
    senderAddress: accounts[0].address,
    inputNoteOwners: [aztecAccounts[0], aztecAccounts[0]],
    publicOwner: accounts[0].address,
    kPublic: 0,
    aztecAddress: joinSplit.options.address,
  });

Второе доказательство:

  1. Переводит 8 токенов на второй счет AZTEC в полномасштабной форме с нулевым разглашением (так называемой fully-fledged zero-knowledge)
  2. Сжигает первые два примечания во избежание в будущем повторного их использования в первом счете AZTEC
proofOutputs = proofs.map(({ expectedOutput }) => {
    return aztec.abiEncoder.outputCoder.getProofOutput(expectedOutput, 0);
  });
  proofHashes = proofOutputs.map(proofOutput => {
    return aztec.abiEncoder.outputCoder.hashProofOutput(proofOutput);
  });

Мы должны взаимодействовать с контрактом под названием «NoteRegistry», который является уникальным для каждого контракта на конфиденциальные токены. Вы можете рассматривать proofHashes как массив уникальных идентификаторов для ранее сгенерированных доказательств.

Согласование

for (let i = 0; i < accounts.length; ++i) {
    const data = erc20Mintable
      .methods
      .approve(noteRegistry.options.address, scalingFactor.mul(tokensTransferred).toString(10))
      .encodeABI();
    await sendTx({
      from: accounts[i].address,
      to: aztecAddresses.erc20Mintable,
      data: data,
      privateKey: accounts[i].privateKey,
    });
  }

Мы «чеканим» серию токенов и даем разрешение NoteRegistry на списание средств с контракта на ERC20.

const delta = 10;
  let data = noteRegistry
    .methods
    .publicApprove(proofHashes[0], delta)
    .encodeABI();
  await sendTx({
    from: accounts[0].address,
    to: noteRegistry.options.address,
    data: data,
    privateKey: accounts[0].privateKey,
  });

По аналогии с ERC20, NoteRegistry должно быть предоставлено разрешение на работу с доказательствами AZTEC. Должны признаться, что это часть требует дальнейших изучений, и мы ищем способы сделать UX более удобным.

Перевод

let data = confidentialToken
    .methods
    .confidentialTransfer(proofs[0].proofData)
    .encodeABI();
  await sendTx({
    from: accounts[0].address,
    to: confidentialToken.options.address,
    data: data,
    privateKey: accounts[0].privateKey,
  });
  data = confidentialToken
    .methods
    .confidentialTransfer(proofs[1].proofData)
    .encodeABI();
  await sendTx({
    from: accounts[0].address,
    to: confidentialToken.options.address,
    data: data,
    privateKey: accounts[0].privateKey,
  });

Наконец, самая интересная часть: для перевода вам нужно вызвать контракт на конфиденциальные токены. Обратите внимание, что первая транзакция только преобразует токены ERC20, поэтому третьи стороны могут узнать, сколько токенов было переведено. Однако вторая транзакция является полностью конфиденциальной.

Вот визуализация того, что мы только что сделали:


Подводные камни

  • Для этого пособия использовалась надежная программа установки, которая была создана силами нашей команды. Мы дадим больше информации о поколении надежных программных продуктов в ближайшее время. Риски за их использование вы берете на себя.
  • Требуется масса предварительных согласований до того, как могут быть инициированы переводы конфиденциальных токенов. Как уже упоминалось ранее, это то, над чем мы работаем и с нетерпением ждем улучшений.
  • Кодовая база AZTEC может претерпеть ряд важных изменений после публикации этой статьи. Но не стоит беспокоиться: в этом пособии используются точные версии пакетов npm во избежание сбоев.
  • AZTEC использует Solidity 0.4.24, поэтому вы должны использовать совместимую версию OpenZeppelin, то есть 2.0.0
  • Когда в контрактах AZTEC есть только один пользователь, происходит утечка конфиденциальных данных. Третьи лица могут сделать вывод о том, сколько денег депонируется из-за публичного характера ERC20 — они могут сравнить это количество с общей суммой, хранящейся в договоре. Чем больше пользователей присоединяется, тем выше конфиденциальность.

Пакеты

Вот полный список «плюшек» AZTEC, которые мы использовали:
1.aztec.js
2.@aztec/contract-addresses
3.@aztec/contract-artifacts
4.@aztec/dev-utils
5.@aztec/protocol

Исходный код для них всех доступен в нашем моно-репозитарии. Смело пишите нам в Twitter или по электронной почте [email protected], если у вас возникнут какие-либо вопросы!

Напоследок

Я надеюсь, что вам понравилась эта обучающая статья и вас также интересуют конфиденциальные транзакции, как и меня. Проверьте вот эти транзакции, которые используют несколько доказательств AZTEC для преобразования 10 токенов ERC20 в полноценную форму с нулевым разглашением:

Категория: 
Tutorial
Монета: 
2
Ваша оценка: Нет Средняя: 2 (1 оценка)
17494 / 0
Аватар пользователя Daritas
Публикацию добавил: Daritas
Дата публикации: пн, 03/18/2019 - 13:58

Что еще почитать: