日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Facebook最新Libra币开发指南---接口服务器开发2

發(fā)布時間:2025/3/21 编程问答 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Facebook最新Libra币开发指南---接口服务器开发2 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

Facebook最新Libra幣開發(fā)指南---接口服務(wù)器開發(fā)2

2019年06月24日 16:23:16?最老程序員閆濤?閱讀數(shù) 1145

在上一篇博文中,我們已經(jīng)使用Rust語言開發(fā)了一款簡單的Web服務(wù)器,雖然以單線程方式工作,但是可以正確解析Libra Core的常見命令,完成了程序的基本框架,在這一篇文件中,我們將帶領(lǐng)大家逐個實現(xiàn)這些命令,最后形成一個基本完整的程序,最后集成Libra Core的client工具中。這樣我們就有一個Libra Core的Web接口,大家就可以將自己的應(yīng)用系統(tǒng)第一時間移植到Libra Core,相信應(yīng)該在絕對是Libra Core上的第一批應(yīng)用,為明年Facebook推出的主網(wǎng)商用服務(wù)搶占有利的位置。

集成到命令行工具

我們首先需要將我們開發(fā)的Web服務(wù)器,集成到Libra Core Client中。首先打開libra/client/src/main.rs文件,將上一篇博文中的代碼,除main函數(shù)外,全部拷貝到libra/client/src/main.rs文件中。
拷貝完成之后,我們首先編譯運行一下Libra Core Client,以保證我們的程序沒有編譯錯誤,在libra目錄下運行如下命令:

./scripts/cli/start_cli_testnet.sh
  • 1

在編譯過程中會有一些警告信息,提示我們定義了一些函數(shù)而沒有使用這些函數(shù),因為我們定義的命令處理函數(shù),確實沒有調(diào)用過,所以我們可以暫時忽略這些警告信息。
接著我們在原來loop循環(huán)開始時調(diào)用啟動我們服務(wù)器的方法,啟動服務(wù)器,如下所示:

......let config = Config::builder().history_ignore_space(true).completion_type(CompletionType::List).auto_add_history(true).build();let mut rl = Editor::<()>::with_config(config);start_server(&mut client_proxy);/*loop {let readline = rl.readline("libra% ");match readline {Ok(line) => {...... */
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

在上面的代碼中,我們將client_proxy作為參數(shù)傳入,實際上所有調(diào)用Libra Core功能的操作,均由此對象來實現(xiàn)。
重新編譯運行客戶端。我們應(yīng)該可以看到Web服務(wù)器已經(jīng)正常啟動,在瀏覽器上輸入http://127.0.0.1:7878/ls?cmd=query_balance&account_id=88 ,會顯示如下所示的結(jié)果:

如果可以顯示上述結(jié)果,就證明我們的Web服務(wù)器已經(jīng)正常啟動,并且可以正常接受和處理Libra Core的命令了。下面我們將在接收到客戶端發(fā)送過來的命令之后,調(diào)用Libra Core相應(yīng)接口,執(zhí)行相應(yīng)的邏輯,最后將調(diào)用結(jié)果返回給客戶端。

改造啟動方法和處理連接方法

由于我們要在Libra Core Client的模式下運行,我們的啟動方法需要做出如下改動:

fn start_server(client_proxy: &mut ClientProxy) {println!("Libra Server v0.0.3 Starting up ...");let listener = TcpListener::bind("127.0.0.1:7878").unwrap();for stream in listener.incoming() {let stream = stream.unwrap();handle_connection(stream, client_proxy);} }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

我們的連接處理方法需要做出如下改動:

