从零开发区块链应用(十四)--以太坊交易哈希查询
Posted 杰哥的技术杂货铺
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了从零开发区块链应用(十四)--以太坊交易哈希查询相关的知识,希望对你有一定的参考价值。
文章目录
一、查询以太坊交易
当上述事件在合约中调用后,我们通过其交易hash获取交易信息。从以太坊得到一条交易信息的方式有两种:
- eth_getTransactionByHash: :返回指定交易对应的交易信息
- eth_getTransactionReceipt :返回指定交易对应的收据信息
1.1 获取以太坊交易信息
GetTransactionByHash 获取交易信息
// 定义一个方法,接收参数为交易哈希,返回参数为接口类型
func (eth *Http) GetTransactionByHash(hash string) (interface, error)
// 判断交易哈希长度是否为66位
if len(hash) != 66
// 如果交易哈希长度不是66位,则返回交易哈希散列长度错误
return nil, errors.New("GetTransactionByHash hash length wrong")
// 定义一个接口的变量,值为交易哈希
args = []interfacehash
// 调用以太坊rpc,查询交易哈希
params := NewHttpParams("eth_getTransactionByHash", args)
resBody, err := eth.rpc.HttpRequest(params)
if err != nil
return nil, err
// 返回一个解析后的交易信息结果
return eth.ParseJsonRPCResponse(resBody)
- 以太坊rpc调用参数拼接方法:NewHttpParams
func NewHttpParams(method string, args []interface) string
id := common.GetRandString(16)
request := &Request
ID: id,
Mthd: method,
Args: args,
Version: "2.0",
rb, _ := json.Marshal(request)
return string(rb)
- 请求结果解析:ParseJsonRPCResponse
// ParseJsonRPCResponse jsonrpc格式返回结果解析
func (eth *Http) ParseJsonRPCResponse(resBody []byte) (interface, error)
response := new(apicommon.Response)
err := json.Unmarshal(resBody, &response)
if err != nil
logger.Warn("resBody", resBody, string(resBody))
return nil, errors.New("ParseJsonRPCResponse Unmarshal err")
if response.Error != nil // && response.Error.Code != 3
return nil, errors.New(response.Error.Msg)
return response.Result, nil
1.2 获取以太坊交易回执信息
GetTransactionReceipt 获取交易票据
// 定义一个方法,接收参数为交易哈希,返回参数为接口类型
func (eth *Http) GetTransactionReceipt(hash string) (interface, error)
// 判断交易哈希长度是否为66位
if len(hash) != 66
// 如果交易哈希长度不是66位,则返回交易哈希散列长度错误
return nil, errors.New("GetTransactionReceipt hash length wrong")
// 定义一个接口的变量,值为交易哈希
args = []interfacehash
// 调用以太坊rpc,查询交易哈希
params := NewHttpParams("eth_getTransactionReceipt", args)
resBody, err := eth.rpc.HttpRequest(params)
if err != nil
return nil, err
// 返回一个解析后的交易信息结果
return eth.ParseJsonRPCResponse(resBody)
- 以太坊rpc调用参数拼接方法:NewHttpParams
func NewHttpParams(method string, args []interface) string
id := common.GetRandString(16)
request := &Request
ID: id,
Mthd: method,
Args: args,
Version: "2.0",
rb, _ := json.Marshal(request)
return string(rb)
- 请求结果解析:ParseJsonRPCResponse
// ParseJsonRPCResponse jsonrpc格式返回结果解析
func (eth *Http) ParseJsonRPCResponse(resBody []byte) (interface, error)
response := new(apicommon.Response)
err := json.Unmarshal(resBody, &response)
if err != nil
logger.Warn("resBody", resBody, string(resBody))
return nil, errors.New("ParseJsonRPCResponse Unmarshal err")
if response.Error != nil // && response.Error.Code != 3
return nil, errors.New(response.Error.Msg)
return response.Result, nil
二、以太坊交易确认数
以太坊和比特币一样,都有一个最长链的概念,因此也有一个交易确认数的概念。
当一个以太坊交易所在区块被新加入区块链时,该交易的确认数为1,之后每增加
一个区块,该交易的确认数加1。显然,一个以太坊交易的确认数越多,就意味着
该交易在区块链中埋的越深,就越不容易被篡改。那么,应该如何获取一个以太坊
交易的确认数?
2.1 使用rpc获取以太坊交易确认数
要获取一个以太坊交易的确认数,需要使用两个RPC调用:
- eth_getTransactionReceipt:获取交易收据
- eth_blockNumber:获取最新区块号
首先利用eth_getTransactionReceipt调用获取指定的交易收据,例如,下面的命令获取交易0xbca39c1f778fcae9e86b513b6e18ed4b0a04b8e0ad5a0c1c1c81788ab1e94bbd的收据:
curl -X POST --data '
"jsonrpc":"2.0",
"method":"eth_getTransactionReceipt",
"params":["0xb903239f8543d04b5dc1ba6579132b143087c68db1b2168786408fcbce568238"],
"id":1' http://localhost:8545
在结果中可以获取该交易所在区块编号:
"id":1,
"jsonrpc":"2.0",
"result":
...
blockNumber: '0xd70aca', // 区块14093002
...
然后就可以在随后的任意时刻使用eth_blockNumber调用来获取当前最新块信息,例如:
curl -X POST --data '
"jsonrpc":"2.0",
"method":"eth_blockNumber",
"params":[],
"id":83' http://localhost:8545
在结果中可以获取当前最新一个区块编号:
"id":83,
"jsonrpc": "2.0",
"result": "0xd70adc" // 区块14093020
用区块链中最后一个区块的编号,减去交易所在区块编号,再加1,就可以得到一个以太坊交易的确认数了:
交易确认数 = 最新区块号 - 交易所在区块号 + 1 = 15 - 11 + 1 = 5
2.2 使用golang获取以太坊交易确认数
基于上面的原理,我们很容易编写golang代码来获取以太坊交易确认数:
// 定义一个方法,接收参数为交易哈希,返回参数为接口类型
func (eth *Http) getTxConfirms(hash string) (interface, error)
//获取交易确认高度
// 判断交易哈希长度是否为66位
if len(hash) != 66
// 如果交易哈希长度不是66位,则返回交易哈希散列长度错误
return nil, errors.New("GetTransactionReceipt hash length wrong")
// 定义一个接口的变量,值为交易哈希
args = []interfacehash
// 调用以太坊rpc,查询交易哈希
params := NewHttpParams("eth_getTransactionReceipt", args)
resBody, err := eth.rpc.HttpRequest(params)
if err != nil
return nil, err
// 解析交易信息结果
res, err := eth.ParseJsonRPCResponse(resBody)
if err != nil
logger.Error("GetMatchBuyTxHashInfo", "step", "GetTransactionReceipt", "hash", hash, "err", err.Error())
return nil, err
// 创建交易回执信息对象
txReceipt := new(taskcommon.TxReceipt)
resB, err := json.Marshal(res)
if err != nil
logger.Error("GetMatchBuyTxHashInfo", "step", "Marshal res", "err", err.Error())
return nil, err
if err := json.Unmarshal(resB, &txReceipt); err != nil
logger.Error("GetMatchBuyTxHashInfo", "step", "Unmarshal block", "err", err.Error())
return nil, err
args = []interface
blockParams := NewHttpParams("eth_blockNumber", args)
blockResBody, err := eth.rpc.HttpRequest(blockParams)
if err != nil
return "0x0", err
blockRes, err := eth.ParseJsonRPCResponse(blockResBody)
if err != nil
return "0x0", err
latestnumber, _ := blockRes.(int)
affirmNumber, _ := strconv.Atoi(txReceipt.BlockNumber)
return latestnumber - affirmNumber + 1, nil
调用上面实现的getTxConfirms()方法,就可以获取指定交易当前的确认数了:
txConfirms := getTxConfirms(0xb903239f8543d04b5dc1ba6579132b143087c68db1b2168786408fcbce568238)
注:以上将两个接口:eth_getTransactionReceipt 和 eth_blockNumber写在了同一方法内,代码不够简洁,可分别调用两个方法,获取值后再进行确认区块的运算
以上是关于从零开发区块链应用(十四)--以太坊交易哈希查询的主要内容,如果未能解决你的问题,请参考以下文章