交易解析

FISCO BCOS的交易是一段发往区块链系统的请求数据,用于部署合约,调用合约接口,维护合约的生命周期以及管理资产,进行价值交换等。当交易确认后会产生交易回执,交易回执交易均保存在区块里,用于记录交易执行过程生成的信息,如结果码、日志、消耗的gas量等。用户可以使用交易哈希查询交易回执,判定交易是否完成。

交易回执包含三个关键字段,分别是input, output , logs:

字段类型描述
inputString交易输入的ABI编码十六进制字符串
outputString交易返回的ABI编码十六进制字符串
logsListevent log列表,保存交易的event信息

交易解析功能帮助用户解析这三个字段为json数据和java对象。

接口说明

代码包路径org.fisco.bcos.web3j.tx.txdecode,使用TransactionDecoderFactory工厂类建立交易解析对象TransactionDecoder,有两种方式:

  1. TransactionDecoder buildTransactionDecoder(String abi, String bin);

    abi:合约的ABI

    bin:合约bin,暂无使用,可以直接传入空字符串””

  2. TransactionDecoder buildTransactionDecoder(String contractName);

    contractName:合约名称,在应用的根目录下创建solidity目录,将交易相关的合约放在solidity目录,通过指定合约名获取交易解析对象

交易解析对象TransactionDecoder接口列表:

  1. String decodeInputReturnJson(String input)

    解析input,将结果封装为json字符串,json格式

    1. {"data":[{"name":"","type":"","data":} ... ],"function":"","methodID":""}

    function : 函数签名字符串

    methodID : 函数选择器

  2. InputAndOutputResult decodeInputReturnObject(String input)

    解析input,返回Object对象,InputAndOutputResult结构:

    1. public class InputAndOutputResult {
    2. private String function; // 函数签名
    3. private String methodID; // methodID
    4. private List<ResultEntity> result; // 返回列表
    5. }
    6. public class ResultEntity {
    7. private String name; // 字段名称, 解析output返回时,值为空字符串
    8. private String type; // 字段类型
    9. private Object data; // 字段值
    10. }
  3. String decodeOutputReturnJson(String input, String output)

    解析output,将结果封装为json字符串,格式同decodeInputReturnJson

  4. InputAndOutputResult decodeOutputReturnObject(String input, String output)

    解析output,返回java Object对象

  5. String decodeEventReturnJson(List<Log> logList)

    解析event列表,将结果封装为json字符串,json格式

    1. {"event1签名":[[{"name":"","type":"","data":}...]...],"event2签名":[[{"name":"","type":"","data":}...]...]...}
  6. Map<String, List<List<ResultEntity>>> decodeEventReturnObject(List<Log> logList)

    解析event列表,返回java Map对象,key为event签名字符串,List<ResultEntity>为交易中单个event参数列表,List<List<ResultEntity>>表示单个交易可以包含多个event

TransactionDecoder对input,output和event logs均分别提供返回json字符串和java对象的方法。json字符串方便客户端处理数据,java对象方便服务端处理数据。

示例

TxDecodeSample合约为例说明接口的使用:

  1. pragma solidity ^0.4.24;
  2. contract TxDecodeSample
  3. {
  4. event Event1(uint256 _u,int256 _i,bool _b,address _addr,bytes32 _bs32, string _s,bytes _bs);
  5. event Event2(uint256 _u,int256 _i,bool _b,address _addr,bytes32 _bs32, string _s,bytes _bs);
  6. function echo(uint256 _u,int256 _i,bool _b,address _addr,bytes32 _bs32, string _s,bytes _bs) public constant returns (uint256,int256,bool,address,bytes32,string,bytes)
  7. {
  8. Event1(_u, _i, _b, _addr, _bs32, _s, _bs);
  9. return (_u, _i, _b, _addr, _bs32, _s, _bs);
  10. }
  11. function do_event(uint256 _u,int256 _i,bool _b,address _addr,bytes32 _bs32, string _s,bytes _bs) public
  12. {
  13. Event1(_u, _i, _b, _addr, _bs32, _s, _bs);
  14. Event2(_u, _i, _b, _addr, _bs32, _s, _bs);
  15. }
  16. }

