package com.yoghurt.crypto.transactions.shared.util; import com.yoghurt.crypto.transactions.shared.domain.RawTransactionContainer; import com.yoghurt.crypto.transactions.shared.domain.ScriptEntity; import com.yoghurt.crypto.transactions.shared.domain.ScriptPart; import com.yoghurt.crypto.transactions.shared.domain.ScriptPartType; import com.yoghurt.crypto.transactions.shared.domain.ScriptType; import com.yoghurt.crypto.transactions.shared.domain.TransactionPartType; public final class ScriptEncodeUtil { private ScriptEncodeUtil() {} public static byte[] encodeScript(final ScriptEntity script) { final int scriptSize = (int) script.getScriptSize().getValue(); final byte[] bytes = new byte[scriptSize]; int pointer = 0; for (final ScriptPart part : script.getInstructions()) { final byte[] partBytes = part.getBytes(); if (part.getOperation() == null) { System.arraycopy(partBytes, 0, bytes, pointer, partBytes.length); pointer += partBytes.length; } else { System.arraycopy(new byte[] { ScriptOperationUtil.getOperationOpCode(part) }, 0, bytes, pointer, 1); pointer++; if (ScriptOperationUtil.isDataPushOperation(part.getOperation())) { pointer = encodePushDataOperation(part.getOperation().getOpcode(), bytes, partBytes, pointer); } } } return bytes; } private static int encodePushDataOperation(final int opcode, final byte[] bytes, final byte[] partBytes, int pointer) { switch (opcode) { case 76: bytes[pointer] = (byte) partBytes.length; pointer++; default: System.arraycopy(partBytes, 0, bytes, pointer, partBytes.length); return pointer + partBytes.length; } } public static void encodeScript(final ScriptEntity script, final RawTransactionContainer container, final ScriptType type) { for (final ScriptPart part : script.getInstructions()) { final TransactionPartType partType = ScriptOperationUtil.getScriptPartType(type, ScriptPartType.OP_CODE); if (part.getOperation() == null) { container.add(TransactionPartType.COINBASE_SCRIPT_SIG, part.getBytes()); } else { container.add(partType, new byte[] { ScriptOperationUtil.getOperationOpCode(part) }); if (ScriptOperationUtil.isDataPushOperation(part.getOperation())) { switch(part.getOperation().getOpcode()) { case 76: final TransactionPartType push1PartType = ScriptOperationUtil.getScriptPartType(type, ScriptPartType.PUSH_DATA_EXTRA); container.add(push1PartType, new byte[] { (byte) part.getBytes().length }); final TransactionPartType pushData1PartType = ScriptOperationUtil.getScriptPartType(type, ScriptPartType.PUSH_DATA); container.add(pushData1PartType, part.getBytes()); break; default: final TransactionPartType pushPartType = ScriptOperationUtil.getScriptPartType(type, ScriptPartType.PUSH_DATA); container.add(pushPartType, part.getBytes()); } } } } } }