(String type, Object value, Map<String, List<Map<String, String>>> types)
| 2557 | } |
| 2558 | |
| 2559 | @SuppressWarnings("unchecked") |
| 2560 | private static byte[] encodeValue(String type, Object value, Map<String, List<Map<String, String>>> types) { |
| 2561 | // Custom struct |
| 2562 | if (types.containsKey(type)) { |
| 2563 | return hashStruct(type, (Map<String, Object>) value, types); |
| 2564 | } |
| 2565 | // Array type |
| 2566 | if (type.endsWith("[]")) { |
| 2567 | String baseType = type.substring(0, type.length() - 2); |
| 2568 | List<Object> list = (List<Object>) value; |
| 2569 | List<byte[]> encoded = new ArrayList<>(); |
| 2570 | int total = 0; |
| 2571 | for (Object item : list) { |
| 2572 | byte[] e = encodeValue(baseType, item, types); |
| 2573 | encoded.add(e); |
| 2574 | total += e.length; |
| 2575 | } |
| 2576 | byte[] buf = new byte[total]; |
| 2577 | int pos = 0; |
| 2578 | for (byte[] e : encoded) { |
| 2579 | System.arraycopy(e, 0, buf, pos, e.length); |
| 2580 | pos += e.length; |
| 2581 | } |
| 2582 | return keccak256(buf); |
| 2583 | } |
| 2584 | // string: keccak256 of UTF-8 bytes |
| 2585 | if (type.equals("string")) { |
| 2586 | String s = value == null ? "" : value.toString(); |
| 2587 | return keccak256(s.getBytes(java.nio.charset.StandardCharsets.UTF_8)); |
| 2588 | } |
| 2589 | // dynamic bytes: keccak256 of the bytes |
| 2590 | if (type.equals("bytes")) { |
| 2591 | byte[] bytes = bytesFromValue(value); |
| 2592 | return keccak256(bytes); |
| 2593 | } |
| 2594 | // bytes1..bytes32: right-padded to 32 |
| 2595 | if (type.startsWith("bytes")) { |
| 2596 | byte[] bytes = bytesFromValue(value); |
| 2597 | byte[] padded = new byte[32]; |
| 2598 | System.arraycopy(bytes, 0, padded, 0, Math.min(bytes.length, 32)); |
| 2599 | return padded; |
| 2600 | } |
| 2601 | // address: 20 bytes left-padded to 32 |
| 2602 | if (type.equals("address")) { |
| 2603 | byte[] addr = bytesFromValue(value); |
| 2604 | byte[] padded = new byte[32]; |
| 2605 | int copyLen = Math.min(addr.length, 20); |
| 2606 | System.arraycopy(addr, addr.length - copyLen, padded, 32 - copyLen, copyLen); |
| 2607 | return padded; |
| 2608 | } |
| 2609 | // bool |
| 2610 | if (type.equals("bool")) { |
| 2611 | byte[] padded = new byte[32]; |
| 2612 | if (Boolean.TRUE.equals(value)) padded[31] = 1; |
| 2613 | return padded; |
| 2614 | } |
| 2615 | // uintNN / intNN |
| 2616 | if (type.startsWith("uint") || type.startsWith("int")) { |
no test coverage detected