使用buildTransactionDecoder 创建TxDecodeSample合约的解析对象:

  1. // TxDecodeSample合约ABI
  2. String abi = "[{\"constant\":false,\"inputs\":[{\"name\":\"_u\",\"type\":\"uint256\"},{\"name\":\"_i\",\"type\":\"int256\"},{\"name\":\"_b\",\"type\":\"bool\"},{\"name\":\"_addr\",\"type\":\"address\"},{\"name\":\"_bs32\",\"type\":\"bytes32\"},{\"name\":\"_s\",\"type\":\"string\"},{\"name\":\"_bs\",\"type\":\"bytes\"}],\"name\":\"do_event\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"_u\",\"type\":\"uint256\"},{\"indexed\":false,\"name\":\"_i\",\"type\":\"int256\"},{\"indexed\":false,\"name\":\"_b\",\"type\":\"bool\"},{\"indexed\":false,\"name\":\"_addr\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"_bs32\",\"type\":\"bytes32\"},{\"indexed\":false,\"name\":\"_s\",\"type\":\"string\"},{\"indexed\":false,\"name\":\"_bs\",\"type\":\"bytes\"}],\"name\":\"Event1\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"_u\",\"type\":\"uint256\"},{\"indexed\":false,\"name\":\"_i\",\"type\":\"int256\"},{\"indexed\":false,\"name\":\"_b\",\"type\":\"bool\"},{\"indexed\":false,\"name\":\"_addr\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"_bs32\",\"type\":\"bytes32\"},{\"indexed\":false,\"name\":\"_s\",\"type\":\"string\"},{\"indexed\":false,\"name\":\"_bs\",\"type\":\"bytes\"}],\"name\":\"Event2\",\"type\":\"event\"},{\"constant\":true,\"inputs\":[{\"name\":\"_u\",\"type\":\"uint256\"},{\"name\":\"_i\",\"type\":\"int256\"},{\"name\":\"_b\",\"type\":\"bool\"},{\"name\":\"_addr\",\"type\":\"address\"},{\"name\":\"_bs32\",\"type\":\"bytes32\"},{\"name\":\"_s\",\"type\":\"string\"},{\"name\":\"_bs\",\"type\":\"bytes\"}],\"name\":\"echo\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"},{\"name\":\"\",\"type\":\"int256\"},{\"name\":\"\",\"type\":\"bool\"},{\"name\":\"\",\"type\":\"address\"},{\"name\":\"\",\"type\":\"bytes32\"},{\"name\":\"\",\"type\":\"string\"},{\"name\":\"\",\"type\":\"bytes\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"}]";
  3. String bin = "";
  4. TransactionDecoder txDecodeSampleDecoder = TransactionDecoderFactory.buildTransactionDecoder(abi, bin);

解析input

调用function echo(uint256 _u,int256 _i,bool _b,address _addr,bytes32 _bs32, string _s,bytes _bs) 接口,输入参数为[ 111111 -1111111 false 0x692a70d2e424a56d2c6c27aa97d1a86395877b3a abcdefghiabcdefghiabcdefghiabhji FISCO-BCOS nice ]

  1. // function echo(uint256 _u,int256 _i,bool _b,address _addr,bytes32 _bs32, string _s,bytes _bs)
  2. String input = "0x406d373b000000000000000000000000000000000000000000000000000000000001b207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffef0bb90000000000000000000000000000000000000000000000000000000000000000000000000000000000000000692a70d2e424a56d2c6c27aa97d1a86395877b3a6162636465666768696162636465666768696162636465666768696162686a6900000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000021e7aba0e9b1bce5b08fe4b8b8e5ad906c6a6a6b6c3b61646a73666b6c6a6c6b6a6c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d736164666c6a6b6a6b6c6a6b6c00000000000000000000000000000000000000";
  3. String jsonResult = txDecodeSampleDecoder.decodeInputReturnJson(input);
  4. InputAndOutputResult objectResult = txDecodeSampleDecoder.decodeInputReturnObject(input);
  5. System.out.println("json => \n" + jsonResult);
  6. System.out.println("object => \n" + objectResult);

