Web3j 繼承StaticStruct的類所有屬性必須為Public,屬性的順序和數(shù)量必須和solidity 里面的struct 屬性相同,否則屬性少了或者多了的時候會出現(xiàn)錯位
Web3j 繼承StaticStruct的類所有屬性不能為private,因?yàn)閣eb3j 是通過長度去截取返回值解析成對應(yīng)的屬性進(jìn)行賦值的。要獲取一個list對象時,web3j是按一個類的所有public屬性個數(shù)去截取總長度的,再進(jìn)行解析賦值到?jīng)]一個屬性里
StaticStruct類
import lombok.Data;
import org.web3j.abi.datatypes.Address;
import org.web3j.abi.datatypes.StaticStruct;
import org.web3j.abi.datatypes.Type;
import org.web3j.abi.datatypes.generated.Uint256;
@Data
public class ChildStaticStruct extends StaticStruct {
public Uint256 attr1;
public Uint256 attr2;
public Address attr3;
public ChildStaticStruct(Uint256 attr1, Uint256 attr2, Address attr3) {
super(new Type[]{attr1,attr2,attr3});
}
}
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.web3j.abi.FunctionEncoder;
import org.web3j.abi.FunctionReturnDecoder;
import org.web3j.abi.TypeReference;
import org.web3j.abi.datatypes.Address;
import org.web3j.abi.datatypes.DynamicArray;
import org.web3j.abi.datatypes.Function;
import org.web3j.abi.datatypes.Type;
import org.web3j.protocol.Web3j;
import org.web3j.protocol.core.DefaultBlockParameterName;
import org.web3j.protocol.core.methods.request.Transaction;
import org.web3j.protocol.core.methods.response.EthCall;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
public class TestContract {
private static final Logger logger = LoggerFactory.getLogger(TestContract.class);
private String address;
private Web3j web3j;
public TestContract(String address, Web3j web3j) {
this.address = address;
this.web3j = web3j;
}
public List<ChildStaticStruct> getStaticStructList(String address) throws IOException {
List<Type> inputParameters = Arrays.asList( new Address(address));
List<TypeReference<?>> outputParameters = Arrays.asList(new TypeReference<DynamicArray<ChildStaticStruct>>(){});
Function function = new Function("getStaticStructList",inputParameters,outputParameters);
Transaction transaction = Transaction.createEthCallTransaction(null,address, FunctionEncoder.encode(function));
EthCall response = web3j.ethCall(transaction, DefaultBlockParameterName.LATEST).send();
List<Type> output = FunctionReturnDecoder.decode(response.getValue(),function.getOutputParameters());
List<ChildStaticStruct> results = (List<ChildStaticStruct>)output.get(0).getValue();
return results;
}
}
web3j的TypeDecoder 里的decodeArrayElements 驗(yàn)證了是否為StructType子類,
在currOffset += getSingleElementLength(input, currOffset, cls) * 64)判斷了截取的長度
if (StructType.class.isAssignableFrom(cls)) {
elements = new ArrayList(length);
currOffset = 0;
for(currOffset = offset; currOffset < length; currOffset += getSingleElementLength(input, currOffset, cls) * 64) {
if (DynamicStruct.class.isAssignableFrom(cls)) {
value = decodeDynamicStruct(input, offset + DefaultFunctionReturnDecoder.getDataOffset(input, currOffset, typeReference), TypeReference.create(cls));
} else {
value = decodeStaticStruct(input, currOffset, TypeReference.create(cls));
}
elements.add(value);
++currOffset;
}
String typeName = Utils.getSimpleTypeName(cls);
return (Type)consumer.apply(elements, typeName);
}
getSingleElementLength 驗(yàn)證了截取長度是根據(jù)public屬性數(shù)量去截取Utils.staticStructNestedPublicFieldsFlatList(type).size(),pirvate計(jì)算長度
static <T extends Type> int getSingleElementLength(String input, int offset, Class<T> type) {
if (input.length() == offset) {
return 0;
} else if (!DynamicBytes.class.isAssignableFrom(type) && !Utf8String.class.isAssignableFrom(type)) {
return StaticStruct.class.isAssignableFrom(type) ? Utils.staticStructNestedPublicFieldsFlatList(type).size() : 1;
} else {
return decodeUintAsInt(input, offset) / 32 + 2;
}
}
?staticStructNestedPublicFieldsFlatList方面里面通過Modifier.isPublic(field.getModifiers())過濾了public??文章來源:http://www.zghlxwxcb.cn/news/detail-703632.html
public static List<Field> staticStructNestedPublicFieldsFlatList(Class<Type> classType) {
return (List)staticStructsNestedFieldsFlatList(classType).stream().filter((field) -> {
return Modifier.isPublic(field.getModifiers());
}).collect(Collectors.toList());
}
Modifier 里面比較了Public文章來源地址http://www.zghlxwxcb.cn/news/detail-703632.html
public static boolean isPublic(int mod) {
return (mod & PUBLIC) != 0;
}
到了這里,關(guān)于Web3j 繼承StaticStruct的類所有屬性必須為Public <DynamicArray<StaticStruct>>的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!