當前位置:
首頁 > 最新 > 開發區塊鏈數字貨幣交易系統要點解析

開發區塊鏈數字貨幣交易系統要點解析

區塊鏈是什麼可以用在什麼地方我前文中已經講了,那麼系統開發的一些文章我在前面也講了一些今天我接著講,最初接觸區塊鏈的小夥伴感覺非常茫然無從下手,區塊鏈開發技術需要的是一整套只會開發一個和全套是不一樣的,就算是國內能夠做主鏈的公司也只有幾家大部分只會做側鏈,主鏈和側鏈需要的是不一樣的,還要會弄錢包.區塊鏈瀏覽器.交易平台系統.場內場外.上幣落地app.項目白皮書.對接主流交易所.跨境支付.貨幣發行系統.主鏈開發.基金會發起,最重要的是牌照沒有牌照就算你會做全套,拿不到牌照也是違法的,就想現在的支付牌照一樣上億元,區塊鏈牌照雖然沒有那麼鬼但是也已經停止辦理,現在市場價是十多萬以上,而且還是熟人交易,不認識不管多少別人也不會轉給你,日本和美國的牌照需要等上好幾年辦下來也需要上千萬,不是錢的問題沒有經驗和關係你也不好辦,我們目前能夠做這一整套技術大家可以諮詢我

那麼區塊鏈發展到現在已經到區塊鏈3.0了 區塊鏈3.0可以用在很多行業,無論你擅長什麼編程語言,都能夠參考這種設計去實現一款區塊鏈產品。當然,具體到產品,架構設計有很多種,不同的人、不同的產品,架構設計也不盡相同,我們這裡僅僅提供一種參考,讓讀者能夠直觀的感受區塊鏈的技術實現,並順便梳理與之相關的知識體系,我先說一下結構分為三個層次,協議層、擴展層和應用層。其中,協議層又可以分為存儲層和網路層,它們相互獨立但又不可分割。如圖:

區塊鏈技術的鼻祖,(協議層)就是用C++語言開發的,客戶端錢包用的Qt,第三方錢包有Python語言開發的,所以首先需要這些語言,如果是Python語言愛好者建議研究研究(Ethereum)的Python實現,Ethereum給出了Go、Java、Python等多語言的實現。其中以python為基礎的實現主要包括三個部分:Pyethapp是客戶端部分;pyethereum是核心庫,實現了區塊鏈、以太坊模擬機和挖礦等功能;pydevp2p是點對點網路庫,實現了節點發現、合約代碼傳輸、加密簽名等功能,這三者組合在一起就是完整的區塊鏈實現,後面兩個核心庫共同組成了協議層。另外,go-ethereum是go語言的完整實現;Ethereum(J) 是純Java實現,它作為可以嵌入任何Java/Scala項目的庫提供。客戶端方面,還有Rust、Ruby、Java等語言的實現,其他編程語言這裡就不再一一列舉,但是協議層所使用的技術並沒有太大的變化。其中,網路編程是重點和難點,多數沒有現成的框架可用,都是使用編程語言自身提供的庫來設計開發,所以比較底層,非常考驗開發者的編碼功底。

知識圖譜:循著上面的分析,我們已經可以了解區塊鏈是什麼,並知道怎麼實現了,順便梳理一下其中的編程技術知識,自然也就清晰多了。

下面再講一下如何實現錢包,接著上文講大家自行查看以前的文章:我們已經有了token,如何讓用戶更容易的管理自己的token並進行交易呢?我們需要支持什麼樣的核心功能?創建一個新錢包. 查看錢包的餘額 .在錢包之間進行交易. 在Bitcoin中你可以通過錢包管理自己的coin,在Ethereum中你也可以用錢包管理自己的各類token。

如何創建錢包錢包的基礎是什麼?公鑰和私鑰。因此我們需要首先創建用戶的這兩把鑰匙。首先是私鑰,並且要保存在本地:node/wallet/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 keysif (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();};

上述代碼首先基於公鑰定位到了記錄,然後進行了求和。

如何進行交易

如何能夠屏蔽底層的發起者和接收者等複雜概念來簡單的使用呢?而且我們的底層支持的是把發起者包括的所有token都給予接收者。如果發起者有50個token,但是指向轉移10個呢?這時候需要我們把剩餘的40個token還給發起者。具體場景如下圖所示:

