Глава IV бумажник

обзор

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

Наша конечная цель состоит в том, чтобы позволить пользователям легко:

  • Создать новый кошелек
  • Просмотр Кошелек
  • Сделки между кошельками

После вступления в силу этих пользователей не нужно знать детали входов и outpus, описанные в предыдущем разделе этих операций, мы сможем управлять сделкой. Как и в сети Bitcoin, вам просто необходимо ввести соответствующий адрес Bitcoin Bitcoin будет в состоянии проникнуть в кого-то другого, в то время как вам нужно только опубликовать свой адрес из, другие будут в состоянии дать вам немного денег.

Смотрите этот раздел полный код здесь

Сформировать бумажник

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

const privateKeyLocation = 'node/wallet/private_key';

const generatePrivatekey = (): string => {
    const keyPair = EC.genKeyPair();
    const privateKey = keyPair.getPrivate();
    return privateKey.toString(16);
};

const initWallet = () => {
    //let's not override existing private keys
    if (existsSync(privateKeyLocation)) {
        return;
    }
    const newPrivateKey = generatePrivatekey();

    writeFileSync(privateKeyLocation, newPrivateKey);
    console.log('new wallet with private key created');
};

Как сказал ранее, наш открытый ключ (кошелек адрес) выводится с помощью секретного ключа.

const getPublicFromWallet = (): string => {
    const privateKey = getPrivateFromWallet();
    const key = EC.keyFromPrivate(privateKey, 'hex');
    return key.getPublic().encode('hex');
};

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

Кошельке

Заявление на рассмотрении упомянутого в предыдущем разделе: у вас есть в валюте шифрования цепи блока, на самом деле, относится к «не-потребительским сделкам результатов», адрес получателя является серией выходов их открытый ключ.

Это означает, что мы хотим, чтобы увидеть, если кошелек баланс, то все становится очень просто: нужно просто все адреса под «непотребительских операции вывода» рекордное количество денег вместе будет закончена.

const getBalance = (address: string, unspentTxOuts: UnspentTxOut[]): number => {
    return _(unspentTxOuts)
        .filter((uTxO: UnspentTxOut) => uTxO.address === address)
        .map((uTxO: UnspentTxOut) => uTxO.amount)
        .sum();
};

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

Сформировать сделки

Для того, чтобы зашифровать денежную сделку, вы не должны беспокоиться о торговле на входах и выходах этих мелочей. Однако, когда учетная запись пользователя А имеет 50 монет, если он даст пользователю B посылает 10 монет, торгуя назад то, что случилось потом?

В этом случае система 10 будет отправлена ​​на открытые ключи кредитов адрес B, в то время как остальные 40 будут возвращены пользователем A. кредитов Другими словами, 50 монет источники потребления должны быть завершены, он должен быть разделен, когда источник назначается выдает валютные операции. После того, как транзакция должна быть источником 50 монет производства в исключив слова «не потребительские сделки выходов», два выхода, чтобы добавить вновь образовавшееса. То есть «не потребительские сделки выдает» на денежные агрегаты не изменится, а некоторые валюты торгуются, адрес принадлежат разным пользователям этого.

На приведенном ниже рисунке показана вышеупомянутой транзакции:

Давайте посмотрим на более сложный момент сцены:

  • Пользователи начинают иметь большинство C 0 монет
  • После того, как три торговые Пусть C получили 10, 20, монета
  • C D хотят направить 55 монет.

В этом случае все три выхода пользователя C ( «не-потребительские операции выходы» в адресе для этих выходов C открытый ключ) в настоящее время лоббируется потратить 55 монет на D, остальные пять монет Он будет возвращен на C.

Так как будет выше описание с логикой кода, чтобы выразить это? Во-первых, мы создадим соответствующие входы для сделки. Как создать? Мы будем пересекать въездной адрес открытого ключа отправителя «сделка выводит не потребление,» до тех пор, пока не найдешь достаточное количество монет можно лоббируются (сложить количество монет выдает больше или равно целевое количество монет) выходов.

const findTxOutsForAmount = (amount: number, myUnspentTxOuts: UnspentTxOut[]) => {
    let currentAmount = 0;
    const includedUnspentTxOuts = [];
    for (const myUnspentTxOut of myUnspentTxOuts) {
        includedUnspentTxOuts.push(myUnspentTxOut);
        currentAmount = currentAmount + myUnspentTxOut.amount;
        if (currentAmount >= amount) {
            const leftOverAmount = currentAmount - amount;
            return {includedUnspentTxOuts, leftOverAmount}
        }
    }
    throw Error('not enough coins to send transaction');
};

Как показано в коде, мы находим в дополнение к тем сделкам выходов соответствуют условиям отсутствия потребления, но и записывать сделку по остальной части необходимого количества монет leftOverAmount обратно отправителю.

