ブロックチェーンアプリケーションを最初から開発する(14)--Ethereumトランザクションハッシュクエリ

1.イーサリアムトランザクションをクエリします

上記のイベントがコントラクトで呼び出されると、トランザクションハッシュを介してトランザクション情報を取得します。イーサリアムからトランザクションメッセージを取得するには、次の2つの方法があります。

  • 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 = []interface{}{hash}
	// 调用以太坊rpc,查询交易哈希
	params := NewHttpParams("eth_getTransactionByHash", args)
	resBody, err := eth.rpc.HttpRequest(params)
	if err != nil {
		return nil, err
	}
	// 返回一个解析后的交易信息结果
	return eth.ParseJsonRPCResponse(resBody)
}
  • Ethereum 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 = []interface{}{hash}
	// 调用以太坊rpc,查询交易哈希
	params := NewHttpParams("eth_getTransactionReceipt", args)
	resBody, err := eth.rpc.HttpRequest(params)
	if err != nil {
		return nil, err
	}
	// 返回一个解析后的交易信息结果
	return eth.ParseJsonRPCResponse(resBody)
}
  • Ethereum 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
}

2.イーサリアムトランザクション確認の数

ビットコインと同様に、イーサリアムには最長のチェーンの概念があるため、トランザクション確認の概念もあります。
イーサリアム取引所がブロック内のブロックチェーンに新たに追加された場合、トランザクションの確認番号は1であり、その後ブロックが追加されるたびに、トランザクションの確認番号は1ずつ
増加します。明らかに、イーサリアムトランザクションの確認が多ければ多いほど、トランザクションがブロックチェーンに深く
埋め込まれるほど、改ざんされる可能性は低くなります。では、イーサリアムトランザクション
の確認カウントを取得するにはどうすればよいですか?

2.1 rpcを使用して、Ethereumトランザクション確認の数を取得します

イーサリアムトランザクションの確認カウントを取得するには、2つの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を使用して、Ethereumトランザクション確認の数を取得します

上記の原則に基づいて、イーサリアムトランザクション確認の数を取得するための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)

注:上記の2つのインターフェース:eth_getTransactionReceiptとeth_blockNumberは同じメソッドで記述されており、コードは十分に簡潔ではありません。2つのメソッドを別々に呼び出すことができ、値を取得した後にブロックを確認する操作を実行できます。

おすすめ

転載: blog.csdn.net/cljdsc/article/details/122737219