com.github.DNAProject.core.scripts.ScriptBuilder Maven / Gradle / Ivy
/*
* Copyright (C) 2018 The DNA Authors
* This file is part of The DNA library.
*
* The DNA is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* The DNA is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with The DNA. If not, see .
*
*/
package com.github.DNAProject.core.scripts;
import java.io.*;
import java.math.BigInteger;
import java.nio.*;
import com.github.DNAProject.common.Helper;
import com.github.DNAProject.common.UIntBase;
/**
*/
public class ScriptBuilder implements AutoCloseable {
private ByteArrayOutputStream ms = new ByteArrayOutputStream();
public ScriptBuilder add(ScriptOp op) {
return add(op.getByte());
}
public ScriptBuilder add(byte op) {
ms.write(op);
return this;
}
public ScriptBuilder add(byte[] script) {
ms.write(script, 0, script.length);
return this;
}
@Override
public void close() {
try {
ms.close();
} catch (IOException ex) {
throw new RuntimeException(ex);
}
}
public ScriptBuilder emitPushBool(boolean b) {
if (b == true) {
return add(ScriptOp.OP_PUSH1);
}
return add(ScriptOp.OP_PUSH0);
}
public ScriptBuilder emitPushInteger(BigInteger number) {
if (number.equals(BigInteger.ONE.negate())) {
return add(ScriptOp.OP_PUSHM1);
}
if (number.equals(BigInteger.ZERO)) {
return add(ScriptOp.OP_PUSH0);
}
if (number.compareTo(BigInteger.ZERO) > 0 && number.compareTo(BigInteger.valueOf(16)) <= 0) {
return add((byte) (ScriptOp.OP_PUSH1.getByte() - 1 + number.byteValue()));
}
// if (number.longValue() < 0 || number.longValue() >= Long.MAX_VALUE) {
// throw new IllegalArgumentException();
// }
// ByteBuffer byteBuffer = ByteBuffer.allocate(Long.BYTES).order(ByteOrder.LITTLE_ENDIAN);
// byteBuffer.putLong(number.longValue());
byte[] bytes = Helper.BigIntToNeoBytes(number);
return emitPushByteArray(bytes);
}
public ScriptBuilder pushNum(short num) {
if(num == 0) {
return add(ScriptOp.OP_PUSH0);
}else if(num < 16){
return add(ScriptOp.valueOf(num - 1 + ScriptOp.OP_PUSH1.getByte()));
}
BigInteger bint = BigInteger.valueOf(num);
return emitPushByteArray(Helper.BigIntToNeoBytes(bint));
}
public ScriptBuilder emitPushByteArray(byte[] data) {
if (data == null) {
throw new NullPointerException();
}
if (data.length <= (int) ScriptOp.OP_PUSHBYTES75.getByte()) {
ms.write((byte) data.length);
ms.write(data, 0, data.length);
} else if (data.length < 0x100) {
add(ScriptOp.OP_PUSHDATA1);
ms.write((byte) data.length);
ms.write(data, 0, data.length);
} else if (data.length < 0x10000) {
add(ScriptOp.OP_PUSHDATA2);
ms.write(ByteBuffer.allocate(2).order(ByteOrder.LITTLE_ENDIAN).putShort((short) data.length).array(), 0, 2);
ms.write(data, 0, data.length);
} else if (data.length < 0x100000000L) {
add(ScriptOp.OP_PUSHDATA4);
ms.write(ByteBuffer.allocate(4).order(ByteOrder.LITTLE_ENDIAN).putInt(data.length).array(), 0, 4);
ms.write(data, 0, data.length);
} else {
throw new IllegalArgumentException();
}
return this;
}
public ScriptBuilder emit(ScriptOp op) {
return add(op.getByte());
}
public ScriptBuilder push(UIntBase hash) {
return emitPushByteArray(hash.toArray());
}
public ScriptBuilder pushPack() {
return add(ScriptOp.OP_PACK);
}
public byte[] toArray() {
return ms.toByteArray();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy