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 - довольно приличное объяснение того, что происходит.

Я считаю, что это отличный пример работы криптовалюты!

Получайте лучшие предложения по программному обеспечению прямо в свой почтовый ящик