package com.yoghurt.crypto.transactions.shared.util;
import com.yoghurt.crypto.transactions.shared.domain.Operation;
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 ScriptOperationUtil {
private ScriptOperationUtil() {}
// TODO Get these out of some cache instead of iterating over the enum values
public static Operation getOperation(final int opcode) {
// Test for simple push data ops
if(opcode > 0 && 75 >= opcode) {
return Operation.OP_PUSHDATA;
}
// Iterate over all operations and give back a match
for(final Operation op : Operation.values()) {
if(op.getOpcode() == opcode) {
return op;
}
}
// Can't find it, return invalid op
return Operation.OP_INVALIDOPCODE;
}
public static TransactionPartType getScriptPartType(final ScriptType type, final ScriptPartType partType) {
switch (type) {
case SCRIPT_PUB_KEY:
switch (partType) {
case OP_CODE:
return TransactionPartType.SCRIPT_PUB_KEY_OP_CODE;
case PUSH_DATA:
return TransactionPartType.SCRIPT_PUB_KEY_PUSH_DATA;
case PUSH_DATA_EXTRA:
return TransactionPartType.SCRIPT_PUB_KEY_PUSH_DATA_EXTRA;
}
case SCRIPT_SIG:
switch (partType) {
case OP_CODE:
return TransactionPartType.SCRIPT_SIG_OP_CODE;
case PUSH_DATA:
return TransactionPartType.SCRIPT_SIG_PUSH_DATA;
case PUSH_DATA_EXTRA:
return TransactionPartType.SCRIPT_SIG_PUSH_DATA_EXTRA;
}
}
return null;
}
/**
* Data push operations are 1-75, OP_PUSHDATA1, 2 and 4 (so up to opcode 78), excluding OP0 through 16.
*
* And also null (indicating coinbase input TODO: remind me why again?)
*/
public static boolean isDataPushOperation(final Operation op) {
return op == null || op == Operation.OP_PUSHDATA || isDataPushOperation(op.getOpcode());
}
public static boolean isDataPushOperation(final int opcode) {
return opcode >= 1 && 78 >= opcode;
}
public static byte getOperationOpCode(final ScriptPart part) {
if(part.getOperation() == Operation.OP_PUSHDATA) {
return (byte) (part.getBytes().length & 0xFF);
}
return (byte) (part.getOperation().getOpcode() & 0xFF);
}
}