Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* Copyright 2019 Web3 Labs Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*/
package com.alphawallet.token.web.Ethereum.web3j;
import static org.web3j.crypto.Hash.sha3;
import static org.web3j.crypto.Hash.sha3String;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import org.web3j.abi.TypeEncoder;
import org.web3j.abi.datatypes.AbiTypes;
import org.web3j.abi.datatypes.Type;
import org.web3j.crypto.Pair;
import org.web3j.utils.Numeric;
/**
* This class is here due to a bug in Web3j which prevented EIP712 working for some structures
* The fix has been submitted to Web3j repo, when fixed this code can be removed. See also class StructuredData
*/
public class StructuredDataEncoder {
public final StructuredData.EIP712Message jsonMessageObject;
// Matches array declarations like arr[5][10], arr[][], arr[][34][], etc.
// Doesn't match array declarations where there is a 0 in any dimension.
// Eg- arr[0][5] is not matched.
final String arrayTypeRegex = "^([a-zA-Z_$][a-zA-Z_$0-9]*)((\\[([1-9]\\d*)?\\])+)$";
final Pattern arrayTypePattern = Pattern.compile(arrayTypeRegex);
final String bytesTypeRegex = "^bytes[0-9][0-9]?$";
final Pattern bytesTypePattern = Pattern.compile(bytesTypeRegex);
// This regex tries to extract the dimensions from the
// square brackets of an array declaration using the ``Regex Groups``.
// Eg- It extracts ``5, 6, 7`` from ``[5][6][7]``
final String arrayDimensionRegex = "\\[([1-9]\\d*)?\\]";
final Pattern arrayDimensionPattern = Pattern.compile(arrayDimensionRegex);
// Fields of Entry Objects need to follow a regex pattern
// Type Regex matches to a valid name or an array declaration.
final String typeRegex = "^[a-zA-Z_$][a-zA-Z_$0-9]*(\\[([1-9]\\d*)*\\])*$";
final Pattern typePattern = Pattern.compile(typeRegex);
// Identifier Regex matches to a valid name, but can't be an array declaration.
final String identifierRegex = "^[a-zA-Z_$][a-zA-Z_$0-9]*$";
final Pattern identifierPattern = Pattern.compile(identifierRegex);
public StructuredDataEncoder(String jsonMessageInString) throws IOException, RuntimeException {
// Parse String Message into object and validate
this.jsonMessageObject = parseJSONMessage(jsonMessageInString);
}
public Set getDependencies(String primaryType) {
// Find all the dependencies of a type
HashMap> types = jsonMessageObject.getTypes();
Set deps = new HashSet<>();
if (!types.containsKey(primaryType)) {
return deps;
}
List remainingTypes = new ArrayList<>();
remainingTypes.add(primaryType);
while (remainingTypes.size() > 0) {
String structName = remainingTypes.get(remainingTypes.size() - 1);
remainingTypes.remove(remainingTypes.size() - 1);
deps.add(structName);
for (StructuredData.Entry entry : types.get(primaryType)) {
if (!types.containsKey(entry.getType())) {
// Don't expand on non-user defined types
} else if (deps.contains(entry.getType())) {
// Skip types which are already expanded
} else {
// Encountered a user defined type
remainingTypes.add(entry.getType());
}
}
}
return deps;
}
public String encodeStruct(String structName) {
HashMap> types = jsonMessageObject.getTypes();
StringBuilder structRepresentation = new StringBuilder(structName + "(");
for (StructuredData.Entry entry : types.get(structName)) {
structRepresentation.append(String.format("%s %s,", entry.getType(), entry.getName()));
}
structRepresentation =
new StringBuilder(
structRepresentation.substring(0, structRepresentation.length() - 1));
structRepresentation.append(")");
return structRepresentation.toString();
}
public String encodeType(String primaryType) {
Set deps = getDependencies(primaryType);
deps.remove(primaryType);
// Sort the other dependencies based on Alphabetical Order and finally add the primaryType
List depsAsList = new ArrayList<>(deps);
Collections.sort(depsAsList);
depsAsList.add(0, primaryType);
StringBuilder result = new StringBuilder();
for (String structName : depsAsList) {
result.append(encodeStruct(structName));
}
return result.toString();
}
public byte[] typeHash(String primaryType) {
return Numeric.hexStringToByteArray(sha3String(encodeType(primaryType)));
}
public List getArrayDimensionsFromDeclaration(String declaration) {
// Get the dimensions which were declared in Schema.
// If any dimension is empty, then it's value is set to -1.
Matcher arrayTypeMatcher = arrayTypePattern.matcher(declaration);
arrayTypeMatcher.find();
Matcher dimensionTypeMatcher = arrayDimensionPattern.matcher(declaration);
List dimensions = new ArrayList<>();
while (dimensionTypeMatcher.find()) {
String currentDimension = dimensionTypeMatcher.group(1);
if (currentDimension == null) {
dimensions.add(Integer.parseInt("-1"));
} else {
dimensions.add(Integer.parseInt(currentDimension));
}
}
return dimensions;
}
@SuppressWarnings("unchecked")
public List getDepthsAndDimensions(Object data, int depth) {
if (!(data instanceof List)) {
// Nothing more to recurse, since the data is no more an array
return new ArrayList<>();
}
List list = new ArrayList<>();
List