После нахождения этих непотребительских сделок выхода, мы можем думать, что текущая транзакция создать соответствующие входы:

const toUnsignedTxIn = (unspentTxOut: UnspentTxOut) => {
    const txIn: TxIn = new TxIn();
    txIn.txOutId = unspentTxOut.txOutId;
    txIn.txOutIndex = unspentTxOut.txOutIndex;
    return txIn;
};
const {includedUnspentTxOuts, leftOverAmount} = findTxOutsForAmount(amount, myUnspentTxouts);
const unsignedTxIns: TxIn[] = includedUnspentTxOuts.map(toUnsignedTxIn);

Подход очень прост, в основном, каждый вход в точке txOutId соответствующий не-потребительские операции вывода найденных предметы выше.

Вслед за необходимостью создания примера двух выходов: выход к получателю, а другой выход отправитель самостоятельно, так как оставшееся количество монет, необходимых, чтобы вернуться. Конечно, общее количество монет, если входы указывающими точно равна сумме сделки, что leftOverAmount 0, нам нужно только создать выход посыла целевой пользователя достаточно.

const createTxOuts = (receiverAddress:string, myAddress:string, amount, leftOverAmount: number) => {
    const txOut1: TxOut = new TxOut(receiverAddress, amount);
    if (leftOverAmount === 0) {
        return [txOut1]
    } else {
        const leftOverTx = new TxOut(myAddress, leftOverAmount);
        return [txOut1, leftOverTx];
    }
};

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

const tx: Transaction = new Transaction();
    tx.txIns = unsignedTxIns;
    tx.txOuts = createTxOuts(receiverAddress, myAddress, amount, leftOverAmount);
    tx.id = getTransactionId(tx);

    tx.txIns = tx.txIns.map((txIn: TxIn, index: number) => {
        txIn.signature = signTxIn(tx, index, privateKey, unspentTxOuts);
        return txIn;
    });

Использование бумажника

Мы обеспечим «/» mineTransaction этот API, чтобы позволить пользователям легко использовать функцию бумажника:

app.post('/mineTransaction', (req, res) => {
        const address = req.body.address;
        const amount = req.body.amount;
        const resp = generatenextBlockWithTransaction(address, amount);
        res.send(resp);
    });

Как показано в коде, пользователю нужно только указать адрес количество сделок и получатель может быть достигнуто с помощью этой транзакции API. Апи после первого звонка проводить добычу, чтобы получить сумму 50 исходной валюты сделки, а затем завершить сделку в соответствии с указанным адресом получателя и количества транзакций, эти операции в конечном итоге будут записаны на новое увеличение в блоке, при обновлении нашего «сделка не выводит потребление.»

Тестирование Опыт

  • начало

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

npm run node1
npm run node 2

В то же время, при запуске второго узла, добавив параметры Peer, так что второй узел и узел 1 автоматически установить соединение P2P.

"scripts": {
    "prestart": "npm run compile",
    "node1": "HTTP_PORT=3001 P2P_PORT=6001 WALLET=1 npm start ",
    "node2": "HTTP_PORT=3002 P2P_PORT=6002 WALLET=2 PEER=ws://localhost:6001 npm start ",
    "start": "node src/main.js",
    "compile": "tsc"
  },

Наконец, поддерживая вновь добавленные параметры КОШЕЛЕК, мы автоматически инициировать кошелек для каждого узла, мы будем гораздо легче наблюдать за поведением бумажника и сделок.

  • Просмотр дополнительных интерфейсов «untraded выходов потребителей.»

Потому что «потребительские untraded выходы» Этот список очень важно, когда мы проводим основную сделку. Таким образом, необходимо обеспечить дополнительный интерфейс для просмотра изменений данных внутри. Вы можете отправить запрос на GET способом « HTTP: // локальный: 3001 / unspentTransactionOutputs » интерфейс для получения списка.

Обратите внимание, что если вы играли два узла, а затем использовать порт 3001 и 3002 возможны. Список распространяется в виде списка, и наш блок цепи, это целая сеть синхронизированы.

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

резюме

Мы только что реализовали незашифрованную функцию бумажника для простых операций. Хотя торговые алгоритмы (mineTransaction связаны с логикой интерфейса) могут иметь только максимум два выхода приемника (один приемник, один их собственный), но наш нижняя цепь блока интерфейс может поддерживать любое количество выходов. Например, вы можете создать входы в 50 монетах, выходы 5, 15 и 30 валюта, но вы должны вручную заполнить данные и вызов / mineRawBlock этого интерфейса для достижения.

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

Смотрите этот раздел полный код здесь

Глава V

Эта статья Fenduo Всемирным советом Чжухай записи, Печатается с разрешения, как точки, как это, пожалуйста, комментарии Tucao, например, проект по Github дать звездам, будет очень цениться.

рекомендация

отblog.csdn.net/zhubaitian/article/details/93346504
рекомендация