创客贴设计网站官网,平湖网站建设,大型营销型网站建设,平面设计兼职Web3j 继承StaticStruct的类所有属性必须为Public#xff0c;属性的顺序和数量必须和solidity 里面的struct 属性相同#xff0c;否则属性少了或者多了的时候会出现错位 Web3j 继承StaticStruct的类所有属性不能为private#xff0c;因为web3j 是通过长度去截取返回值解析成… Web3j 继承StaticStruct的类所有属性必须为Public属性的顺序和数量必须和solidity 里面的struct 属性相同否则属性少了或者多了的时候会出现错位 Web3j 继承StaticStruct的类所有属性不能为private因为web3j 是通过长度去截取返回值解析成对应的属性进行赋值的。要获取一个list对象时web3j是按一个类的所有public属性个数去截取总长度的再进行解析赋值到没一个属性里
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 ListChildStaticStruct getStaticStructList(String address) throws IOException {ListType inputParameters Arrays.asList( new Address(address));ListTypeReference? outputParameters Arrays.asList(new TypeReferenceDynamicArrayChildStaticStruct(){});Function function new Function(getStaticStructList,inputParameters,outputParameters);Transaction transaction Transaction.createEthCallTransaction(null,address, FunctionEncoder.encode(function));EthCall response web3j.ethCall(transaction, DefaultBlockParameterName.LATEST).send();ListType output FunctionReturnDecoder.decode(response.getValue(),function.getOutputParameters());ListChildStaticStruct results (ListChildStaticStruct)output.get(0).getValue();return results;}
}
web3j的TypeDecoder 里的decodeArrayElements 验证了是否为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 验证了截取长度是根据public属性数量去截取Utils.staticStructNestedPublicFieldsFlatList(type).size()pirvate计算长度
static T extends Type int getSingleElementLength(String input, int offset, ClassT 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
public static ListField staticStructNestedPublicFieldsFlatList(ClassType classType) {return (List)staticStructsNestedFieldsFlatList(classType).stream().filter((field) - {return Modifier.isPublic(field.getModifiers());}).collect(Collectors.toList());}
Modifier 里面比较了Public
public static boolean isPublic(int mod) {return (mod PUBLIC) ! 0;}