
USDT是由Tether公司發(fā)行的基于比特幣區(qū)塊鏈的一種去中心化數(shù)字貨幣,作為當(dāng)前數(shù)字貨幣市場的主流錨定貨幣之一,其官方承諾將嚴(yán)格遵守與美元1:1的比例準(zhǔn)備保證金。在技術(shù)層面,USDT是基于Omni協(xié)議發(fā)行的代幣,在Omni共識網(wǎng)絡(luò)上令牌id為31。Omni是一個可以自由發(fā)行數(shù)字貨幣的平臺,它完全基于比特幣協(xié)議,并在原有的比特幣核心上增加了新的共識網(wǎng)絡(luò),類似與HTTP協(xié)議基于TCP協(xié)議。
OmniCore是Omni協(xié)議的C++實現(xiàn),完全采用與bitcoin的區(qū)塊數(shù)據(jù),所以如果需要同時集成USDT與BTC,實際上只需要使用OmniCore一個核心錢包即可。
本文的主要內(nèi)容是介紹如何在服務(wù)端集成OmniCore實現(xiàn)USDT錢包的基本功能
示例代碼倉庫 https://github.com/initsysctrl/WalletDe
參數(shù)說明:
- 服務(wù)端 Ubuntu x86 5.4.0-6
- OmniCore 0.3.1 fork bitcoin 0.13
- 語言:java 、c++
一.安裝與配置
1.安裝OmniCore客戶端
Step1:安裝git和pkg-config,已經(jīng)安裝過的可以跳過
sudo apt-get install git
sudo apt-get install pkg-config
Step2:Clone OmniCore
git clone https://github.com/OmniLayer/omnicore.git
Step3:安裝依賴項
首先安裝必須的構(gòu)建工具
sudo apt-get install build-essential libtool autotools-dev automake pkg-config libssl-dev libevent-dev bsdmainutils
然后安裝boost,為了兼容各個系統(tǒng)版本,建議安裝所有的boost開發(fā)包
sudo apt-get install libboost-all-dev
最后安裝BerkeleyDB。盡管Ubuntu自帶libdb-dev,但同樣為了錢包的兼容性,建議使用下面的版本
sudo apt-get install software-properties-common
sudo add-apt-repository ppa:bitcoin/bitcoin
sudo apt-get update
sudo apt-get install libdb4.8-dev libdb4.8++-dev
本文中并不需要構(gòu)建Bitcoin-Qt,所以沒有依賴ZMQ和GUI。
Step4:開始構(gòu)建OmniCore
上一步依賴安裝完畢后,進(jìn)入OmnIcore安裝目錄
cd omnicore/
執(zhí)行構(gòu)建腳本
./autogen.sh
./configure
make
2.bitcoin 基本配置
啟動之前,需要配置位于工程目錄之下的.bitcoin文件夾中的OmniCore配置文件bitcoin.conf
server=1
txindex=1
rpcuser=你的rpc用戶名
rpcpassword=你的rpc密碼
rpcallowip=127.0.0.1
rpcport=8332
paytxfee=0.00001
minrelaytxfee=0.00001
datacarriersize=80
logtimestamps=1
omnidebug=tally
omnidebug=packets
omnidebug=pending
server=1代表開啟RPC訪問txindex=1代表事務(wù)初始索引recuser和rpcpassword代表rpc訪問的身份驗證,rpcallowip和rpcport代表允許訪問錢包的ip地址及端口。paytxfee和minrelattxfee控制bitcoin交易的手續(xù)費,Omni交易也屬于一種特殊的比特幣交易,打包與廣播也需要向礦工支付費用。手續(xù)費設(shè)置過低會造成交易確認(rèn)慢甚至交易失敗,手續(xù)費過高會造成資源的浪費(以2018.09.13的BTC價格換算,每多消耗0.0001btc需要浪費4rmb),所以設(shè)置動態(tài)配置交易手續(xù)費十分必要。預(yù)估比特幣交易手續(xù)費可以使用下面的網(wǎng)址bitcoinfees.earn,buybitcoinworldwide。假設(shè)當(dāng)前預(yù)估的比特幣交易費率為0.0000001BTC/Byte,那么需要設(shè)置paytxfee=0.00001BTC/kByte。
3.啟動方式
上述構(gòu)建完成后,進(jìn)入omnicore/src 目錄,開始啟動錢包,啟動時可以配置啟動項以選擇不同的網(wǎng)絡(luò)。
-
./omnicored -testnet連接test3測試網(wǎng)絡(luò),會同步test3網(wǎng)絡(luò)的區(qū)塊數(shù)據(jù)(約20G) -
./omnicored -regtest單機運行,不需要連接其他網(wǎng)絡(luò),區(qū)塊數(shù)據(jù)在本地運行。 -
./omnicored連接比特幣主網(wǎng)網(wǎng)絡(luò),會同步真實區(qū)塊數(shù)據(jù)(約180G)。
錢包初始化完成后,將自動開始同步區(qū)塊。啟動主網(wǎng)或測試網(wǎng)后需要同步一段較長的時間,在這段時間內(nèi)不要進(jìn)行任何交易。可以新開一個終端連接錢包所在服務(wù)器,通過getinfo和omni_getinfo可以查看底層bitcoin信息和上層omni信息。區(qū)塊瀏覽器(Test3區(qū)塊瀏覽器)可以作為區(qū)塊同步的參考。同步將作為守護(hù)進(jìn)程在后臺執(zhí)行,如果需要停止,使用指令 ./omnicore-cli stop。前期開發(fā)建議在test3測試網(wǎng)絡(luò)上進(jìn)行。
$ ./omnicore-cli getinfo
{
"version": 130200,
"protocolversion": 70015,
"walletversion": 130000,
"balance": 4.85909131, //錢包比特幣總余額
"blocks": 1413349,
"timeoffset": 0,
"connections": 0,
"proxy": "",
"difficulty": 56234572.68927951,
"testnet": true, //是否是測試網(wǎng)
"keypoololdest": 1535371434,
"keypoolsize": 100,
"paytxfee": 0.00010000,
"relayfee": 0.00001000,
"errors": ""
}
$ ./omnicore-cli omni_getinfo
{
"omnicoreversion_int": 30001000,
"omnicoreversion": "0.3.1", //omni core 版本
"mastercoreversion": "0.3.1",
"bitcoincoreversion": "0.13.2", //基于比特幣版本
"block": 1413349,//區(qū)塊要舉高高
"blocktime": 1536841368,
"blocktransactions": 0,
"totaltrades": 15601,
"totaltransactions": 43731,
"alerts": [
]
}
二.RPC訪問
1. json-rpc協(xié)議
json-rpc是一種輕量級傳輸協(xié)議,定義一個完整網(wǎng)絡(luò)請求中請求對象的格式和響應(yīng)對象的格式。與rest api相比,僅僅只是數(shù)據(jù)格式的差異而已,網(wǎng)絡(luò)請求的本身并沒有什么差別。
請求對象:
{
"jsonrpc": "2.0",//rpc版本號
"method": "your_method",//方法名
"params": [//參數(shù)數(shù)組
"var1",
"var2"
],
"id": 9527//請求
}
響應(yīng)對象(正確):
{"jsonrpc": "2.0", "result": "this is result", "id": 9527}
響應(yīng)對象(錯誤):
{
"result": null,
"error": {
"code": -32601,//錯誤碼
"message": "Method not found"http://錯誤原因
},
"id": 9527
}
2. 通過RPC接口連接錢包
請求的協(xié)議是http,請求的地址是錢包主機地址。身份驗證信息將以Authorzation的形式添加到headers中,方法、參數(shù)、id信息將以raw的形式添加到hbody中:


返回的結(jié)果如下:

服務(wù)端,以java為例:
String RPC_USER = "your_user_name";
String RPC_PASSWORD = "your_password";
RestTemplate client = new RestTemplateBuilder()
.basicAuthorization(RPC_USER, RPC_PASSWORD)
.rootUri(URL)
.build();
client.postForObject(URL, baseRpcReq, BaseRPCresponse.class);
或者采用jsonrpc4j,這種方式可以捕捉異常便于調(diào)試:
<!--JSON-PRP handler-->
<dependency>
<groupId>com.github.briandilley.jsonrpc4j</groupId>
<artifactId>jsonrpc4j</artifactId>
<version>1.5.3</version>
</dependency>
String RPC_USER = "your_user_name";
String RPC_PASSWORD = "your_password";
String cred = Base64.encodeBase64String((RPC_USER + ":" + RPC_PASSWORD).getBytes());
Map<String, String> headers = new HashMap<>(1);
headers.put("Authorization", "Basic " + cred);
try {
this.mClient = new JsonRpcHttpClient(new URL(URL), headers);
} catch (MalformedURLException e) {
e.printStackTrace();
}
rpc僅僅只是一種數(shù)據(jù)請求的固定格式,username和passwrod并不能保證訪問的安全性。錢包需要配置rpcallowip字段來限定運行訪問錢包的ip地址,默認(rèn)情況下為localhost,在測試節(jié)點,可以使用0.0.0.0/0開啟無限制訪問。
三.核心指令集
Omnicore的指令集完全兼容bitcoin,除了與omni令牌相關(guān)的指令集外,其余的指令集都來全部繼承自bitcoin-cli。下面為錢包創(chuàng)建的核心指令集,更詳細(xì)的內(nèi)容可以從OmniCore JSON-RPC和BitCoin JSON-RPC進(jìn)行查詢。
1.生成BTC、USDT地址
因為Omnicore底層基于Bitcoin,所以USDT地址實際上就是BTC地址,當(dāng)前的比特幣錢包采用的是deterministic wallet錢包模式,使用如樹狀層級推導(dǎo) (hierarchical deterministic) 的推導(dǎo)方式,從一個隨機數(shù)生成源推導(dǎo)所有地址密鑰。所以一個USDT錢包中,所有的地址實際上來自同一個種子源。如果是測試網(wǎng)絡(luò),地址一般以"m","n"獲取新地址可以指定account名稱,如果不指定,那么會分配到默認(rèn)賬戶。
$ ./omnicore-cli getnewaddress
mkRj6TFspkyso96LvDTJq77DwoqoFMBEcJ
$ ./omnicore-cli getnewaddress feeaccount
n1WuiWX5zjmz7MVymUtsdSnC325xQ1v4SR
一個賬戶名可以對應(yīng)多個地址
$ ./omnicore-cli getaddressesbyaccount feeaccount
[
"mk8cMZBX7v7zzzc9FHBMQbRNVPwRtq9CZ2",
"n1WuiWX5zjmz7MVymUtsdSnC325xQ1v4SR"
]
如果是正式環(huán)境,那么必須使用其他地址轉(zhuǎn)賬或提現(xiàn)到新地址才能獲取BTC和USDT。如果使用regtest本地網(wǎng)絡(luò),那么需要通過挖礦獲得比特幣。如果使用test3測試網(wǎng)絡(luò),那么TBTC可以從coinfaucet或者faucet獲取。但在測試網(wǎng)絡(luò)是沒有測試usdt的,所有只能用test omni代替usdt進(jìn)行測試。發(fā)送TBTCmoneyqMan7uh8FqdCA2BV5yZ8qVrc9ikLP即可獲得少量TOMNI,匯率為100 TOMNI/1 TBTC,令牌id分別為1和2。
2.查詢BTC的未花費列表
比特幣實際上沒有“余額”這個概念,只有UTXO(Unspent Transaction Outputs)。在傳統(tǒng)的交易系統(tǒng)中,從A地址轉(zhuǎn)給B地址100個單位的資產(chǎn)的過程是把A地址下的余額減100,B地址下的余額加100,兩步必須滿足原子性。但在比特幣中A地址下并沒有余額,只有一張張零碎的“支票”,記錄著每一筆轉(zhuǎn)入資金,轉(zhuǎn)賬的過程實際上是把一張或者多張“支票”湊起來花費掉,沒有花掉的部分作為“找零”返回給找零地址。所以一般需要把找零地址設(shè)置為發(fā)送地址,如果沒有的話,系統(tǒng)將在錢包中隨機挑選一個地址作為“找零地址”。
列出比特幣UTXO:
方法: listunspent
參數(shù):
- min_confrim (int,可選) 最小確認(rèn)
- max_comfrim(int ,可選)最大確認(rèn)
- address (string[],可選)地址列表
返回:UTXO列表
$ ./omnicore-cli listunspent 0 999999 '["mjH1iB7wt5TC4f8qjvZqtmBXd1aCPSPinC"]'
[
{
"txid": "ef6e77063dff8988b82044286b3d3f022df5a14aae260179a95c2e80c0e47ec4",//來源
"vout": 2,
"address": "mjH1iB7wt5TC4f8qjvZqtmBXd1aCPSPinC",//地址
"account": "account0",//所屬賬戶
"scriptPubKey": "76a914293d87f697ca96ffb00f049b60645e5c8979498488ac",
"amount": 0.00054600,//支票金額
"confirmations": 799,
"spendable": true,//可花費?
"solvable": true
}
]
3.USDT轉(zhuǎn)賬
USDT的轉(zhuǎn)賬實際上是代號為31的OmniCore令牌轉(zhuǎn)賬。Omnicore提供了多套api實現(xiàn)令牌轉(zhuǎn)賬功能,v0.3.1版本之前,可以使用omni_send和omni_sendall。這種方式必須保證發(fā)送地址上不僅需要有令牌余額,還需要有一定數(shù)量的比特幣用于支付手續(xù)費。從v0.3.1版本開始,Omnicore提供了兩個新的api omni_funded_send和omni_funded_sendall,這種方式的好處在于可以指定手續(xù)費的支付方,所有的令牌交易都可以使用統(tǒng)一的地址進(jìn)行支付比特幣手續(xù)費,而不需要發(fā)送者自身擁有比特幣。但這里并未設(shè)定手續(xù)費的具體數(shù)量,系統(tǒng)將根據(jù)在配置文件中的關(guān)于手續(xù)費的配置文件進(jìn)行動態(tài)設(shè)定。
方法 omni_funded_send
參數(shù)
fromaddress (string,必選) 令牌發(fā)送者
toaddress (string,必選) 令牌接收者
propertyid (number,必選) 令牌id
amount (string,必選) 發(fā)送金額
feeaddress (string,可選)用于支付手續(xù)費的地址,如果設(shè)置此地址,那么此地址上必須擁有比特幣
返回:事務(wù) hex
$ ./omnicore-cli omni_funded_send mjH1iB7wt5TC4f8qjvZqtmBXd1aCPSPinC mqrA5Ai8XdKe1ob1L2HwyYr3TXUf9nUeBf 1 5 mpaumxor659PhoJhXp1VCVHVwbFCZSRmuf
a25260a79243a48df21ca2d9fba2209818ea1339026d91b6476d531929c52dad
錯誤返回:
{
error code: -212
error message:Error choosing inputs for the send transaction
}
發(fā)送USDT或其他令牌的過程屬于一種比較特殊的比特幣交易,交易的打包廣播同樣需要支付礦工費用,費用太低交易將無法成功。發(fā)送令牌的過程可能會出現(xiàn)各種錯誤,可以檢查發(fā)送者地址是否是本地錢包地址令牌余額是否充足、feeaddress是否是本機錢包地址、比特幣余額是否充足。
除了使用基本的api外,還可以使用 Raw Transaction API 創(chuàng)建并廣播事務(wù),但過程相當(dāng)?shù)姆爆崳枰?jīng)過七步構(gòu)建。一般情況下不建議這么做,但如果需要將打包簽名的過程與發(fā)送的過程進(jìn)行分離,那么就必須使用這種方式。例如某些情況下,需要在冷錢包中簽名,然后在熱錢包中廣播。
4.查詢交易事務(wù)
方法:omni_gettransaction
參數(shù):hex(string_64位事務(wù)哈希),發(fā)送交易后的交易哈希txid
返回 :
- 未確認(rèn)狀態(tài)
$ ./omnicore-cli omni_gettransaction a25260a79243a48df21ca2d9fba2209818ea1339026d91b6476d531929c52dad
{
"txid": "a25260a79243a48df21ca2d9fba2209818ea1339026d91b6476d531929c52dad",//交易哈希
"fee": "0.00002765",//手續(xù)費金額
"sendingaddress": "mjH1iB7wt5TC4f8qjvZqtmBXd1aCPSPinC",//發(fā)送者
"referenceaddress": "mqrA5Ai8XdKe1ob1L2HwyYr3TXUf9nUeBf",//接受者
"ismine": true,//是否本機地址
"version": 0,
"type_int": 0,
"type": "Simple Send",
"propertyid": 1,
"divisible": true,
"amount": "5.00000000",//發(fā)送令牌金額
"confirmations": 0//確認(rèn)數(shù),,默認(rèn)情況下,>5一般才認(rèn)為交易有效
}
- 已確認(rèn)狀態(tài)
$ ./omnicore-cli omni_gettransaction a25260a79243a48df21ca2d9fba2209818ea1339026d91b6476d531929c52dad
{
"txid": "a25260a79243a48df21ca2d9fba2209818ea1339026d91b6476d531929c52dad",//交易哈希
"fee": "0.00002765",
"sendingaddress": "mjH1iB7wt5TC4f8qjvZqtmBXd1aCPSPinC",//發(fā)送address
"referenceaddress": "mqrA5Ai8XdKe1ob1L2HwyYr3TXUf9nUeBf",//接收address
"ismine": true,
"version": 0,
"type_int": 0,
"type": "Simple Send",//交易類型
"propertyid": 1,
"divisible": true,
"amount": "5.00000000",
"valid": true,//已經(jīng)成功
"blockhash": "00000000000000460219a9fe9761cb92120eb7d67b640d2b643a0a05185fa2a0",
"blocktime": 1536324400,
"positioninblock": 1391,
"block": 1412595,
"confirmations": 1123//通過節(jié)點確認(rèn)
}
5.查詢本地事務(wù)列表
方法:omni_listtransactions
參數(shù):
| addfilt | string | 可選 | 地址過濾 (default: "*") |
|---|---|---|---|
count |
number | 可選 | 最大數(shù)量(default: 10) |
skip |
number | 可選 | 跳過第n個事務(wù) (default: 0) |
startblock |
number | 可選 | 起始的區(qū)塊(default: 0) |
endblock |
number | 可選 | last block to include in the search (default: 999999) |
? 請求:
$ ./omnicore-cli omni_listtransactions
[
{
"txid": "a25260a79243a48df21ca2d9fba2209818ea1339026d91b6476d531929c52dad",//事務(wù)哈希
"fee": "0.00002765",//手續(xù)費
"sendingaddress": "mjH1iB7wt5TC4f8qjvZqtmBXd1aCPSPinC",//發(fā)送
"referenceaddress": "mqrA5Ai8XdKe1ob1L2HwyYr3TXUf9nUeBf",//接收
"ismine": true,
"version": 0,
"type_int": 0,
"type": "Simple Send",//類型
"propertyid": 1,//令牌id
"divisible": true,
"amount": "5.00000000",
"valid": true,//是否有效的交易事務(wù)
"blockhash": "00000000000000460219a9fe9761cb92120eb7d67b640d2b643a0a05185fa2a0",
"blocktime": 1536324400,
"positioninblock": 1391,
"block": 1412595,
"confirmations": 221//確認(rèn)數(shù),默認(rèn)大于5猜有效
},
{
"txid": "2e527c3c85b2a9b21252b50efd6cda31022ee5ebcf9fee451255bea61211b799",
"fee": "0.00002570",
"sendingaddress": "mjH1iB7wt5TC4f8qjvZqtmBXd1aCPSPinC",
"referenceaddress": "mq8fRoxRB9M4vstJ9BrEBaysZVUjxPxoK3",
"ismine": true,
"version": 0,
"type_int": 0,
"type": "Simple Send",
"propertyid": 2,
"divisible": true,
"amount": "3.00000000",
"valid": true,
"blockhash": "0000000000000007c957dc0642c39c26b9bb46327620e18e23244936f894c570",
"blocktime": 1536324082,
"positioninblock": 2115,
"block": 1412594,
"confirmations": 222
}
]
如果交易剛剛發(fā)送,即沒有被驗證是否合法,也沒有被節(jié)點確認(rèn),那么該事務(wù)將處于pengding 狀態(tài)使用 omni_listtransactions 不能作為轉(zhuǎn)賬的確認(rèn)狀態(tài)。使用omni_listpendingtransactions可以在緩沖區(qū)找到這一類型的事務(wù)信息,但pengding狀態(tài)并不穩(wěn)定,不能用于確認(rèn)轉(zhuǎn)賬結(jié)果。
6.查詢指定地址的USDT余額
查詢USDT的余額即查詢第31號令牌的余額。
方法:omni_getbalance
參數(shù):
- address 地址
- id 令牌id
$ ./omnicore-cli omni_getbalance mjH1iB7wt5TC4f8qjvZqtmBXd1aCPSPinC 1
{
"balance": "4.00000000",//余額
"reserved": "0.00000000",
"frozen": "0.00000000"http://被凍結(jié),沒啥用
}
7.查詢錢包內(nèi)的所有地址的USDT余額列表
方法:omni_getwalletaddressbalances將返回錢包內(nèi)所有余額不為0的地址列表,每個地址都可能有不同的令牌余額。令牌id如果為31,那么這個令牌即USDT。
$ ./omnicore-cli omni_getwalletaddressbalances
[
{
"address": "mjH1iB7wt5TC4f8qjvZqtmBXd1aCPSPinC",//地址
"balances": [
{
"propertyid": 1,//令牌id,31=USDT
"name": "Omni",//令牌名稱
"balance": "4.00000000",//余額
"reserved": "0.00000000",
"frozen": "0.00000000"
},
{
"propertyid": 2,
"name": "Test Omni",
"balance": "7.00000000",
"reserved": "0.00000000",
"frozen": "0.00000000"
}
]
}
]
8.查詢錢包內(nèi)的USDT總額
方法:omni_getwalletbalances
返回:
$ ./omnicore-cli omni_getwalletbalances
[
{
"propertyid": 1,//令牌id
"name": "Omni",//令牌名稱
"balance": "11.00000000",//可用余額
"reserved": "0.00000000",
"frozen": "0.00000000"
},
{
"propertyid": 2,
"name": "Test Omni",
"balance": "8.00000000",
"reserved": "0.00000000",
"frozen": "0.00000000"
}
]
其他的相關(guān)指令集會在源代碼中示例出來。
四.中心化錢包模式
中心化錢包的本質(zhì)是代替用戶托管資產(chǎn),錢包保存了所有地址的私鑰,對上面的令牌有完全的使用權(quán)。對于用戶而言,對資產(chǎn)的流動有知情權(quán),但并沒有實際控制權(quán)。一個完整的中心化錢包可以分為兩層,記賬層和區(qū)塊底層,至少需要集成四個基本的業(yè)務(wù)功能:
1.地址生成
USDT地址即比特幣區(qū)塊鏈上的地址,借助比特幣內(nèi)核 getnewaddress可以從同一個種子推導(dǎo)出無數(shù)個地址,生成地址的過程類似與把一枚硬幣連續(xù)拋255次。服務(wù)端需要在自己的用戶系統(tǒng)中為每個用戶生成不同的地址,用戶的看到的資產(chǎn)實際上服務(wù)端的記賬狀態(tài),并非真實資產(chǎn)。
2.掃描充值事務(wù)
錢包一旦啟動,會開啟同步區(qū)塊的守護(hù)進(jìn)程,服務(wù)端不需要進(jìn)行手動的區(qū)塊同步操作。但服務(wù)端需要定期的掃描區(qū)塊以發(fā)現(xiàn)并確認(rèn)充值事務(wù)。通過omni_listtransactions可以查詢當(dāng)前錢包內(nèi)的事務(wù)列表,根據(jù)業(yè)務(wù)需要,可以定時每小時全量掃描一次,每次最多返回100條事務(wù)。遍歷每條事務(wù),如果事務(wù)已經(jīng)驗證且確認(rèn)數(shù)大于等于6,那么被認(rèn)為是一條有效的充值記錄。然后判斷記賬層是否已經(jīng)記錄了該事務(wù),如果沒有記錄則寫入充值記錄表,同時查詢綁定該地址的用戶,在余額表中該用戶的可用余額加上充值金額。如果已經(jīng)寫入了那么跳過本次事務(wù)。單次的事務(wù)處理流程如下:

