㈠ JSON-RPC輕量級遠程調用協議介紹及使用
json-rpc是基於json的跨語言遠程調用協議。比xml-rpc、webservice等基於文本的協議數據傳輸格小;相對hessian、java-rpc等二進制協議便於調試、實現、擴展,是很優秀的一種遠程調用協議。眼下主流語言都已有json-rpc的實現框架,java語言中較好的json-rpc實現框架有jsonrpc4j、jpoxy、json-rpc。三者之中jsonrpc4j既可獨立使用。又可與spring無縫集合,比較適合於基於spring的項目開發。
json-rpc協議很easy,發起遠程調用時向服務端數據傳輸格式例如以下:
{ "method": "sayHello", "params": ["Hello JSON-RPC"], "id": 1}
參數說明:
method: 調用的方法名
params: 方法傳入的參數。若無參數則傳入 []
id : 調用標識符。用於標示一次遠程調用過程
server其收到調用請求,處理方法調用,將方法效用結果效應給調用方;返回數據格式:
參數說明:
result: 方法返回值。若無返回值。則返回null。
若調用錯誤,返回null。
error :調用時錯誤,無錯誤返回null。
id : 調用標識符,與調用方傳入的標識符一致。
以上就是json-rpc協議規范,很easy,小巧。便於各種語言實現。
2.1、server端Java調用演示樣例
jsonrpc4jserver端java演示樣例:
2.2、Javaclient調用演示樣例
jsonrpc4j的Javaclient調用演示樣例:
2.3、JavaScriptclient調用演示樣例
基於jsonrpcjs的JavaScriptclient調用演示樣例:
2.4、直接GET請求進行調用
無需不論什麼client。僅僅需手工拼接參數進行遠程調用,請求URL例如以下:
參數說明:
method : 方法名
params :調用參數。json的數組格式[], 將參數需先進行url編碼,再進行base64編碼
id : 調用標識符,隨意值。
json-rpc是一種很輕量級的跨語言遠程調用協議。實現及使用簡單。
僅需幾十行代碼,就可以實現一個遠程調用的client。方便語言擴展client的實現。
server端有php、java、python、ruby、.net等語言實現,是很不錯的及輕量級的遠程調用協議。
㈡ DApp開發入門
本文僅介紹以太坊系列的DApp開發,其他鏈原理差不太多。
MetaMask安裝完成並運行後,可以在Chrome控制台列印 MetaMask注入的window.ethereum對象
關於ethereum對象,我們只需要關心 ethereum.request 就足夠了,MetaMask 使用 ethereum.request(args) 方法 來包裝 RPC API。這些 API 基於所有以太坊客戶端公開的介面。 簡單來說錢包交互的大部分操作都是由 request() 方法實現,通過傳入不同的方法名來區分。
⚠️ 即使ethereum對象中提供了chainId,isMetaMask,selectAddress屬性,我們也不能完全相信這些屬性,他們是不穩定或不標准,不建議使用。我們可以通過上面說的request方法,拿到可靠的數據 。
錢包通過method方法名,進行對應的實現 以獲取錢包地址為例
調用 ethereum.request({ method: "eth_requestAccounts" }) ,錢包實現了該方法,那麼就可以拿到錢包的地址了。
MetaMask注入的 window.ethereum 就是一個Provider,一個RPC節點也是一個Provider,通過Provider,我們有了訪問區塊鏈的能力。 在連接到錢包的情況下,通常使用錢包的Provider就可以了, ethers.providers.Web3Provider(ethereum)
如果只需要查詢一些區塊鏈數據,可以使用EtherscanProvider 和 InfuraProvider 連接公開的 第三方節點服務提供商 。JsonRpcProvider 和 IpcProvider 允許連接到我們控制或可以訪問的以太坊節點。
獲取當前賬戶余額
獲取最新區塊號
其他RPC操作,可以通過 JSON-RPC 查看。
通過 ethers.js 可以連接ERC20的合約,合約編譯後會生成ABI,合約部署後,會生成合約地址,開發者通過 ABI和合約地址 ,對合約發送消息。
合約中的方法大致分為兩種: 視圖方法(免費),非視圖方法(消耗Gas) ,可以通過ABI查看方法類型。
⚠️ ERC20需要多加關注的是 Approve() 方法以及 transfer() 和 transferFrom() 的區別 ,授權過的代幣,被授權的那一方,可以通過調用 transferFrom() 方法,轉走你授權數量內的代幣,所以授權是一個很危險的操作,假設你授權了一個不良的合約,那你會面臨授權的token被轉走的風險,即使你沒有泄露私鑰助記詞。
便利三方庫: web3-react use-wallet
文檔: doc.metamask.io ethers
㈢ 技術基礎--JSON-RPC2.0
最近剛加入區塊鏈學習的熱潮,從一些基本技術開始學起。本文翻譯自 JSON-RPC 2.0 Specification . 其實協議很簡單,本不需要翻譯,主要是為了記錄這個學習過程,以及加深理解。
JSON是一種輕量級的數據交換格式。它可以地標數字,字元串,有序數組,以及鍵值對。
而JSON-RPC是一種無狀態的,輕量級的遠程程序調用協議。不只一種數據結構及其處理規則可以符合這種定義。數據通過socket, http, 或其他環境傳輸,並不能確定其將在本進程內使用。它使用JSON來座位數據格式。
設計也很簡單。
關鍵詞「MUST」, "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", "OPTIONAL"的解釋可以在RFC2119中找到。
由於採用了JSON協議,其可傳輸的數據類型也和JSON相同。JSON可以表示四種基本類型, Strings, Numbers, Booleans, Null,還有兩種結構類型:Objects, Arrays。當我們提到「基本類型」的時候,是指四種基本的JSON類型,而「結構類型」則指代以上兩種JSON結構類型。當提到JSON類型時,總會把第一個字母大寫,比如Object, Array, String, Number, Boolean, Null. True和False也是如此。
JSON-RPC 2.0定義的請求對象和響應對象和現有的JSON-RPC 1.0客戶端/伺服器有兼容問題。這兩個版本其實很好區分,2.0定義了一個叫"jsonrpc"的成員,其值時2.0,而1.0版本沒有。2.0的實現往往要兼容1.0的對象,即使我們在開發點對點以外或者明顯不是1.0的業務的時候亦是如此。
RPC調用是指發送一個請求對象到遠程伺服器上。請求對象包括以下成員:
jsonrpc: 用來聲明JSON-RPC協議的版本,固定為「2.0」
method:需要調用的方法。方法名以單詞rpc開頭,後面跟上期限字元,這個欄位在rpc交互的方法及其擴展上被存儲起來,並且不能用於其他意義。
params: 結構化的值,用於存儲方法響應需要用到的參數,且不能被省略。
id:客戶端分配的一個標識符,可以包含字元串,數字或者為空。如果沒有id,就會被當成是廣播通知。這個值一般不能為Null,且為數字時不能有小數。如果請求中含有這個欄位,伺服器在響應時,必須原樣返回該欄位,用來關聯以下兩個對象的不同環境:
當請求參數中不發送id成員時,該請求會被當作通知處理。對於通知,客戶端不關心響應對象,因為服務端也沒必要返回響應對象,確切的說,服務端不準答復一個通知請求,即便這個請求是批處理請求中的一個。
根據這個定義,通知請求並不會被確認,因為客戶端不會收到響應對象,更進一步說,通知請求的客戶端無法感知到錯誤,比如參數錯誤/網路錯誤等。
RPC調用的參數必須是結構化的值(對象或者數組),對象通過名字遍歷,而數組通過位置可遍歷。
數組參數的遍歷順序必須與服務端順序一致。
對象參數的成員值必須與服務端期望的一致,且在大小寫上精確匹配。一旦有成員缺失,會導致錯誤產生。
當RPC請求出錯時,伺服器響應的Response對象中,必須包含error,且包含以下成員:
code: Number類型,表示出錯類型
message: String類型 簡介的一句話來描述錯誤
data: 可以是基本類型,也可以是結構類型,來表示錯誤的額外信息,且可以預設。具體取值由伺服器自定義,比如錯誤詳情,訪問限制等等。
-32768到-32000之間的錯誤碼是系統保留錯誤碼,協議預定義方便未來使用。錯誤碼的定義和XML-RPC類似:
-32700: 解析錯誤,無效的JSON結構,伺服器在解析JSON時出錯
-32600: 請求無效,Request對象不是一個合法的JSON請求
-32601: 未知的方法,伺服器未定義該method,或者該方法不可用
-32602: 參數錯誤
-32603: 網路錯誤
-32000--32099: 伺服器錯誤,伺服器其他錯誤的保留錯誤碼
上述區間以外的錯誤碼可在應用開發時使用。
同時發送多個Request對象時, 客戶端可以把請求都放到一個數組里一起發送。
服務端收到Request對象數組並處理完成後,應當以數組的形式返回,且數組中包含了響應的請求的Response對象。每一個請求對應一個響應,如果請求是通知的話,則不包含該Response對象。服務端在批處理請求任務時,可以按任何順序或者並行化處理。
服務端對請求進行批處理時者不是至少長度為1的合法請求對象數組時,伺服器響應的對象必須是一個單的Response對象。如果沒有Response數組中不包含Response對象,那也不能返回空數組,而應該什麼都不返回。
--> {"jsonrpc": "2.0", "method": "subtract", "params": [42, 23], "id": 1}
<-- {"jsonrpc": "2.0", "result": 19, "id": 1}
--> {"jsonrpc": "2.0", "method": "subtract", "params": [23, 42], "id": 2}<-- {"jsonrpc": "2.0", "result": -19, "id": 2}
--> {"jsonrpc": "2.0", "method": "subtract", "params": {"subtrahend": 23, "minuend": 42}, "id": 3}<-- {"jsonrpc": "2.0", "result": 19, "id": 3}--> {"jsonrpc": "2.0", "method": "subtract", "params": {"minuend": 42, "subtrahend": 23}, "id": 4}<-- {"jsonrpc": "2.0", "result": 19, "id": 4}
--> {"jsonrpc": "2.0", "method": "update", "params": [1,2,3,4,5]}
--> {"jsonrpc": "2.0", "method": "foobar"}
--> {"jsonrpc": "2.0", "method": "foobar", "id": "1"}
<-- {"jsonrpc": "2.0", "error": {"code": -32601, "message": "Method not found"}, "id": "1"}
--> {"jsonrpc": "2.0", "method": "foobar, "params": "bar", "baz]
<-- {"jsonrpc": "2.0", "error": {"code": -32700, "message": "Parse error"}, "id": null}
--> {"jsonrpc": "2.0", "method": 1, "params": "bar"}
<-- {"jsonrpc": "2.0", "error": {"code": -32600, "message": "Invalid Request"}, "id": null}
--> [ {"jsonrpc": "2.0", "method": "sum", "params": [1,2,4], "id": "1"}, {"jsonrpc": "2.0", "method"]<-- {"jsonrpc": "2.0", "error": {"code": -32700, "message": "Parse error"}, "id": null}
--> []<-- {"jsonrpc": "2.0", "error": {"code": -32600, "message": "Invalid Request"}, "id": null}
--> [1]
<-- [ {"jsonrpc": "2.0", "error": {"code": -32600, "message": "Invalid Request"}, "id": null}]
--> [1,2,3]
<-- [ {"jsonrpc": "2.0", "error": {"code": -32600, "message": "Invalid Request"}, "id": null}, {"jsonrpc": "2.0", "error": {"code": -32600, "message": "Invalid Request"}, "id": null}, {"jsonrpc": "2.0", "error": {"code": -32600, "message": "Invalid Request"}, "id": null}]
--> [
{"jsonrpc": "2.0", "method": "sum", "params": [1,2,4], "id": "1"},
{"jsonrpc": "2.0", "method": "notify_hello", "params": [7]},
{"jsonrpc": "2.0", "method": "subtract", "params": [42,23], "id": "2"},
{"foo": "boo"},
{"jsonrpc": "2.0", "method": "foo.get", "params": {"name": "myself"}, "id": "5"},
{"jsonrpc": "2.0", "method": "get_data", "id": "9"}
]
<-- [
{"jsonrpc": "2.0", "result": 7, "id": "1"},
{"jsonrpc": "2.0", "result": 19, "id": "2"},
{"jsonrpc": "2.0", "error": {"code": -32600, "message": "Invalid Request"}, "id": null},
{"jsonrpc": "2.0", "error": {"code": -32601, "message": "Method not found"}, "id": "5"},
{"jsonrpc": "2.0", "result": ["hello", 5], "id": "9"}
]
--> [
{"jsonrpc": "2.0", "method": "notify_sum", "params": [1,2,4]},
{"jsonrpc": "2.0", "method": "notify_hello", "params": [7]}
]
<-- //Nothing is returned for all notification batches
使用rpc開頭的方法名是系統擴展方法,且不能用於其他場合。每一個系統擴展都在相關聲明中定義。系統擴展是可選的。
1)如何撰寫一個規范,或者說一個規范由哪些部分組成,本規范是一個很好的模版
2)如何做前後兼容。jsonrpc的兼容方式很簡單,在請求頭部擴展一個jsonrpc的版本號即可。如果是良好的設計,在1.0的時候就應該加上此欄位。
3)嚴謹性。比如,我們不能簡單的使用Null作為id參數來表示通知,服務端解析id失敗也返回Null的id,無法區分這兩種情形。
4)批處理。一個好的設計必然要考慮多任務的批處理,在設計批處理時,需要考慮數據的解析,伺服器可能不按序處理,以及可能並發處理,需要考慮不同的請求在不同的時許下處理可能產生的影響
5)舉例。和測試用例的設計有點類似,盡可能覆蓋全面
JSON-RPC 2.0 Specification
㈣ 以太坊event log查詢與解析
從 ethereum json-rpc文檔 的文檔中找到一個同時指定多個事件以 OR 或者 AND 查詢的方法.以下是查詢 Approval 或 Transfer 事件的方法:
topics 欄位中指定查詢條件的語法參考上面鏈接。
通過 getTransactionReceipt 在ropsten測試網上查詢到交易號為 的交易詳情
這個交易從 "from": "" 發送到合約地址 "to": "" .這個合約為ERC20代幣合約.從 topics 的第一個元素可以看出合約中產生了 Transfer 事件(topics第一個元素一定是事件的keccak哈希). topics 的第二個欄位是轉出代幣的地址,第三個欄位是接收者地址.ERC20代幣 Transfer 事件的簽名為
我們注意到 Transfer 事件的第一個和第二個參數被標記為 indexed , 因此他們的值被放在 topics array 中. 由於tokens參數沒有標記為 indexed , 所以他的值被放在 data 欄位. 如果事件中有多個欄位未標記為 indexed , 那麼他們的值都會被記錄在 data 欄位中。
㈤ 以太坊如何使用web3.js或者rpc介面獲取交易數據交易時間與確認數
如果要查詢主網上的交易記錄,可以使用etherscan。但是,如果是你自己搭建的私鏈,應該如何查詢交易記錄呢?
答案是你需要自己監聽鏈上的日誌,存到資料庫里,然後在這個資料庫中查詢。例如:
varaddr=""
varfilter=web3.eth.filter({fromBlock:0,toBlock:'latest',address:addr});
filter.get(function(err,transactions){
transactions.forEach(function(tx){
vartxInfo=web3.eth.getTransaction(tx.transactionHash);
//這時可以將交易信息txInfo存入資料庫
});
});
web3.eth.filter()用來監聽鏈上的日誌,web3.eth.getTransaction()用來提取指定交易的信息,一旦獲得交易信息,就可以存入資料庫供查詢用了。
推薦一個實戰入門,你可以看看:以太坊教程
㈥ Php如何調用以太坊介面
curl方法,file_get_contents,
㈦ Infura API 獲取以太坊當前配置鏈 ID - 區塊鏈數據開發實戰
簡介:Infura 是以太坊和 IPFS 的 API 服務提供商。Infura 一開始只是為 ConsenSys 內部項目提供穩定可靠的 RPC 訪問,後來隨著以太坊生態發展,他們意識到自己可以起到更大作用,於是開始面向開發者提供公共 API 服務。本文整理使用 Infura API 獲取以太坊當前配置鏈 ID 的實現。
Infura 是以太坊和 IPFS 的 API 服務提供商。Infura 一開始只是為 ConsenSys 內部項目提供穩定可靠的 RPC 訪問,後來隨著以太坊生態發展,他們意識到自己可以起到更大作用,於是開始面向開發者提供公共 API 服務。
本文整理使用 Infura API 獲取以太坊當前配置鏈 ID 的實現。
Infura API 官方文檔: https://infura.io/docs
使用 API 需要申請 Project ID ,ID 是免費申請的,申請流程為「注冊 - 登錄 - 創建新項目」,不需要審核,幾分鍾就能搞定。
Infura API 標准請求埠格式:
本例中我們使用基於 HTTP 的以太坊主網 JSON-RPC 埠:
Infura API 獲取以太坊當前配置鏈 ID:
Curl 示例:
Node.js 示例:
返回的 JSON 示例:
返回當前鏈 ID 的大整數。
Infura API 服務思維導圖:
我們有一個區塊鏈知識星球,做區塊鏈前沿資料的歸納整理以方便大家檢索查詢使用,也是國內頂尖區塊鏈技術社區,歡迎感興趣的朋友加入。如果你對上面內容有疑問,也可以加入知識星球提問我: