public String solFunction(String str) {
byte[] byteValue = DatatypeConverter.parseHexBinary(str);
Bytes32 strInBytes = new Bytes32(byteValue);
try {
Uint256 value = contract.showPoint(strInBytes).get();
return value.getValue().toString();
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
return null;
}
// web3j generated java code for solidity program
public Future<Uint256> showPoint(Bytes32 byteValue) {
Function function = new Function("showPoint",
Arrays.<Type>asList(rewardType),
Arrays.<TypeReference<?>>asList(new TypeReference<Uint256>() {}));
return executeCallSingleValueReturnAsync(function);
}
Ich versuche, ein Argument vom Typ Bytes32 mit web3j an die SmartContract-Funktion zu senden. Es wirft immer eine Ausnahme
Input byte array must be in range 0 < M <= 32 and length must match type
Ich habe bereits den numerischen Datentypkonverter von web3j und diese Lösungen überprüft. Problem in git web3j gemeldet
Das ist mein Soliditätsprogramm
contract MyContract {
address public owner; // Store owner address
mapping (address => mapping (bytes32 => uint)) value;
function MyContract (uint initValue, bytes32 chkByte) {
owner = msg.sender;
reward[msg.sender][chkByte] = initValue;
}
function showAvailReward(bytes32 chkByte) constant returns(uint) {
return value[msg.sender][chkByte];
}
}
GELÖST!!! LANGE/DETAILLIERTE METHODE!!! ( kürzere Version unten )
Das Hauptproblem war, dass Bytes32(byte[])
nur 32 Längen unterstützt werden byte[]
. Denken Sie auch Numeric.hexStringToByteArray(strValueInHex)
daran, jeden HexString in byte[]
.
Dies ist der Prozess:
String => Hex => 32 length Hex (ie. 64 length HexString) => byte[] => Bytes32
Hinweis: "00"
= 1 Hex-Länge & 2 String-Länge
So habe ich String to Bytes erreicht:
String bis 64 Länge HexString:
// String to 64 length HexString (equivalent to 32 Hex lenght)
public static String asciiToHex(String asciiValue)
{
char[] chars = asciiValue.toCharArray();
StringBuffer hex = new StringBuffer();
for (int i = 0; i < chars.length; i++)
{
hex.append(Integer.toHexString((int) chars[i]));
}
return hex.toString() + "".join("", Collections.nCopies(32 - (hex.length()/2), "00"));
}
HexString der Länge 64 bis Byte[] der Länge 32:
byte[] myStringInByte = Numeric.hexStringToByteArray(asciiToHex("myString"));
32 Längenbyte[] bis Bytes32:
Bytes32 myStringInBytes32 = new Bytes32(myStringInByte);
Jetzt wird myStringInBytes32 von der Vertragsfunktion von web3j akzeptiert. In meinem Fall solFunction(String str)
ist korrigiert:
public String solFunction(String str) {
String strInHex = asciiToHex(str);
Bytes32 strInBytes32 = new Bytes32(Numeric.hexStringToByteArray(strInHex));
try {
Uint256 value = contract.showPoint(strInBytes32).get();
return value.getValue().toString();
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
return null;
}
Wenn Ihre Solidity-Funktion Daten in Bytes32 zurückgibt, erfahren Sie hier, wie Sie einen Wert aus den zurückgegebenen Bytes32-Daten abrufen.
String dataInString = hexToASCII(Numeric.toHexStringNoPrefix(dataInBytes32);
FunktionhexToASCII
public static String hexToASCII(String hexValue)
{
StringBuilder output = new StringBuilder("");
for (int i = 0; i < hexValue.length(); i += 2)
{
String str = hexValue.substring(i, i + 2);
output.append((char) Integer.parseInt(str, 16));
}
return output.toString();
}
String-to-Hex & Hex-to-String Hilfe von hier
KURZE/VEREINFACHTE Methode:
Zeichenfolge zu Bytes32:
public static Bytes32 stringToBytes32(String string) {
byte[] byteValue = string.getBytes();
byte[] byteValueLen32 = new byte[32];
System.arraycopy(byteValue, 0, byteValueLen32, 0, byteValue.length);
return new Bytes32(byteValueLen32);
}
Bytes32 zu String:
StringUtils.newStringUsAscii(varTypeBytes32.getValue());