Cool Crypto - отправка значения по ссылке
В последнее время я помогал в разработке приложения-кошелька для записи с открытым исходным кодом, созданного Остином Томасом Гриффитом. Идея заключалась в том, чтобы попытаться создать приложение, которое могло бы обмениваться ценностями с помощью мобильного веб-браузера. Он торгует сложностью и передовыми методами хранения закрытых ключей, загрузки приложений и т. Д., Чтобы просто сделать что-то, что должно быть простым для начала работы и простым в использовании.
Одна из функций, которые мне показались наиболее интересными, заключалась в возможности отправить какое-либо значение, в данном случае xDai, кому-либо, используя ссылку (попробуйте приложение здесь). Функциональность, лежащая в основе этого метода, довольно крутая и использует множество фундаментальных принципов web3 / crypto. Мне было интересно вникнуть в это, и я подумал, что им стоит поделиться.
Начать
Прежде всего, Dapp на самом деле не `` отправляет '' xDai, это скорее шаблон депозита / требования с некоторой классной криптографией, используемой, чтобы убедиться, что только человек с правильной информацией, предоставленной отправителем по ссылке, может требовать Значение.
Во-вторых, есть две части - веб-приложение и смарт-контракт на блокчейне. Веб-приложение Dapp - это действительно хороший способ взаимодействия со смарт-контрактом.
Шаг за шагом
Пошаговое описание помогло мне вбить это в голову. Обратите внимание, что я не показываю здесь все детали кода, это более высокоуровневое описание, показывающее концепцию.
Отправка
Используя Dapp, «отправитель» вводит сумму, с которой он хочет отправить, и нажимает «Отправить».
После отправки Dapp выполняет небольшую работу в фоновом режиме, чтобы получить данные, необходимые для настройки смарт-контракта.
Dapp использует web3.js для хеширования случайных данных:
let randomHash = web3.utils.sha3("" + Math.random());
Теперь Dapp использует web3.js для создания случайной учетной записи, которая будет иметь закрытый ключ и открытый ключ:
let randomWallet = web3.eth.accounts.create();
Затем случайные хешированные данные подписываются с использованием случайного закрытого ключа кошелька (подробнее о подписании и т. Д. См. Ниже):
let sig = web3.eth.accounts.sign(randomHash, randomWallet.privateKey);
Dapp отправляет транзакцию в смарт-контракт блокчейна со значением, равным сумме, которая отправляется вместе с подписью и хешированными данными:
Contract.send(randomHash, sig.signature), 140000, false, value ... // This is just a pseudo code to give the gist, see the repo for the full code
Смарт-контракт содержит отображение структур фонда на ключи идентификатора bytes32:
struct Fund { address sender; address signer; uint256 value; uint256 nonce; bool claimed; } mapping (bytes32 => Fund) public funds;
Когда Dapp «отправляет» значение, смарт-контракт создает новую структуру фонда с полем подписывающей стороны, установленным на открытый ключ случайного кошелька, созданного Dapp. Это поле важно, поскольку оно используется для проверки при подаче претензии:
newFund = Fund({ sender: msg.sender, signer: randomWallet.publicKey, value: msg.value, nonce: nonce, claimed: false })
Теперь newFund отображается с использованием значения randomHash в качестве ключа:
funds[randomHash] = newFund;
XDai от отправителя был отправлен в смарт-контракт и готов к востребованию любым, у кого есть необходимая информация.
Наконец, Dapp генерирует ссылку с randomHash и случайным закрытым ключом кошелька в качестве параметров ссылки:
Link Format: xDai.io/randomHash;privateKey
Затем ссылку можно скопировать и отправить через WhatsApp, SMS и т. Д.
Заявление:
Здесь, вероятно, стоит отметить, что ссылка на самом деле просто хороший способ поделиться важной информацией, необходимой для получения xDai. Dapp также выполняет тяжелую работу по взаимодействию со смарт-контрактом блокчейна.
Когда ссылка посещается, Dapp анализирует randomHash и privateKey из ссылки.
Затем он подписывает сообщение, используя privateKey из ссылки:
let accountHash = web3.utils.sha3(claimAccount); let sig = web3.eth.accounts.sign(accountHash, privateKey);
Теперь функция заявки смарт-контракта вызывается с использованием подписи и исходных данных:
Contact.claim(accountHash, sig, randomHash, claimAccount)
Функция Solidity ecrecover используется для получения публичного адреса из подписи (это волшебство, см. Информацию ниже):
address signer = recoverSigner(accountHash, sig);
Наконец, смарт-контракт проверяет фонд с совпадающим ключом. RandomHash имеет «подписывающего», равного адресу, восстановленному из подписи. Если это так, он может отправить значение на счет заявителя:
if(funds[randomHash].signer == signer && funds[randomHash].claimed == false){ funds[randomHash].claimed = true; claimAccount.send(funds[randomHash].value); }
Фух, вот и все! Кажется, что многое происходит, но по сути, это разумный способ для пользователя сохранить ценность в смарт-контракте, который может быть заявлен только с правильной информацией, не показывая, что эта информация находится в общедоступной цепочке блоков.
Крутая криптография
Подписание, ecrecover, а что ??? Есть вещи, о которых, вероятно, стоит рассказать подробнее.
Кошельки, счета и т. Д.
Аккаунт, созданный с помощью web3.eth.accounts.create()
, имеет собственный закрытый ключ и открытый ключ. Более подробную информацию можно найти в документации и здесь. Закрытый и открытый ключи связаны через алгоритм, который имеет свойства подписи и проверки.
Подписание и проверка
Ниже приводится очень краткое изложение этого полезного сообщения.
Подписание - это действие пользователя, «подписывающее» данные, которые может подтвердить любой, кто пришел от этого пользователя.
Функция подписи примет закрытый ключ и данные. На выходе будет другая строка, которая является подписью.
Для проверки подлинности подписи от владельца закрытого ключа требуются подпись, исходные данные и открытый ключ.
Запускается функция валидатора, которая восстанавливает открытый ключ из подписанных данных.
Затем восстановленный открытый ключ сравнивается с исходным, и, если оба они одинаковы, подпись действительна.
Ecrecover
В этом случае функция Solidity ecrecover (Восстановление эллиптической кривой) используется для восстановления адреса, связанного с открытым ключом. Функция recoverySigner в коде смарт-контракта показывает пример того, как это делается, и this - довольно приличное объяснение того, что происходит.
Я считаю, что это отличный пример работы криптовалюты!
Получайте лучшие предложения по программному обеспечению прямо в свой почтовый ящик