-
Notifications
You must be signed in to change notification settings - Fork 59
abi
maggie edited this page Sep 27, 2020
·
3 revisions
-
功能
-
重构目标
-
模块关联
-
类图
-
接口
-
示例
提供Solidity ABI
编解码工具集
- ABI编解码
Contract ABI Specification - 工具类
- 函数
methodId
计算 - 事件
topic
计算
- 函数
-
完善类型支持
- 支持完整
ABI
类型,完善对ABIEncodeV2 struct
类型的支持
- 支持完整
-
提供友好/完整的ABI工具类
- 易用性
- 支持完整类型的
ABI
编解码 -
JavaSDK
其他模块易于集成
- 支持完整类型的
- 特定需求
- 支持字符串参数
- 支持函数
signature
入参描述ABI
- 其他
- 国密/非国密
hash
接口依赖整理
- 国密/非国密
- 易用性
参考 JavaSDK 重构整体架构
支持两种参数形式:
- Java对象参数
- 字符串参数
我们将ABI Codec和ABICodecJsonWrapper合并成一个类
public class ABICodec {
// Encode method
String encodeMethod(String ABI, String methodName, List<Object> params) throws ABICodecException;
String encodeMethodById(String ABI, String methodId, List<Object> params) throws ABICodecException;
String encodeMethodByInterface(String methodInterface, List<Object> params) throws ABICodecException;
String encodeMethodFromString (String ABI, String methodName, List<String> params) throws ABICodecException;
String encodeMethodByIdFromString(String ABI, String methodId, List<String> params) throws ABICodecException;
String encodeMethodByInterfaceFromString(String methodInterface, List<String> params) throws ABICodecException;
// Encode event
String encodeEvent(String ABI, String eventName, List<Object> params) throws ABICodecException;
String encodeEventByTopic(String ABI, String eventTopic, List<Object> params) throws ABICodecException;
String encodeEventByInterface(String eventSignature, List<Object> params) throws ABICodecException;
String encodeEventFromString(String ABI, String eventName, List<String> params) throws ABICodecException;
String encodeEventByTopicFromString(String ABI, String eventTopic, List<String> params) throws ABICodecException;
String encodeEventByInterfaceFromString(String eventSignature, List<String> params) throws ABICodecException;
// Decode method
List<Object> decodeMethod(String ABI, String methodName, String output) throws ABICodecException;
List<Object> decodeMethodById(String ABI, String methodId, String output) throws ABICodecException;
List<Object> decodeMethodByInterface(String methodSignature, String output) throws ABICodecException;
List<String> decodeMethodToString(String ABI, String methodName, String output) throws ABICodecException;
List<String> decodeMethodByIdToString(String ABI, String methodId, String output) throws ABICodecException;
List<String> decodeMethodByInterfaceToString(String methodSignature, String output) throws ABICodecException;
// Decode event
List<Object> decodeEvent(String ABI, String eventName, String output) throws ABICodecException;
List<Object> decodeEventByTopic(String ABI, String eventTopic, String output) throws ABICodecException;
List<Object> decodeEventByInterface(String eventSignature, String output) throws ABICodecException;
List<String> decodeEventToString(String ABI, String eventName, String output) throws ABICodecException;
List<String> decodeEventByTopicToString(String ABI, String eventTopic, String output) throws ABICodecException;
List<String> decodeEventByInterfaceToString(String eventSignature, String output) throws ABICodecException;
}
Java Object与solidity类型映射关系:
uint => BigInteger
int => BigInteger
bool => boolean
address => Address
string => String
bytes => byte[]
bytesN => byte[]
tuple => List
T[] => List
T[N] => List
ABI编解码模块可以接受字符串类型的入参数,内部进行类型初始化,对于复杂类型T[]
T[N]
tuple
可以使用JSON
字符串表示。
示例合约
pragma solidity>=0.5.0 <0.6.11;
pragma experimental ABIEncoderV2;
contract TupleTest {
event SetEvent(int i, Item item, string s);
struct Item {
int a;
int b;
int c;
}
int i;
Item item;
string s;
function set(int _i, Item memory _item, string memory _s) public {
i = _i;
item = _item;
s = _s;
}
function get() view public returns(int, Item memory, string memory) {
return (i, item, s);
}
}
ABI:
[{"constant":false,"inputs":[{"name":"_i","type":"int256"},{"components":[{"name":"a","type":"int256"},{"name":"b","type":"int256"},{"name":"c","type":"int256"}],"name":"_item","type":"tuple"},{"name":"_s","type":"string"}],"name":"set","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"get","outputs":[{"name":"","type":"int256"},{"components":[{"name":"a","type":"int256"},{"name":"b","type":"int256"},{"name":"c","type":"int256"}],"name":"","type":"tuple"},{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"anonymous":false,"inputs":[{"indexed":false,"name":"i","type":"int256"},{"components":[{"name":"a","type":"int256"},{"name":"b","type":"int256"},{"name":"c","type":"int256"}],"indexed":false,"name":"item","type":"tuple"},{"indexed":false,"name":"s","type":"string"}],"name":"SetEvent","type":"event"}]
- 接口: set
- 参数:
- int i: 1
- Item item: tuple(2, 3, 4)
- string s: "Hello World"
- 方式一: 合约ABI + 接口名
String abi = "[{"constant":false,"inputs":[{"name":"_i","type":"int256"},{"components":[{"name":"a","type":"int256"},{"name":"b","type":"int256"},{"name":"c","type":"int256"}],"name":"_item","type":"tuple"},{"name":"_s","type":"string"}],"name":"set","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"get","outputs":[{"name":"","type":"int256"},{"components":[{"name":"a","type":"int256"},{"name":"b","type":"int256"},{"name":"c","type":"int256"}],"name":"","type":"tuple"},{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"anonymous":false,"inputs":[{"indexed":false,"name":"i","type":"int256"},{"components":[{"name":"a","type":"int256"},{"name":"b","type":"int256"},{"name":"c","type":"int256"}],"indexed":false,"name":"item","type":"tuple"},{"indexed":false,"name":"s","type":"string"}],"name":"SetEvent","type":"event"}]";
ABICodec abiCodec = new ABICodec();
String abiEncoded = abiCodec.encodeMethod(abi, "set", new Object[]{1, new ArrayList<> {2,3,4}, new String("Hello World")});
- 方式二: 接口signature
ABICodec abiCodec = new ABICodec();
String setMethodSignature = "set(int,tuple(int,int,int),string)";
String abiEncoded = abiCodec.encodeMethodByMethodSignature(setMethodSignature, new Object[]{1, new ArrayList<> {2,3,4}, new String("Hello World")});
- 方式一: 合约ABI + 接口名 + 字符串入参
ABICodecJsonWrapper abiCodecJsonWrapper = new ABICodecJsonWrapper();
String abi = "";
String abiEncoded = abiCodecJsonWrapper.encodeMethod(abi, "set", new String[]{"1", "\"[1,2,3]\"", "Hello World"});
- 方式一: 接口signature + 字符串入参
ABICodecJsonWrapper abiCodecJsonWrapper = new ABICodecJsonWrapper();
String setMethodSignature = "set(int,tuple(int,int,int),string)";
String abiEncoded = abiCodec.encodeMethodByMethodSignature(setMethodSignature, new String[]{"1", "\"[1,2,3]\"", "Hello World"});