這是最簡易的模式,根據(jù)業(yè)務(wù)情景可以適當(dāng)調(diào)整掃描周期和最大事務(wù)數(shù)。
3.轉(zhuǎn)移充值余額
用戶充值后USDT保留在用戶綁定的區(qū)塊地址中,需要及時的轉(zhuǎn)移到中央地址中去。中央地址即保存整個平臺資產(chǎn)的一個或者多個地址??梢允褂门c普通用戶相同的“種子”,也可以單獨使用一個錢包,或者直接使用冷錢包離線保存。在保證安全和效率的情況下,越少的轉(zhuǎn)賬次數(shù)越好,可以最大限度的節(jié)省手續(xù)費。獲取錢包地址USDT余額列表有多種方式 ,從v0.3.1開始可以使用omni_getwalletaddressbalances直接返回所有每個地址的所有令牌列表。一旦檢測id=31的令牌余額不為0,且大于最小額度(一般大于預(yù)估的手續(xù)費)則使用omni_funded_sendall轉(zhuǎn)移所有的USDT到指定的中央錢包。
但需要注意的是,在Omnicore上從發(fā)送者轉(zhuǎn)賬轉(zhuǎn)移指定id的令牌到接受者,當(dāng)交易被創(chuàng)建且被發(fā)送成功后,交易驗證需要一定時間,發(fā)送者的令牌余額不會立即變化。所以如果掃描余額的時間周期太短,會造成一個地址上的余額被多次轉(zhuǎn)移,雖然只會有一次成功但會重復(fù)消耗手續(xù)費,所以建議2-6hour掃描一次本地錢包余額列表。
4.提現(xiàn)事件
提現(xiàn)是指用戶把實際資產(chǎn)從平臺錢包中轉(zhuǎn)移出去,只要判斷是本人操作而且提現(xiàn)金額小于可用額度就被認(rèn)為是有效的提現(xiàn)請求。根據(jù)提現(xiàn)地址的不同有兩種情況:
當(dāng)提現(xiàn)地址是錢包內(nèi)的地址時(即平臺內(nèi)的另外一個用戶)屬于內(nèi)部轉(zhuǎn)賬。這種方式并不需在從中央錢包發(fā)送USDT到指定地址,只需要在記賬層進(jìn)行依次對兩個賬戶上的USDT余額進(jìn)行修改,幾乎沒有時間延遲。
當(dāng)提現(xiàn)地址是不是錢包內(nèi)的地址時(非平臺用戶)屬于外部轉(zhuǎn)賬。這種方式需要操作區(qū)塊鏈,不會馬上進(jìn)行確認(rèn),根據(jù)手續(xù)費設(shè)定和當(dāng)前比特幣主網(wǎng)擁堵狀況可能需要幾小時到一天的確認(rèn)時間。
對于外部轉(zhuǎn)賬,如果用戶綁定的區(qū)塊地址上還存在余額,那么優(yōu)先使用該地址進(jìn)行轉(zhuǎn)賬,其次選擇中央錢包進(jìn)行轉(zhuǎn)賬。可以使用omni_funded_send來進(jìn)行創(chuàng)建USDT交易并廣播,交易發(fā)送成功后會生成的事務(wù)哈希。根據(jù)事務(wù)哈希,通過omni_gettransaction可以進(jìn)行提現(xiàn)進(jìn)度的跟蹤。

關(guān)于實際開發(fā)中的常見問題、以及錢包與服務(wù)端交互,或其他安全問題會在下一篇博客中更新
《使用OmniCore在Unix系統(tǒng)上構(gòu)建USDT錢包(二)》
如果文章的內(nèi)容對你有所幫助,希望你能點贊、投幣、收藏三連。
如果你對區(qū)塊鏈技術(shù)有興趣,可以加入我們在杭州的交流群。
參考資料: