pos機開發api

 新聞資訊2  |   2023-08-12 10:28  |  投稿人:pos機之家

網上有很多關于pos機開發api,Facebook最新Libra幣開發指南的知識,也有很多人為大家解答關于pos機開發api的問題,今天pos機之家(www.shbwcl.net)為大家整理了關于這方面的知識,讓我們一起來看下吧!

本文目錄一覽:

1、pos機開發api

pos機開發api

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

集成到命令行工具

我們首先需要將我們開發的Web服務器,集成到Libra Core Client中。首先打開libra/client/src/main.rs文件,將上一篇博文中的代碼,除main函數外,全部拷貝到libra/client/src/main.rs文件中。

拷貝完成之后,我們首先編譯運行一下Libra Core Client,以保證我們的程序沒有編譯錯誤,在libra目錄下運行如下命令:

./scripts/cli/start_cli_testnet.sh

在編譯過程中會有一些警告信息,提示我們定義了一些函數而沒有使用這些函數,因為我們定義的命令處理函數,確實沒有調用過,所以我們可以暫時忽略這些警告信息。

接著我們在原來loop循環開始時調用啟動我們服務器的方法,啟動服務器,如下所示:

...... 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) => { ......*/

在上面的代碼中,我們將client_proxy作為參數傳入,實際上所有調用Libra Core功能的操作,均由此對象來實現。

重新編譯運行客戶端。我們應該可以看到Web服務器已經正常啟動,在瀏覽器上輸入http://127.0.0.1:7878/ls?cmd=query_balance&account_id=88 ,會顯示如下所示的結果:

如果可以顯示上述結果,就證明我們的Web服務器已經正常啟動,并且可以正常接受和處理Libra Core的命令了。下面我們將在接收到客戶端發送過來的命令之后,調用Libra Core相應接口,執行相應的邏輯,最后將調用結果返回給客戶端。

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

由于我們要在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); }}

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

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[..]); // 不處理請求網站圖標請求 if request.find("GET /favicon.ico HTTP/1.1") >= Some(0) { return ; } // 請出請求中的query string let 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\\\\{}", contents); stream.write(response.as_bytes()).unwrap(); stream.flush().unwrap();}/*** 獲取請求中的Query String,規定參數以?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參數值* @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();}

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

賬戶生成

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

/*** 生成賬戶命令處理函數* @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;}

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

查詢所有賬戶列表

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

/*** 列出當前系統的所有賬戶* @version v0.0.1 閆濤 2019.06.23*/fn handle_account_list(params: Vec<&str>, client_proxy: &ClientProxy) -> String { return client_proxy.get_all_accounts();}

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

/// 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; }

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

挖礦和發幣

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

/*** 挖指定數量的幣發送給指定的賬戶* @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!("挖礦發幣: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() }}查詢賬戶余額

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

/*** 查詢賬戶余額* @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() }}查詢賬戶最新交易編號

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

/*** 查詢指定賬戶的交易編號,即已經發生的交易數(指轉出的筆數)* @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() }}轉賬

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

/*** 賬戶之間轉賬* @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!("賬戶間轉賬交易: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() }}查詢交易詳細信息

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

/*** 查詢交易詳情* @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() }}

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

以上就是關于pos機開發api,Facebook最新Libra幣開發指南的知識,后面我們會繼續為大家整理關于pos機開發api的知識,希望能夠幫助到大家!

轉發請帶上網址:http://www.shbwcl.net/newsone/97533.html
上一篇:0.3費率pos機 下一篇:pos機普及貼

你可能會喜歡:

版權聲明:本文內容由互聯網用戶自發貢獻,該文觀點僅代表作者本人。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。如發現本站有涉嫌抄襲侵權/違法違規的內容, 請發送郵件至 babsan@163.com 舉報,一經查實,本站將立刻刪除。