Ethereumj
在 web3j 中將字元串轉換為 Bytes32?
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); }
我正在嘗試使用 web3j 將 Bytes32 類型的參數發送到 SmartContract 函式。它總是拋出異常
Input byte array must be in range 0 < M <= 32 and length must match type
我已經檢查了 web3j 的數值數據類型轉換器和這個解決方案。 git web3j 中報告的問題
這是我的穩固計劃
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]; } }
解決了!!!長/詳細的方法!!!(底部較短的版本)
主要問題是
Bytes32(byte[])
只支持 32 長度byte[]
。還要記住Numeric.hexStringToByteArray(strValueInHex)
將任何 HexString 轉換為byte[]
.這是過程:
String => Hex => 32 length Hex (ie. 64 length HexString) => byte[] => Bytes32
注意:
"00"
= 1 十六進制長度 & 2 字元串長度這是我如何實現字元串到字節:
字元串到 64 長度的 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")); }
64 長度的 HexString 到 32 長度的字節
$$ $$:
byte[] myStringInByte = Numeric.hexStringToByteArray(asciiToHex("myString"));
32個長度字節
$$ $$到 Bytes32:
Bytes32 myStringInBytes32 = new Bytes32(myStringInByte);
現在 myStringInBytes32 被 web3j 的合約函式接受。在我的情況下更正
solFunction(String str)
的是: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; }
如果您的 solidity 函式以 Bytes32 形式返回數據,那麼這裡是如何從返回的 Bytes32 數據中獲取值。
String dataInString = hexToASCII(Numeric.toHexStringNoPrefix(dataInBytes32);
功能
hexToASCII
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(); }
簡短/簡化方法:
字元串到 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 轉字元串:
StringUtils.newStringUsAscii(varTypeBytes32.getValue());