fn handle_connection(mut stream: TcpStream, client_proxy: &mut ClientProxy) {let mut contents: String = String::from("Hello World!");let mut buffer = [0; 1024];// 獲取請求信息stream.read(&mut buffer).unwrap();println!("Request: {}", String::from_utf8_lossy(&buffer[..]));let request = String::from_utf8_lossy(&buffer[..]);// 不處理請求網(wǎng)站圖標請求if request.find("GET /favicon.ico HTTP/1.1") >= Some(0) {return ;}// 請出請求中的query stringlet query_string = &get_query_string(&request);println!("query_string:{}", query_string);let cmd = get_cmd_param(query_string.to_string());println!("接收到命令:cmd={}!", cmd);let params: Vec<_> = query_string.split("&").collect();if cmd.find("account_create")>=Some(0) {contents = handle_account_create(params, client_proxy);} else if cmd.find("account_list")>=Some(0) {contents = handle_account_list(params, client_proxy);} else if cmd.find("account_mint")>=Some(0) {contents = handle_account_mint(params, client_proxy);} else if cmd.find("query_balance")>=Some(0) {contents = handle_query_balance(params, client_proxy);} else if cmd.find("query_sequence")>=Some(0) {contents = handle_query_sequence(params, client_proxy);} else if cmd.find("transfer")>=Some(0) {contents = handle_transfer(params, client_proxy);} else if cmd.find("query_txn_acc_seq")>=Some(0) {contents = handle_query_txn_acc_seq(params, client_proxy);}let response = format!("HTTP/1.1 200 OK\r\n\r\n{}", contents);stream.write(response.as_bytes()).unwrap();stream.flush().unwrap(); }/** * 獲取請求中的Query String,規(guī)定參數(shù)以?cmd=開頭 * @version v0.0.1 閆濤 2019.06.23 */ fn get_query_string(request: &str) -> String {let pos = request.find("?cmd=");if pos <= Some(0) {return "Has no parameters in request".to_string();}let end_pos = request.find(" HTTP/1.1");return (&request[(pos.unwrap()+1)..end_pos.unwrap()]).to_string(); }/** * 獲取請求cmd參數(shù)值 * @version v0.0.1 閆濤 2019.06.23 */ fn get_cmd_param(query_string: String) -> String {let params: Vec<_> = query_string.split("&").collect();for param in params.iter() {println!("item: {}!", param);if param.find("cmd=") >= Some(0) {let cmd = &param[4..];return cmd.to_string();}}return "".to_string(); }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65

與前一篇文章中的程序不同點在于,調(diào)用每個命令處理函數(shù)時,需將client_proxy作為參數(shù)傳入。有了這些公共方法之后,我們就可以開始實現(xiàn)各個命令處理函數(shù)了。

賬戶生成

在命令行模式下,我們通過account create來創(chuàng)建賬戶,在我們的web服務(wù)器中我們通過http://127.0.0.1:7878/ls?cmd=account_create來創(chuàng)建賬戶,命令處理代碼如下所示:

/** * 生成賬戶命令處理函數(shù) * @version v0.0.1 閆濤 2019.06.23 */ fn handle_account_create(_params: Vec<&str>, client_proxy: &mut ClientProxy) -> String {println!("生成新賬戶!");let mut rst: String;match client_proxy.create_next_account() {Ok(account_data) => {rst = format!("{{\"account_id\": \"{}\", \"wallet_address\": \"{}\"}}", account_data.index, hex::encode(account_data.address));},Err(e) => rst = format!("Error creating account:{}", e),}return rst; }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

在這個例子中使用了Rust的一種比較特別的語法,我們用match修飾調(diào)用client_proxy.create_next_account方法,該方法會返回Ok或Err兩種情況,我們需要分別進行處理,大家可以將match 理解為其他語言中的switch語句。

查詢所有賬戶列表

我們通過http://127.0.0.1:7878/ls?cmd=account_list請求來獲取所有賬戶列表,命令處理函數(shù)如下所示:

/** * 列出當前系統(tǒng)的所有賬戶 * @version v0.0.1 閆濤 2019.06.23 */ fn handle_account_list(params: Vec<&str>, client_proxy: &ClientProxy) -> String {return client_proxy.get_all_accounts(); }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

我們在client/src/client_proxy.rs中添加一個新的函數(shù),如下所示:

/// Print index and address of all accounts.pub fn get_all_accounts(&self) -> String {let mut rst: String = String::new();rst.push_str("[");if !self.accounts.is_empty() {for (ref index, ref account) in self.accounts.iter().enumerate() {let mut item: String = String::new();item.push_str(&format!("{{\"account_id\":{}, \"wallet_address\":\"{}\", \"account_seq\":{}, \"account_status\":\"{:?}\"}},", index, hex::encode(&account.address), account.sequence_number, account.status));rst.push_str(&item);}}if let Some(faucet_account) = &self.faucet_account {println!("Faucet account address: {}, sequence_number: {}, status: {:?}",hex::encode(&faucet_account.address),faucet_account.sequence_number,faucet_account.status,);}rst.push_str("]");return rst;}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26

本來在官方程序中,有一個print_all_accounts方法,但是該方法只是將信息打印到屏幕上,這顯然不是我們所需要的,所以我們重寫了這個函數(shù),將其返回值定義為Json字符串。

挖礦和發(fā)幣

我們通過http://127.0.0.1:7878/ls?cmd=account_mint&account_id=1&num_coins=100來進行挖礦和發(fā)幣,表明向編號為1的錢包發(fā)送100個Libra幣,命令處理函數(shù)如下所示:

/** * 挖指定數(shù)量的幣發(fā)送給指定的賬戶 * @version v0.0.1 閆濤 2019.06.23 */ fn handle_account_mint(params: Vec<&str>, client_proxy: &mut ClientProxy) -> String {let mut account_id: String = String::new();let mut num_coins: String = String::new();for param in params.iter() {if param.find("account_id=") >= Some(0) {account_id.push_str(&param[11..]);} else if param.find("num_coins=") >= Some(0) {num_coins.push_str(&param[10..]);}}println!("挖礦發(fā)幣:account_id={}; num_coins={}!", account_id, num_coins);let cmd = format!("mint {} {}", account_id, num_coins);let params = ["mint", account_id.as_str(), num_coins.as_str()];match client_proxy.account_mint_coins(&params, false) {Ok(msg) => return msg,Err(_) => "{{\"status\": \"Error\"}}".to_string()} }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

查詢賬戶余額

我們通過http://127.0.0.1:7878/ls?cmd=query_balance&account_id=1來查詢賬戶編號為1的賬戶的余額,命令處理函數(shù)如下所示:

/** * 查詢賬戶余額 * @version v0.0.1 閆濤 2019.06.23 */ fn handle_query_balance(params: Vec<&str>, client_proxy: &mut ClientProxy) -> String {let mut account_id: String = String::new();for param in params.iter() {if param.find("account_id=") >= Some(0) {account_id.push_str(&param[11..]);} }println!("查詢余額:account_id={};!", account_id);let params = ["balance", account_id.as_str()];match client_proxy.get_balance(&params) {Ok(num) => {let resp = format!("{{\"status\": \"Ok\", \"balance\": {} }}", num);return resp;},Err(_) => "{{\"status\": \"Error\"}}".to_string()} }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

查詢賬戶最新交易編號

我們通過http://127.0.0.1:7878/ls?cmd=query_sequence&account_id=1查詢賬戶編號為1的賬戶的交易編號,注意這里只有資金轉(zhuǎn)出時才產(chǎn)生交易,命令處理方法如下所示:

/** * 查詢指定賬戶的交易編號,即已經(jīng)發(fā)生的交易數(shù)(指轉(zhuǎn)出的筆數(shù)) * @version v0.0.1 閆濤 2019.06.23 */ fn handle_query_sequence(params: Vec<&str>, client_proxy: &mut ClientProxy) -> String {let mut account_id: String = String::new();for param in params.iter() {if param.find("account_id=") >= Some(0) {account_id.push_str(&param[11..]);}}println!("查詢交易編號:account_id={};!", account_id);let params = ["sequence", account_id.as_str()];match client_proxy.get_sequence_number(&params) {Ok(seq) => {let resp = format!("{{\"status\": \"Ok\", \"sequence\": {} }}", seq);return resp;},Err(_) => "{{\"status\": \"Error\"}}".to_string()} }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

轉(zhuǎn)賬

我們通過http://127.0.0.1:7878/ls?cmd=transfer&src_account_id=1&dest_account_id=2&amount=20來實現(xiàn)從賬戶1轉(zhuǎn)20個Libra幣給賬戶2,命令處理函數(shù)如下所示:

/** * 賬戶之間轉(zhuǎn)賬 * @version v0.0.1 閆濤 2019.06.23 */ fn handle_transfer(params: Vec<&str>, client_proxy: &mut ClientProxy) -> String {let mut src_account_id: String = String::new();let mut dest_account_id: String = String::new();let mut amount: String = String::new();for param in params.iter() {if param.find("src_account_id=") >= Some(0) {src_account_id.push_str(&param[15..]);} else if param.find("dest_account_id=") >= Some(0) {dest_account_id.push_str(&param[16..]);} else if param.find("amount=") >= Some(0) {amount.push_str(&param[7..]);}}println!("賬戶間轉(zhuǎn)賬交易:src_account_id={}; dest_account_id={}; amount={}!", src_account_id, dest_account_id, amount);let params = ["transfer", src_account_id.as_str(),dest_account_id.as_str(),amount.as_str()];match client_proxy.transfer_coins(&params, false) {Ok(ias) => {let resp = format!("{{\"status\": \"Ok\", \"account_index\": {}, \"account_number\": {} }}", ias.account_index, ias.sequence_number);return resp;},Err(_) => "{{\"status\": \"Error\"}}".to_string()} }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

查詢交易詳細信息

我們通過http://127.0.0.1:7878/ls?cmd=query_txn_acc_seq&account_id=1&seq=1用來查詢賬戶1的編號為1的交易的詳情,命令處理函數(shù)如下所示:

/** * 查詢交易詳情 * @version v0.0.1 閆濤 2019.06.23 */ fn handle_query_txn_acc_seq(params: Vec<&str>, client_proxy: &mut ClientProxy) -> String {let mut account_id: String = String::new();let mut seq: String = String::new();for param in params.iter() {if param.find("account_id=") >= Some(0) {account_id.push_str(&param[11..]);} else if param.find("seq=") >= Some(0) {seq.push_str(&param[4..]);}}println!("查詢交易詳情:account_id={}; seq={}!", account_id, seq);let params = ["txn_acc_seq", account_id.as_str(), seq.as_str(), "false"];match client_proxy.get_committed_txn_by_acc_seq(&params) {Ok(rst) => {let mut resp = String::new(); //format!("{{\"status\": \"Ok\" }}");if let Some(obj) = rst {let trans = obj.0;resp.push_str(&trans.format_for_client(name_cb));}return resp;},Err(_) => "{{\"status\": \"Error\"}}".to_string()} }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28

這樣,我們就擁有了一個與官方命令功能相等的Web API,雖然十分簡陋,但是作為應(yīng)用系統(tǒng)測試后臺已經(jīng)足夠了,我們可以現(xiàn)在就開始構(gòu)建基于Libra的應(yīng)用系統(tǒng),祝大家能抓住Libra的商機。

總結(jié)

以上是生活随笔為你收集整理的Facebook最新Libra币开发指南---接口服务器开发2的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。