NEM Authenticator
Что такое NEM Authenticator?
NEM Authenticator - это 100% децентрализованная 2FC (2 Factor Confirmation) система на блокчейне NEM, защищающая активы/токены от кражи. Система состоит из 2х приложений:
- Веб страница (Web Page) : Создает и управляет учетными записями NEM Authenticator с помощью понятного и простого интерфейса. (Находится в стадии разработки)
- Мобильное приложение (Mobile Application): Содержит список транзакций, ожидающих подписи/подтверджения для включения в блок.
Что такое NEM?
NEM - это р2р криптовалюта и блокчейн платформа, построена на алгоритме консенсуса Proof-of-Importance (POI)
Возможности:
- Пространства имен (Namespaces)
- Мозаики/токены (Mosaics)
- Сообщения (Messages)
- Траспортация токенов (Transfer assets)
- Мультиподписные аккаунты (Multisig Accounts)
NEM Authenticator применим только для мультиподписных аккаунтов (multisig Accounts).
Как работают мультиподписные аккаунты?
Простой аккаунт инициирует транзакцию и отправляет активы. Что касается мультиподписного аккаунта, то здесь соподписанты совершают действия.
Мультиподписной аккаунт может включать до 32 соподписантов. Нужны ли все подписи соподписантов? - Нет, это указывается при создании мультиподписного аккаунта N/M , где N - это необходимое кол-во подписей, а M - общее кол-во соподписантов. Например, 1–1, 1–2, 1–64, 3–30, 30–30.
Почему важно использовать мультиподписные аккаунты?
Если кто-то украдет приватный ключ вашего обычного аккаунта, вы потеряете все свои средства окончально, игра закончилась.
Если кто-то украдет приватный ключ вашего мультиподписного аккаунта, хакер не сможет украсть ваши токены. А если ваши соподписатны находятся на том же компьютере? - Тогда вы тоже потеряете свои средства.
Решение ? - Хранить аккаунты соподписантов на разных устройствах.
NEM Authenticator полностью решает данную проблему.
Как разработан NEM Authenticator?
Использувались следующие тулы:
- NEM Library для взаимодействия с блокчейн NEM
- Ionic Framework для мобильных приложениний; iOS & Android c помощью NEM Library Ionic seed
- Angular +2 для веб-приложения с помощью NEM Library Angular seed
- TypeScript, основной язык программирования
Конфигурация мультиподписного аккаунта
Мультиподписной аккаунт имеет 2/3 структуру, нужно минимум 2 подписи для совершения транзакции.
- 2FC Account будет находится на мобильном приложении
- Main Accoun -- обычный аккаунт, Nano Wallet
- Security Account -- бэкап, необходим в случае взлома одного из аккаунтов
- Multisig Account содержит активы
Импорт 2FC Account в NEM Authenticator
Используем QR код для импорта 2FC Account в приложение NEM Authenticator. 2FC Account защищен паролем.
// https://github.com/aleixmorgadas/NEM-Authenticator/blob/master/src/pages/setup/setup-account.modal.ts
verifyAccount() {
try {
const password = new Password(this.form.get('password').value);
const qrService = new QRService();
// this.WalletQRText is the result of the QR scan
const privateKey = qrService.decryptWalletQRText(password, this.walletQRText);
const simpleWallet = SimpleWallet.createWithPrivateKey("NEM Auth Account", password, privateKey);
// Return to the previous view with the wallet imported
this.viewCtrl.dismiss({
wallet: simpleWallet,
account: simpleWallet.open(password)
})
} catch (e) {
// error visual logic
}
}
- QRService для безопасного импорта/экспорта кошелька между девайсами.
- SimpleWallet хранит кошелек локально до момента импорта.
Верификация валидности кошелька
Проверка соподписанта
// Callback of the previous code
modal.onDidDismiss((wallet: { wallet: SimpleWallet, account: Account }) => {
if (wallet != null) {
// Visual logic
// ...
/*
* We fetch the information from the imported account.
*/
new AccountHttp().getFromAddress(this.account.address).subscribe(accountMetaData => {
// Check that the account is Cosignatory of just one account
if (accountMetaData.cosignatoryOf.length != 1) {
// Show error logic
} else {
// We save the information of the imported 2FA Account and the Multisig Account
this.multisigAddress = accountMetaData.cosignatoryOf[0].publicAccount.address;
}
// Visual Logic
}, err => {
// Visual error logic
});
}
});
Ожидающие транзакции
2FC Account будет вытягивать транзакции 2 способами:
- Вытягивание транзакций во время запуска приложения
- Подтягивание транзакций во время работы приложения
@Component({
selector: 'page-home',
templateUrl: './home.html'
})
export class HomePage {
private account: Account;
unconfirmedTransactions: MultisigTransactionPlusView[];
loader: Loading;
accountPulling: Observable<MultisigTransactionPlusView[]>;
constructor(// ..
public accountHttp: AccountHttp,
private accountService: AccountService,
public transactionHttp: TransactionHttp,
private translateService: TranslateService) {
// Visual logic
// ...
// We receive the 2FC Account
this.account = this.accountService.getAccount();
// Fetch all unconfirmed transactions for 2FC Account
this.accountPulling = accountHttp.unconfirmedTransactions(this.account.address)
// We transform the result from an Transaction[] to Transaction to apply the logic individually
.flatMap(_ => _)
// Remove from the result all the transactions that are not of type Multisig
.filter(transaction => transaction.type == TransactionTypes.MULTISIG)
// Trasnform the MultisigTransaction into a ModelView class for visual reasons
.map(multisigTransaction => new MultisigTransactionPlusView(<MultisigTransaction>multisigTransaction, false, false))
// We compact all the results into an array to print all of them at the same time
.toArray();
// Resolve the Observable in fetchTransactions and print the result
this.fetchTransactions();
// Receive the Multisig Account that we are cosignatory
let multisig = accountService.getMultisig();
// Start listen via WebSocket the multisig transactions to print it
new UnconfirmedTransactionListener().given(multisig)
.delay(1000)
.subscribe(_ => {
this.fetchTransactions();
});
// Listen when a signed transaction is included in a block to remove it from the pending to sign list
new ConfirmedTransactionListener().given(multisig)
.subscribe(transaction => {
if (transaction.type == TransactionTypes.MULTISIG) {
this.unconfirmedTransactions = this.unconfirmedTransactions
.filter(x => {
const innerData = x.transaction.hashData.data;
const confirmedTransactionInnerData = (<MultisigTransactionInfo>(<MultisigTransaction>transaction).getTransactionInfo()).innerHash.data;
return innerData != confirmedTransactionInnerData;
})
}
})
}
fetchTransactions(refresher?: any) {
this.unconfirmedTransactions = [];
this.accountPulling.subscribe(
value => {
// List all unconfirmedTransactions
this.unconfirmedTransactions = value;
// Visual logic
},
error => {
// Error logic
}
);
}
}
Здесь присутствуют следующие компоненты NEM Library:
- ConfirmedTransactionListener проверка транзакции на включение в блок и подтверждение в сети
- UnconfirmedTransactionListener поиск новых "ожидающих" транзакций
Проверка основной информации, Hash как и в NanoWallet, и подпись.
private signTransaction(unconfirmedTransaction: MultisigTransactionPlusView) {
// We create as MultisigSignedTransaction that contains
// TimeWindow: The interval of time that the transaction can be included in a block
// The address of who started the transaction
// The hash to identify the Multisig transaction
const multisigSignedTransaction = MultisigSignatureTransaction.create(
TimeWindow.createWithDeadline(),
unconfirmedTransaction.transaction.otherTransaction.signer.address,
unconfirmedTransaction.transaction.hashData
);
// Visual logic
unconfirmedTransaction.signing = true;
// The 2FC account signs the multisigSignedTransaction (notice that we do not expose the private key)
const signedTransaction = this.account.signTransaction(multisigSignedTransaction);
// We send the transaction into the network already signed by the 2FC Account
this.transactionHttp.announceTransaction(signedTransaction).subscribe(x => {
// Visual logic
unconfirmedTransaction.signing = false;
unconfirmedTransaction.signed = true;
}, err => {
// Error logic
}
);
}
Несколько строчек кода позволяют подписать транзакцию и включить в блок.
- Account отвечает за подпись транзакции, не открывая приватный ключ
- MultisigSignatureTransaction нужен для подписи Multisig Transaction
- TransactionHttp анонсирует транзакцию сети NEM
NEM Authenticator 100% безопасен?
Нет, мы лишь увеличили уровень безопасности в блокчейне NEM. Если 2 устройсва будут украдены одновременно, то вы потеряете свои средства.
NEM Authenticator уже есть в основной сеть?
NEM Authenticator находится в бета тестировании, но скоро будет релиз.
Код
NEM Authenticator - это приложение с открытым исходным кодом и MIT License.
https://github.com/aleixmorgadas/NEM-Authenticator
Источник: How NEM Authenticator is made