這個過程甚至能夠更加負責,例如:用戶C開始只有0個token之後的三個交易讓C分別獲得了10、20、30個tokenC想要給D轉發55個token

這個場景如上圖所示,我們要如何做呢?具體來說我們需要把這三次交易的總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 } } throwError("not enough coins to send transaction");};

如代碼所示,我們還記錄了額外多出來的數量,我們之後會把它還給C。

因為我們有了需要使用的未花費的交易,於是我們能夠創建發起者的數據了。

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

然後我們可以把對應的token分別給予D和C,也就是一個是我們的接受者,一個是還給發起者。當然,如果token恰好不多不少,我們就不需要歸還了。

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

我們現在可以構建交易並且簽名了。

const tx:Transaction=newTransaction(); 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; });

如何使用錢包

我們現在構建使用錢包的一個外部介面。

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分給三個不同的人。

但是現在你只能通過自己挖礦來添加新的區塊,我們要如何才能更方便的使用呢?這是下一節的內容。

如何找他人幫忙

如果每次添加交易都需要用戶自己挖礦,那麼效率會極為低下。我們如何才能利用他人來幫忙呢?這需要我們把未確認的交易提交到這個網路中,並且期待有人能夠幫助我們把這次交易寫入區塊鏈中。

因此節點直接除了同步區塊的信息之外還需要交流未確認的交易信息。

如何保存未確認的交易

我們需要構建一個新的結構「交易池」來保存未確認的交易(Bitcoin中稱之為mempool)。 我們可以通過數據來實現:

let transactionPool:Transaction[] = [];

如何使用這個新的提交交易的功能呢?我們可以在創建一個對外的介面POST /sendTransaction。這個方法會在我們本地的節點的交易池中添加我們的新的交易,這也會成為我們默認的提交交易的方法。

app.post("/sendTransaction", (req, res) => { ... })

這時候我們就不再需要挖礦,而只是把交易記錄下來。

const sendTransaction = (address:string, amount:number):Transaction=> { const tx:Transaction=createTransaction(address, amount, getPrivateFromWallet(), getUnspentTxOuts(), getTransactionPool()); addToTransactionPool(tx, getUnspentTxOuts()); return tx;};

如何通知他人交易信息

當我們添加一個未確認的交易後,我們需要把這個交易告訴整個網路,並且期待有人會把這個交易放入區塊鏈中。我們要如何廣播呢?

當一個節點接收到一個新的未確認的交易時,他會廣播自己的交易池給所有的節點

當一個節點第一次連接到另一個節點時,他會請求這個節點的交易池

因此我們需要構建兩個新的消息:QUERY_TRANSACTION_POOL和RESPONSE_TRANSACTION_POOL。它們一個負責查詢,一個負責回復,具體的代碼如下。

enumMessageType { 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(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 poolbroadCastTransactionPool(); } catch (e) { //unconfirmed transaction not valid (we probably already have it in our pool) } });

由於時間有限這篇文章我們把先區塊鏈技術基礎架構和如何創建錢包描述了一下,需要再次強調的是這僅僅是一種實現方式,絕非所有的區塊鏈產品都是如此,我們也期待更多創新出現,也相信一定會出現。文章編程實現部分羅列了幾種編程語言與其實現的典型產品,因為協議層技術較為底層,並沒有太多現成的框架需要介紹或討論,同時,具體的技術細節,也絕非幾行字能夠羅列清楚,我們目前能夠做區塊鏈主鏈開發 搭建貨幣電子錢包.區塊鏈瀏覽器.交易平台系統.數字貨幣交易所.場內場外.上幣落地app.項目白皮書.對接主流交易所.跨境支付.貨幣發行系統.主鏈開發.基金會發起.海內外貨幣牌照等一整套技術解決方案,具體的大家可以仔細諮詢我,我為大家一一解答。

開發區塊鏈數字貨幣交易系統需要什麼方法怎麼開發區塊鏈數字貨幣交易所需要什麼代碼和技術談談區塊鏈交易所搭建所需要的代碼和方法從官方企業白皮書看區塊鏈搭建主鏈到工業應用區塊鏈搭建開發與特點在工業方面的使用


喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 彭利 的精彩文章:

談談區塊鏈交易所搭建所需要的代碼和方法
開發區塊鏈數字貨幣交易系統需要什麼方法

TAG:彭利 |