区块链交流吧 关注:2,729贴子:22,068

回复:开发数字货币交易所的方法

只看楼主收藏回复



IP属地:北京72楼2018-04-14 15:01
回复
    这个过程甚至能够更加负责,例如:用户C开始只有0个token 之后的三个交易让C分别获得了10、20、30个token C想要给D转发55个token


    IP属地:北京73楼2018-04-14 15:01
    回复


      IP属地:北京74楼2018-04-14 15:02
      回复
        这个场景如上图所示,我们要如何做呢?具体来说我们需要把这三次交易的总token拆成两份,其中的55个给D,另外的5个还给C。
        如何实现这个代码呢?我们首先在C所有未花费的交易中不断的累积token,直到总和达到或者超过目标值。
        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');};
        如代码所示,我们还记录了额外多出来的数量,我们之后会把它还给C。


        IP属地:北京75楼2018-04-14 15:02
        回复
          因为我们有了需要使用的未花费的交易,于是我们能够创建发起者的数据了。
          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);
          然后我们可以把对应的token分别给予D和C,也就是一个是我们的接受者,一个是还给发起者。当然,如果token恰好不多不少,我们就不需要归还了。


          IP属地:北京76楼2018-04-14 15:03
          回复
            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]; }};
            我们现在可以构建交易并且签名了。


            IP属地:北京77楼2018-04-14 15:04
            回复
              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; });


              IP属地:北京78楼2018-04-14 15:04
              回复
                如何使用钱包
                我们现在构建使用钱包的一个外部接口。
                app.post('/mineTransaction', (req, res) => { const address = req.body.address; const amount = req.body.amount; const resp = generatenextBlockWithTransaction(address, amount); res.send(resp); });
                用户只需要提供接收者地址和交易数量就可以使用钱包了。
                小结:如何实现钱包
                我们实现了支持交易的钱包。虽然在使用中最多包括两个接收者,但实际上我们底层的接口支持更多复杂的场景。例如,把50个token分给三个不同的人。
                但是现在你只能通过自己挖矿来添加新的区块,我们要如何才能更方便的使用呢?这是下一节的内容。


                IP属地:北京79楼2018-04-14 15:04
                回复
                  如何找他人帮忙
                  如果每次添加交易都需要用户自己挖矿,那么效率会极为低下。我们如何才能利用他人来帮忙呢?这需要我们把未确认的交易提交到这个网络中,并且期待有人能够帮助我们把这次交易写入区块链中。
                  因此节点直接除了同步区块的信息之外还需要交流未确认的交易信息。
                  如何保存未确认的交易
                  我们需要构建一个新的结构“交易池”来保存未确认的交易(Bitcoin中称之为mempool)。 我们可以通过数据来实现:
                  let transactionPool: Transaction[] = [];
                  如何使用这个新的提交交易的功能呢?我们可以在创建一个对外的接口POST /sendTransaction。这个方法会在我们本地的节点的交易池中添加我们的新的交易,这也会成为我们默认的提交交易的方法。
                  app.post('/sendTransaction', (req, res) => { ... })


                  IP属地:北京80楼2018-04-14 15:05
                  回复
                    如何找他人帮忙
                    如果每次添加交易都需要用户自己挖矿,那么效率会极为低下。我们如何才能利用他人来帮忙呢?这需要我们把未确认的交易提交到这个网络中,并且期待有人能够帮助我们把这次交易写入区块链中。
                    因此节点直接除了同步区块的信息之外还需要交流未确认的交易信息。
                    如何保存未确认的交易
                    我们需要构建一个新的结构“交易池”来保存未确认的交易(Bitcoin中称之为mempool)。 我们可以通过数据来实现:
                    let transactionPool: Transaction[] = [];
                    如何使用这个新的提交交易的功能呢?我们可以在创建一个对外的接口POST /sendTransaction。这个方法会在我们本地的节点的交易池中添加我们的新的交易,这也会成为我们默认的提交交易的方法。
                    app.post('/sendTransaction', (req, res) => { ... })


                    IP属地:北京81楼2018-04-14 15:06
                    回复
                      这时候我们就不再需要挖矿,而只是把交易记录下来。
                      const sendTransaction = (address: string, amount: number): Transaction => { const tx: Transaction = createTransaction(address, amount, getPrivateFromWallet(), getUnspentTxOuts(), getTransactionPool()); addToTransactionPool(tx, getUnspentTxOuts()); return tx;};
                      如何通知他人交易信息
                      当我们添加一个未确认的交易后,我们需要把这个交易告诉整个网络,并且期待有人会把这个交易放入区块链中。我们要如何广播呢?
                      ·
                      当一个节点接收到一个新的未确认的交易时,他会广播自己的交易池给所有的节点


                      IP属地:北京82楼2018-04-14 15:06
                      回复
                        当一个节点第一次连接到另一个节点时,他会请求这个节点的交易池
                        ·
                        因此我们需要构建两个新的消息:QUERY_TRANSACTION_POOL和 RESPONSE_TRANSACTION_POOL。它们一个负责查询,一个负责回复,具体的代码如下。
                        enum MessageType { QUERY_LATEST = 0, QUERY_ALL = 1, RESPONSE_BLOCKCHAIN = 2, QUERY_TRANSACTION_POOL = 3, RESPONSE_TRANSACTION_POOL = 4}
                        交易池信息的消息构建如下:
                        const responseTransactionPoolMsg = (): Message => ({ 'type': MessageType.RESPONSE_TRANSACTION_POOL, 'data': JSON.stringify(getTransactionPool())});const queryTransactionPoolMsg = (): Message => ({ 'type': MessageType.QUERY_TRANSACTION_POOL, 'data': null});
                        为了实现整个广播的逻辑,我们需要添加处理MessageType.RESPONSE_TRANSACTION_POOL消息的业务逻辑。每当我们收到了未确认的交易,我们首先把它加入到自己的消息池中。然后我们会把我们的整个交易池广播给所有我身边的节点。
                        case MessageType.RESPONSE_TRANSACTION_POOL: const receivedTransactions: Transaction[] = JSONToObject<Transaction[]>(message.data); receivedTransactions.forEach((transaction: Transaction) => { try { handleReceivedTransaction(transaction); //if no error is thrown, transaction was indeed added to the pool //let's broadcast transaction pool broadCastTransactionPool(); } catch (e) { //unconfirmed transaction not valid (we probably already have it in our pool) } });


                        IP属地:北京83楼2018-04-14 15:06
                        回复
                          我的联系方式 http://wpa.qq.com/msgrd?v=3&uin=2398788267


                          IP属地:北京85楼2018-04-14 15:08
                          回复
                            留个方式吧主


                            IP属地:辽宁来自iPhone客户端87楼2018-04-16 14:34
                            回复
                              留个方式,合作


                              IP属地:辽宁来自iPhone客户端88楼2018-04-16 14:34
                              回复