输出:

  1. json =>
  2. {
  3. "function": "echo(uint256,int256,bool,address,bytes32,string,bytes)",
  4. "methodID": "0x406d373b",
  5. "result": [
  6. {
  7. "name": "_u",
  8. "type": "uint256",
  9. "data": 111111
  10. },
  11. {
  12. "name": "_i",
  13. "type": "int256",
  14. "data": -1111111
  15. },
  16. {
  17. "name": "_b",
  18. "type": "bool",
  19. "data": false
  20. },
  21. {
  22. "name": "_addr",
  23. "type": "address",
  24. "data": "0x692a70d2e424a56d2c6c27aa97d1a86395877b3a"
  25. },
  26. {
  27. "name": "_bs32",
  28. "type": "bytes32",
  29. "data": "abcdefghiabcdefghiabcdefghiabhji"
  30. },
  31. {
  32. "name": "_s",
  33. "type": "string",
  34. "data": "FISCO-BCOS"
  35. },
  36. {
  37. "name": "_bs",
  38. "type": "bytes",
  39. "data": "nice"
  40. }
  41. ]
  42. }
  43. object =>
  44. InputAndOutputResult[
  45. function=echo(uint256,
  46. int256,
  47. bool,
  48. address,
  49. bytes32,
  50. string,
  51. bytes),
  52. methodID=0x406d373b,
  53. result=[
  54. ResultEntity[
  55. name=_u,
  56. type=uint256,
  57. data=111111
  58. ],
  59. ResultEntity[
  60. name=_i,
  61. type=int256,
  62. data=-1111111
  63. ],
  64. ResultEntity[
  65. name=_b,
  66. type=bool,
  67. data=false
  68. ],
  69. ResultEntity[
  70. name=_addr,
  71. type=address,
  72. data=0x692a70d2e424a56d2c6c27aa97d1a86395877b3a
  73. ],
  74. ResultEntity[
  75. name=_bs32,
  76. type=bytes32,
  77. data=abcdefghiabcdefghiabcdefghiabhji
  78. ],
  79. ResultEntity[
  80. name=_s,
  81. type=string,
  82. data=FISCO-BCOS
  83. ],
  84. ResultEntity[
  85. name=_bs,
  86. type=bytes,
  87. data=nice
  88. ]
  89. ]
  90. ]

解析output

调用function echo(uint256 _u,int256 _i,bool _b,address _addr,bytes32 _bs32, string _s,bytes _bs) 接口,输入参数为[ 111111 -1111111 false 0x692a70d2e424a56d2c6c27aa97d1a86395877b3a abcdefghiabcdefghiabcdefghiabhji FISCO-BCOS nice ],echo接口直接将输入返回,因此返回与输入相同

  1. // function echo(uint256 _u,int256 _i,bool _b,address _addr,bytes32 _bs32, string _s,bytes _bs) public constant returns (uint256,int256,bool,address,bytes32,string,bytes)
  2. String input = 0x406d373b000000000000000000000000000000000000000000000000000000000001b207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffef0bb90000000000000000000000000000000000000000000000000000000000000000000000000000000000000000692a70d2e424a56d2c6c27aa97d1a86395877b3a6162636465666768696162636465666768696162636465666768696162686a6900000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000021e7aba0e9b1bce5b08fe4b8b8e5ad906c6a6a6b6c3b61646a73666b6c6a6c6b6a6c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d736164666c6a6b6a6b6c6a6b6c00000000000000000000000000000000000000”;
  3. String output = "“0x000000000000000000000000000000000000000000000000000000000001b207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffef0bb90000000000000000000000000000000000000000000000000000000000000000000000000000000000000000692a70d2e424a56d2c6c27aa97d1a86395877b3a6162636465666768696162636465666768696162636465666768696162686a6900000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000021e7aba0e9b1bce5b08fe4b8b8e5ad906c6a6a6b6c3b61646a73666b6c6a6c6b6a6c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d736164666c6a6b6a6b6c6a6b6c00000000000000000000000000000000000000";
  4. String jsonResult = txDecodeSampleDecoder.decodeOutputReturnJson(input, output);
  5. InputAndOutputResult objectResult = txDecodeSampleDecoder.decodeOutputReturnObject(input, output);
  6. System.out.println("json => \n" + jsonResult);
  7. System.out.println("object => \n" + objectResult);

结果:

  1. json =>
  2. {
  3. "function": "echo(uint256,int256,bool,address,bytes32,string,bytes)",
  4. "methodID": "0x406d373b",
  5. "result": [
  6. {
  7. "name": "",
  8. "type": "uint256",
  9. "data": 111111
  10. },
  11. {
  12. "name": "",
  13. "type": "int256",
  14. "data": -1111111
  15. },
  16. {
  17. "name": "",
  18. "type": "bool",
  19. "data": false
  20. },
  21. {
  22. "name": "",
  23. "type": "address",
  24. "data": "0x692a70d2e424a56d2c6c27aa97d1a86395877b3a"
  25. },
  26. {
  27. "name": "",
  28. "type": "bytes32",
  29. "data": "abcdefghiabcdefghiabcdefghiabhji"
  30. },
  31. {
  32. "name": "",
  33. "type": "string",
  34. "data": "FISCO-BCOS"
  35. },
  36. {
  37. "name": "",
  38. "type": "bytes",
  39. "data": "nice"
  40. }
  41. ]
  42. }
  43. object =>
  44. InputAndOutputResult[
  45. function=echo(uint256,
  46. int256,
  47. bool,
  48. address,
  49. bytes32,
  50. string,
  51. bytes),
  52. methodID=0x406d373b,
  53. result=[
  54. ResultEntity[
  55. name=,
  56. type=uint256,
  57. data=111111
  58. ],
  59. ResultEntity[
  60. name=,
  61. type=int256,
  62. data=-1111111
  63. ],
  64. ResultEntity[
  65. name=,
  66. type=bool,
  67. data=false
  68. ],
  69. ResultEntity[
  70. name=,
  71. type=address,
  72. data=0x692a70d2e424a56d2c6c27aa97d1a86395877b3a
  73. ],
  74. ResultEntity[
  75. name=,
  76. type=bytes32,
  77. data=abcdefghiabcdefghiabcdefghiabhji
  78. ],
  79. ResultEntity[
  80. name=,
  81. type=string,
  82. data=FISCO-BCOS
  83. ],
  84. ResultEntity[
  85. name=,
  86. type=bytes,
  87. data=nice
  88. ]
  89. ]
  90. ]

解析event logs

调用function do_event(uint256 _u,int256 _i,bool _b,address _addr,bytes32 _bs32, string _s,bytes _bs) 接口,输入参数为[ 111111 -1111111 false 0x692a70d2e424a56d2c6c27aa97d1a86395877b3a abcdefghiabcdefghiabcdefghiabhji FISCO-BCOS nice ],解析交易中的logs

  1. // transactionReceipt为调用do_event接口的交易回执
  2. String jsonResult = txDecodeSampleDecoder.decodeEventReturnJson(transactionReceipt.getLogs());
  3. String mapResult = txDecodeSampleDecoder.decodeEventReturnJson(transactionReceipt.getLogs());
  4. System.out.println("json => \n" + jsonResult);
  5. System.out.println("map => \n" + mapResult);

结果:

  1. json =>
  2. {
  3. "Event1(uint256,int256,bool,address,bytes32,string,bytes)": [
  4. [
  5. {
  6. "name": "_u",
  7. "type": "uint256",
  8. "data": 111111,
  9. "indexed": false
  10. },
  11. {
  12. "name": "_i",
  13. "type": "int256",
  14. "data": -1111111,
  15. "indexed": false
  16. },
  17. {
  18. "name": "_b",
  19. "type": "bool",
  20. "data": false,
  21. "indexed": false
  22. },
  23. {
  24. "name": "_addr",
  25. "type": "address",
  26. "data": "0x692a70d2e424a56d2c6c27aa97d1a86395877b3a",
  27. "indexed": false
  28. },
  29. {
  30. "name": "_bs32",
  31. "type": "bytes32",
  32. "data": "abcdefghiabcdefghiabcdefghiabhji",
  33. "indexed": false
  34. },
  35. {
  36. "name": "_s",
  37. "type": "string",
  38. "data": "Fisco Bcos",
  39. "indexed": false
  40. },
  41. {
  42. "name": "_bs",
  43. "type": "bytes",
  44. "data": "sadfljkjkljkl",
  45. "indexed": false
  46. }
  47. ]
  48. ],
  49. "Event2(uint256,int256,bool,address,bytes32,string,bytes)": [
  50. [
  51. {
  52. "name": "_u",
  53. "type": "uint256",
  54. "data": 111111,
  55. "indexed": false
  56. },
  57. {
  58. "name": "_i",
  59. "type": "int256",
  60. "data": -1111111,
  61. "indexed": false
  62. },
  63. {
  64. "name": "_b",
  65. "type": "bool",
  66. "data": false,
  67. "indexed": false
  68. },
  69. {
  70. "name": "_addr",
  71. "type": "address",
  72. "data": "0x692a70d2e424a56d2c6c27aa97d1a86395877b3a",
  73. "indexed": false
  74. },
  75. {
  76. "name": "_bs32",
  77. "type": "bytes32",
  78. "data": "abcdefghiabcdefghiabcdefghiabhji",
  79. "indexed": false
  80. },
  81. {
  82. "name": "_s",
  83. "type": "string",
  84. "data": "FISCO-BCOS",
  85. "indexed": false
  86. },
  87. {
  88. "name": "_bs",
  89. "type": "bytes",
  90. "data": "nice",
  91. "indexed": false
  92. }
  93. ]
  94. ]
  95. }
  96. map =>
  97. {
  98. Event1(uint256,
  99. int256,
  100. bool,
  101. address,
  102. bytes32,
  103. string,
  104. bytes)=[
  105. [
  106. ResultEntity[
  107. name=_u,
  108. type=uint256,
  109. data=111111
  110. ],
  111. ResultEntity[
  112. name=_i,
  113. type=int256,
  114. data=-1111111
  115. ],
  116. ResultEntity[
  117. name=_b,
  118. type=bool,
  119. data=false
  120. ],
  121. ResultEntity[
  122. name=_addr,
  123. type=address,
  124. data=0x692a70d2e424a56d2c6c27aa97d1a86395877b3a
  125. ],
  126. ResultEntity[
  127. name=_bs32,
  128. type=bytes32,
  129. data=abcdefghiabcdefghiabcdefghiabhji
  130. ],
  131. ResultEntity[
  132. name=_s,
  133. type=string,
  134. data=FISCO-BCOS
  135. ],
  136. ResultEntity[
  137. name=_bs,
  138. type=bytes,
  139. data=nice
  140. ]
  141. ]
  142. ],
  143. Event2(uint256,
  144. int256,
  145. bool,
  146. address,
  147. bytes32,
  148. string,
  149. bytes)=[
  150. [
  151. ResultEntity[
  152. name=_u,
  153. type=uint256,
  154. data=111111
  155. ],
  156. ResultEntity[
  157. name=_i,
  158. type=int256,
  159. data=-1111111
  160. ],
  161. ResultEntity[
  162. name=_b,
  163. type=bool,
  164. data=false
  165. ],
  166. ResultEntity[
  167. name=_addr,
  168. type=address,
  169. data=0x692a70d2e424a56d2c6c27aa97d1a86395877b3a
  170. ],
  171. ResultEntity[
  172. name=_bs32,
  173. type=bytes32,
  174. data=abcdefghiabcdefghiabcdefghiabhji
  175. ],
  176. ResultEntity[
  177. name=_s,
  178. type=string,
  179. data=FISCO-BCOS
  180. ],
  181. ResultEntity[
  182. name=_bs,
  183. type=bytes,
  184. data=nices
  185. ]
  186. ]
  187. ]
  188. }