使用OmniCore在Unix系統(tǒng)上構(gòu)建USDT錢包(一)

image

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:安裝gitpkg-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ù)初始索引

  • recuserrpcpassword 代表rpc訪問的身份驗證,

  • rpcallowiprpcport代表允許訪問錢包的ip地址及端口。

  • paytxfeeminrelattxfee控制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ù)器,通過getinfoomni_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中:

image
image

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

image

服務(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-RPCBitCoin 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_sendomni_sendall。這種方式必須保證發(fā)送地址上不僅需要有令牌余額,還需要有一定數(shù)量的比特幣用于支付手續(xù)費。從v0.3.1版本開始,Omnicore提供了兩個新的api omni_funded_sendomni_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ù)處理流程如下:

image

這是最簡易的模式,根據(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)度的跟蹤。

image

關(guān)于實際開發(fā)中的常見問題、以及錢包與服務(wù)端交互,或其他安全問題會在下一篇博客中更新
《使用OmniCore在Unix系統(tǒng)上構(gòu)建USDT錢包(二)》

如果文章的內(nèi)容對你有所幫助,希望你能點贊、投幣、收藏三連。
如果你對區(qū)塊鏈技術(shù)有興趣,可以加入我們在杭州的交流群。
參考資料:

Tether USDT 官網(wǎng)

Omni Explore.info

Omni Layer GitHub

OmniCore JSON-PRC API

BitCoin JSON-PRC-APi

比特幣WIKI之手續(xù)費

比特幣Test3區(qū)塊瀏覽器

比特幣主網(wǎng)區(qū)塊瀏覽器

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容