主页 > imtoken官网下载3.0版本 > 从零开始开发区块链应用(十四)--以太坊交易哈希查询
从零开始开发区块链应用(十四)--以太坊交易哈希查询
杰克的技术杂货店[1]
1.查询以太坊交易
当在合约中调用上述事件时,我们通过它的交易哈希得到交易信息。 从以太坊获取交易消息有两种方式:
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 = []interface{}{hash}
// 调用以太坊rpc,查询交易哈希
params := NewHttpParams("eth_getTransactionByHash", args)
resBody, err := eth.rpc.HttpRequest(params)
if err != nil {
return nil, err
}
// 返回一个解析后的交易信息结果
return eth.ParseJsonRPCResponse(resBody)
}
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 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 = []interface{}{hash}
// 调用以太坊rpc,查询交易哈希
params := NewHttpParams("eth_getTransactionReceipt", args)
resBody, err := eth.rpc.HttpRequest(params)
if err != nil {
return nil, err
}
// 返回一个解析后的交易信息结果
return eth.ParseJsonRPCResponse(resBody)
}
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 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
}
2. 以太坊交易确认数
和比特币一样,以太坊有最长链的概念,所以也有交易确认数的概念。 当以太坊交易所在一个区块中新加入区块链时,交易的确认数为1,此后每增加一个区块,交易的确认数增加1。 显然,以太坊交易的确认次数越多以太坊交易信息获取,交易在区块链中的埋藏就越深,被篡改的可能性就越小。 那么,如何获取以太坊交易的确认号呢?
2.1 使用rpc获取以太坊交易确认号
为了获得以太坊交易的确认数量,使用了两个 RPC 调用:
首先使用 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 = []interface{}{hash}
// 调用以太坊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写在同一个方法中,代码不够简洁,可以分别调用这两个方法,获取值后再执行确认区块的操作
本系列文章:
从零开始开发区块链应用(一)--golang配置文件管理工具viper[2]
从零开始开发区块链应用(二)--mysql的安装与数据库表的安装与创建[3]
从零开始开发区块链应用(三)--mysql初始化及gorm框架使用[4]
从零开始开发区块链应用(四)--自定义业务错误信息[5]
从零开始开发区块链应用(五)--golang网络请求[6]
从零开始开发区块链应用(6)--gin框架使用[7]
从零开始开发区块链应用(七)--gin框架参数获取[8]
从零开始开发区块链应用(8)——结构初探[9]
从零开始开发区块链应用(9)--区块链结构的创建[10]
从零开始开发区块链应用(10)--golang协程使用[11]
从零开始开发区块链应用(十一)--以太坊地址生成[12]
从零开始开发区块链应用(12)--以太坊余额查询[13]
从零开始开发区块链应用(十三)--以太坊区块查询[14]
从零开始开发区块链应用(14)--以太坊交易哈希查询[15]
参考
[1]
杰克的科技商店:
[2]
从零开始开发区块链应用(一)--golang配置文件管理工具viper:
[3]
从零开始开发区块链应用(二)--mysql的安装与数据库表的安装与创建:
[4]
从零开始开发区块链应用(三)--mysql初始化及gorm框架的使用:
[5]
从零开始开发区块链应用(四)--自定义业务错误信息:
[6]
从零开始开发区块链应用(五)--golang网络请求:
[7]
从零开始开发区块链应用(六)--gin框架使用:
[8]
从零开发区块链应用获取(七)--gin框架参数:
[9]
从零开始开发区块链应用(八)--结构介绍:
[10]
从零开始开发区块链应用(九)--区块链结构的创建:
[11]
从零开始开发区块链应用(十)--golang协程使用:
[12]
从零开始开发区块链应用(十一)--以太坊地址生成:
[13]
从零开始开发区块链应用(十二)--以太坊余额查询:
[14]
从零开始开发区块链应用(十三)--以太坊区块查询:
[15]
从零开始开发区块链应用(十四)--以太坊交易哈希查询: