public static String stringify(byte[] code, int index, String result) { if (code == null || code.length == 0) return result; OpCode op = OpCode.code(code[index]); byte[] continuedCode = null; switch (op) { case PUSH1: case PUSH2: case PUSH3: case PUSH4: case PUSH5: case PUSH6: case PUSH7: case PUSH8: case PUSH9: case PUSH10: case PUSH11: case PUSH12: case PUSH13: case PUSH14: case PUSH15: case PUSH16: case PUSH17: case PUSH18: case PUSH19: case PUSH20: case PUSH21: case PUSH22: case PUSH23: case PUSH24: case PUSH25: case PUSH26: case PUSH27: case PUSH28: case PUSH29: case PUSH30: case PUSH31: case PUSH32: result += ' ' + op.name() + ' '; int nPush = op.val() - OpCode.PUSH1.val() + 1; byte[] data = Arrays.copyOfRange(code, index + 1, index + nPush + 1); result += new BigInteger(data).toString() + ' '; continuedCode = Arrays.copyOfRange(code, index + nPush + 1, code.length); break; default: result += ' ' + op.name(); continuedCode = Arrays.copyOfRange(code, index + 1, code.length); break; } return stringify(continuedCode, 0, result); }
public void fullTrace() { if (logger.isTraceEnabled() || listener != null) { StringBuilder stackData = new StringBuilder(); for (int i = 0; i < stack.size(); ++i) { stackData.append(" ").append(stack.get(i)); if (i < stack.size() - 1) stackData.append("\n"); } if (stackData.length() > 0) stackData.insert(0, "\n"); ContractDetails contractDetails = this.result.getRepository().getContractDetails(this.programAddress.getLast20Bytes()); StringBuilder storageData = new StringBuilder(); List<DataWord> storageKeys = new ArrayList<>(contractDetails.getStorage().keySet()); Collections.sort((List<DataWord>) storageKeys); for (DataWord key : storageKeys) { storageData .append(" ") .append(key) .append(" -> ") .append(contractDetails.getStorage().get(key)) .append("\n"); } if (storageData.length() > 0) storageData.insert(0, "\n"); StringBuilder memoryData = new StringBuilder(); StringBuilder oneLine = new StringBuilder(); for (int i = 0; memory != null && i < memory.limit(); ++i) { byte value = memory.get(i); oneLine.append(Utils.oneByteToHexString(value)).append(" "); if ((i + 1) % 16 == 0) { String tmp = String.format("[%4s]-[%4s]", Integer.toString(i - 15, 16), Integer.toString(i, 16)) .replace(" ", "0"); memoryData.append("").append(tmp).append(" "); memoryData.append(oneLine); if (i < memory.limit()) memoryData.append("\n"); oneLine.setLength(0); } } if (memoryData.length() > 0) memoryData.insert(0, "\n"); StringBuilder opsString = new StringBuilder(); for (int i = 0; i < ops.length; ++i) { String tmpString = Integer.toString(ops[i] & 0xFF, 16); tmpString = tmpString.length() == 1 ? "0" + tmpString : tmpString; if (i != pc) opsString.append(tmpString); else opsString.append(" >>").append(tmpString).append(""); } if (pc >= ops.length) opsString.append(" >>"); if (opsString.length() > 0) opsString.insert(0, "\n "); logger.trace(" -- OPS -- {}", opsString); logger.trace(" -- STACK -- {}", stackData); logger.trace(" -- MEMORY -- {}", memoryData); logger.trace(" -- STORAGE -- {}\n", storageData); logger.trace( "\n Spent Gas: [ {} ]/[ {} ]\n Left Gas: [ {} ]\n", result.getGasUsed(), invokeData.getGas().longValue(), getGas().longValue()); StringBuilder globalOutput = new StringBuilder("\n"); if (stackData.length() > 0) stackData.append("\n"); if (pc != 0) globalOutput.append("[Op: ").append(OpCode.code(lastOp).name()).append("]\n"); globalOutput.append(" -- OPS -- ").append(opsString).append("\n"); globalOutput.append(" -- STACK -- ").append(stackData).append("\n"); globalOutput.append(" -- MEMORY -- ").append(memoryData).append("\n"); globalOutput.append(" -- STORAGE -- ").append(storageData).append("\n"); if (result.getHReturn() != null) { globalOutput.append("\n HReturn: ").append(Hex.toHexString(result.getHReturn().array())); } // soffisticated assumption that msg.data != codedata // means we are calling the contract not creating it byte[] txData = invokeData.getDataCopy(DataWord.ZERO, getDataSize()); if (!Arrays.equals(txData, ops)) { globalOutput.append("\n msg.data: ").append(Hex.toHexString(txData)); } globalOutput.append("\n\n Spent Gas: ").append(result.getGasUsed()); if (listener != null) { listener.output(globalOutput.toString()); } } }