本篇是關(guān)于“如何使用OmniCore在服務(wù)端構(gòu)建USDT錢包”系列的下篇咏删,主要是對(duì)上一篇《使用OmniCore構(gòu)建USDT錢包(一)》的補(bǔ)充和總結(jié)厦滤。上一篇主要對(duì)安裝片任、配置和基本json-api使用逗概,以及交易所錢包模型做了簡(jiǎn)略的說(shuō)明,這一篇將對(duì)常見(jiàn)錯(cuò)誤箕宙、安全機(jī)制以及其他擴(kuò)展做一些技術(shù)分享嚎朽。
1.omni_funded_send -212錯(cuò)誤
從v0.3.1開始o(jì)mnicore提供了新的轉(zhuǎn)賬api omni_funded_send 來(lái)支持USDT的轉(zhuǎn)賬操作。與之前的方式不同在于扒吁,omni_funded_send支持從第三方支付手續(xù)費(fèi)火鼻。但在實(shí)際操作,明明擁有充足的btc用于支付手續(xù)費(fèi)雕崩,也有充分的usdt用于轉(zhuǎn)賬魁索,還是會(huì)頻繁出現(xiàn)編號(hào)-212錯(cuò)誤:
$ ./omnicore-cli omni_funded_send "mrAVAPxdQEZxFkunh56skB6sgJa6vrfrpo" "msJ2h47ZrxFJjksVvPy8ik4h2HFfa9W1zV" 31 "100.01" "mpaumxor659PhoJhXp1VCVHVwbFCZSRmuf"
error code: -212
error message:
Error choosing inputs for the send transaction
issues/760#詳細(xì)討論了這個(gè)問(wèn)題。
USDT的轉(zhuǎn)賬本質(zhì)上屬于比特幣的一種特殊交易(OP_RETUTRN)盼铁,需要一部分BTC來(lái)支付礦工費(fèi)用粗蔚。同時(shí),根據(jù)omnilayer協(xié)議饶火,還需要微量的比特幣用于標(biāo)記omni事務(wù)的接受者鹏控,這部分btc無(wú)法從手續(xù)費(fèi)地址扣除,只能從發(fā)送地址扣除肤寝。因此当辐,當(dāng)發(fā)送地址缺乏btc(也就是UTXO)時(shí),會(huì)出現(xiàn) “Error choosing inputs for the send transaction”的錯(cuò)誤鲤看。經(jīng)過(guò)測(cè)試缘揪,默認(rèn)情況下用于標(biāo)記omni事務(wù)的BTC為0.0000546。因此解決這個(gè)問(wèn)題的唯一方法是向發(fā)送地址中轉(zhuǎn)入>0.000055的BTC。
但需要注意的是找筝,發(fā)送地址上的某個(gè)UTXO將全部消耗掉蹈垢,不會(huì)有找零。例如A地址向B地址轉(zhuǎn)移USDT袖裕,A地址中擁有兩個(gè)UTXO曹抬,分別為0.0001和0.0002,那么轉(zhuǎn)賬成功后急鳄,0.0001的UTXO將會(huì)被消耗掉谤民,只剩下額度為0.0002的UTXO。
但在交易所模式下攒岛,這種錯(cuò)誤幾乎不會(huì)發(fā)生赖临。因?yàn)樵谥行幕X包的模式下,充值的過(guò)程會(huì)自動(dòng)攜帶了微量的btc灾锯,這一部分比特幣足夠用于標(biāo)記omni事務(wù),用于下一次轉(zhuǎn)賬嗅榕,但也僅限一次顺饮。因此,只要不使用同一個(gè)地址發(fā)送兩次USDT凌那,這種錯(cuò)誤幾乎不會(huì)出現(xiàn)兼雄。
值得注意的是,轉(zhuǎn)賬錯(cuò)誤也可能會(huì)消耗掉發(fā)送地址下的微量utxo帽蝶,所以赦肋,當(dāng)發(fā)生這種錯(cuò)誤時(shí),需要查詢出缺少微量utxo的地址并進(jìn)行btc的轉(zhuǎn)賬励稳。但這里會(huì)引發(fā)另外一個(gè)問(wèn)題佃乘,就是批量轉(zhuǎn)移微量btc時(shí),會(huì)發(fā)生code:-26 message: dust
的錯(cuò)誤驹尼。
2.dust錯(cuò)誤
拒絕粉塵攻擊其實(shí)是比特幣錢包的一個(gè)安全機(jī)制趣避,當(dāng)錢包或節(jié)點(diǎn)檢測(cè)到非常微小的比特幣交易時(shí),會(huì)自動(dòng)把這筆交易從緩沖區(qū)里面清除出去新翎,甚至都不讓進(jìn)入緩沖區(qū)就直接拒絕掉了程帕。這是一種維護(hù)比特區(qū)塊安全通暢的一種手法。當(dāng)為了usdt轉(zhuǎn)賬的成功地啰,像發(fā)送地址轉(zhuǎn)賬微量btc時(shí)愁拭,會(huì)觸發(fā)這種機(jī)制。解決方法是修改配置文件中的minrealytxfee參數(shù)亏吝,令minrealytxfee=0.000000055岭埠,可以讓錢包允許這筆比特幣交易。但這么做???可能會(huì)引發(fā)另外一個(gè)問(wèn)題,修改這個(gè)參數(shù)后枫攀,可能造成usdt的轉(zhuǎn)賬被堵死在自己錢包的緩沖區(qū)里面括饶,無(wú)法將交易廣播出去。一個(gè)明顯的特征是来涨,你可以在構(gòu)建usdt交易并且好像發(fā)送成功图焰,并在緩沖區(qū)看到了這筆交易,但在任何比特幣區(qū)塊瀏覽器上都無(wú)法找到這筆交易蹦掐。解決這個(gè)問(wèn)題的方式需要將minrealytxfee從配置中刪除或恢復(fù)默認(rèn)值技羔。
3.usdt的交易可以取消嗎?卧抗?
這種問(wèn)題需要分情況分析藤滥,如果交易已經(jīng)廣播出去了(哪怕手續(xù)費(fèi)是0都可廣播出去),也就是區(qū)塊鏈瀏覽器上可以查詢到了(注意這里指的是比特幣的區(qū)塊瀏覽器)社裆,那么這筆交易是無(wú)法被取消的拙绊。面對(duì)遲遲不能確認(rèn)的交易,唯一能做的就是額外給礦工一筆錢泳秀,讓他優(yōu)先把你的交易打包進(jìn)區(qū)塊,如果你不愿意與礦工發(fā)生這種PY交易标沪,那么只能繼續(xù)等待。目前大部分礦池都支持這種服務(wù)嗜傅,俗稱交(hui)易(luo)加(kuang)速(gong)金句。
還一種情況是,雖然交易是構(gòu)建成功了吕嘀,產(chǎn)生了交易id违寞,但始終沒(méi)有廣播出去。交易一直在你的錢包里面躺著偶房,區(qū)塊瀏覽器上一直查不到趁曼。那么這種情況是可以撤銷的,解決的方案是在配置文件中設(shè)置zapwallettxes=1,然后重啟啟動(dòng)蝴悉。重啟后緩沖區(qū)中的交易會(huì)被清空掉彰阴,并重新開始掃描,接收自己或其他節(jié)點(diǎn)的交易信息拍冠。如果你還配置了minrealytxfee尿这,那么記得在重啟前把這個(gè)參數(shù)恢復(fù)默認(rèn)值或干脆刪除掉。這里需要解釋的是庆杜,為什么區(qū)塊瀏覽器查不到的交易可以確認(rèn)沒(méi)有被廣播出去射众?原因是區(qū)塊瀏覽器其實(shí)也是一個(gè)節(jié)點(diǎn),而且屬于那種不挑食的節(jié)點(diǎn)晃财,無(wú)論你是沒(méi)有支付手續(xù)費(fèi)的交易叨橱,還是粉塵交易典蜕,只有驗(yàn)證通過(guò)他都會(huì)接收。如果區(qū)塊瀏覽器的節(jié)點(diǎn)都收不到的交易罗洗,那么其他節(jié)點(diǎn)更不會(huì)接收愉舔。
當(dāng)然,如果你的目的并非撤銷這一筆未廣播的交易伙菜,而是重新發(fā)送他轩缤,那么只需要獲取這筆交易的交易id,然后使用getrawtransaction 獲取raw數(shù)據(jù)贩绕,再通過(guò)sendrawtransaction進(jìn)行重新廣播即可火的。只要拿到raw數(shù)據(jù),通過(guò)任何聯(lián)網(wǎng)的方式都可以發(fā)送到其他節(jié)點(diǎn)上去淑倾。
4. 錢包安全
數(shù)字資產(chǎn)不同于一般性的資產(chǎn)馏鹤,一旦被盜或丟失,幾乎無(wú)法找回娇哆,也無(wú)法進(jìn)行數(shù)據(jù)回滾湃累。對(duì)于中心化的錢包而言,用戶本身對(duì)資產(chǎn)沒(méi)有直接控制權(quán)碍讨,所有的資產(chǎn)安全性全部取決于中心化錢包的安全策略脱茉,因此非常有必要對(duì)安全性進(jìn)行設(shè)計(jì)。以下方式僅供參考垄开。
4.1 限制訪問(wèn)權(quán)限
omnicore基于bitcore,自帶有加密訪問(wèn)權(quán)限設(shè)置,可以通過(guò)bitcoin.conf文件可以進(jìn)行配置税肪。
rpcuser=你的rpc用戶名
rpcpassword=你的rpc密碼
rpcallowip=127.0.0.1
rpcport=8332
其中rpcuser
和rpcpassword
分別配置訪問(wèn)用戶和訪問(wèn)密碼溉躲,rpcallowip
和rpcport
分別配置可訪問(wèn)的網(wǎng)絡(luò)地址。測(cè)試環(huán)境下益兄,該地址可以為0.0.0.0/0 為全地址訪問(wèn)锻梳。正式環(huán)境下,需要配置為制定的訪問(wèn)服務(wù)器地址或者本地地址净捅。值得注意的是疑枯,這里的安全原理是限定錢包訪問(wèn)對(duì)象,一旦密碼泄漏或服務(wù)器被黑蛔六,那么整個(gè)錢包相當(dāng)于裸奔荆永。
4.2 離線生成地址
資產(chǎn)的唯一憑證是私鑰,因此私鑰的保存非常重要国章。一般情況下具钥,根據(jù)業(yè)務(wù)需求,服務(wù)端需要給每個(gè)用戶分配一個(gè)地址液兽。這里的建議是不應(yīng)該分配地址的時(shí)候“即使”的去調(diào)用getnewaddresss
骂删,而是通過(guò)離線的方式批量生產(chǎn)大量地址,然后連同地址、私鑰保存到數(shù)據(jù)庫(kù)宁玫,同時(shí)導(dǎo)出地址列表給服務(wù)端進(jìn)行使用粗恢。這樣服務(wù)端需要分配地址時(shí),只需要從數(shù)據(jù)庫(kù)讀取即可欧瘪,而不需要與錢包進(jìn)行交互眷射。
為了私鑰的安全性,保存到數(shù)據(jù)庫(kù)時(shí)可以進(jìn)行二次加密恋追。
4.3 錢包文件備份
錢包文件的備份可以直接使用bitcore的導(dǎo)出數(shù)據(jù)方式dumpwallet
,每天定期保存到文件,例如:
/***
* 導(dǎo)出錢包數(shù)據(jù)以人類可讀的方式
* @param: []
* @return: java.lang.String
**/
public String dumpWallet() {
System.currentTimeMillis();
String time = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
String file = String.format("wallet-%s.txt", time);
http.engine("dumpwallet", file);
return file;
}
一旦需要恢復(fù)凭迹,使用importwallet
即可,例如:
/***
* 錢包數(shù)據(jù)導(dǎo)入
* @param: []
* @return: void
* https://bitcoin.org/en/developer-reference#importwallet
*對(duì)于影響新添加的密鑰的事務(wù)苦囱,調(diào)用可能需要重新掃描整個(gè)鏈嗅绸,可能需要幾分鐘。
**/
public void importWallet(String fielName) {
http.engine("importwallet", fielName);
}
4.4 冷錢包
冷錢包即不聯(lián)網(wǎng)的錢包撕彤。對(duì)于交易所模式下而言鱼鸠,錢包的作業(yè)其實(shí)就相當(dāng)于銀行的存款系統(tǒng),充值的過(guò)程相當(dāng)于把金額全部匯總到中央地址羹铅。因此可以使用一臺(tái)不聯(lián)網(wǎng)的錢包生成中央地址若干蚀狰,將私鑰保存到U盤或其他加密硬件中,充值金額將匯集到冷錢包中保存职员。一旦需要提現(xiàn)麻蹋,可以根據(jù)金額大小。小額提現(xiàn)可以通過(guò)熱錢包直接發(fā)消息轉(zhuǎn)賬焊切;大額可以使用需要使用指定U盤將私鑰或錢包文件導(dǎo)入到錢包中扮授,然后聯(lián)網(wǎng)轉(zhuǎn)賬。操作完成后斷網(wǎng)专肪,重新保存硬件即可刹勃。
這一過(guò)程需要注意,冷錢包因?yàn)闊o(wú)法聯(lián)網(wǎng),自然也無(wú)法知道余額嚎尤。那么可以設(shè)置觀察錢包對(duì)中央錢包地址進(jìn)行余額觀察荔仁,以確保充值到賬。在實(shí)際業(yè)務(wù)中芽死,提現(xiàn)過(guò)程可能還需要人工進(jìn)行審核乏梁。
4.5 錢包與服務(wù)端隔離
一般情況下,錢包與服務(wù)端會(huì)部署在同一臺(tái)服務(wù)器上收奔。這種方式有兩個(gè)缺陷掌呜,第一是錢包需要的存儲(chǔ)空間龐大,但需要的網(wǎng)絡(luò)帶寬很低坪哄,與業(yè)務(wù)相關(guān)的服務(wù)器部署子啊同一服務(wù)器上將造成資源的浪費(fèi)质蕉。第二是這種方式有一些安全隱患势篡。所以建議錢包單獨(dú)部署到一臺(tái)服務(wù)器上,如果業(yè)務(wù)允許模暗,還可以同時(shí)備份到多臺(tái)冗余服務(wù)器上禁悠。錢包與服務(wù)端的通訊可以使用 “消息隊(duì)列”。
注意使用Queue兑宇,而不是Topics碍侦,同一時(shí)間內(nèi),只有一個(gè)消費(fèi)者和一個(gè)生產(chǎn)者隶糕。
4.6 USDT假鈔漏洞
這是一種不常見(jiàn)的代碼漏洞瓷产,但對(duì)于部分小型交易所卻很容易中招。如果你是開發(fā)人員枚驻,請(qǐng)務(wù)必不要進(jìn)行偽造usdt的嘗試(盡管很容易濒旦,但這屬于違法)。如果你是運(yùn)維人員請(qǐng)務(wù)必檢查充值流程的代碼細(xì)節(jié)是否存在被假鈔攻擊的可能再登。
如果文章的內(nèi)容對(duì)你有所幫助尔邓,希望你能點(diǎn)贊、投幣锉矢、收藏三連梯嗽。
如果你對(duì)區(qū)塊鏈技術(shù)有興趣,可以加入我們?cè)诤贾莸慕涣魅骸?/p>