Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
com.github.DNAProject.smartcontract.neovm.abi.BuildParams 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.smartcontract.neovm.abi;
import com.alibaba.fastjson.JSON;
import com.github.DNAProject.common.Address;
import com.github.DNAProject.common.ErrorCode;
import com.github.DNAProject.common.Helper;
import com.github.DNAProject.core.scripts.ScriptBuilder;
import com.github.DNAProject.core.scripts.ScriptOp;
import com.github.DNAProject.io.BinaryReader;
import com.github.DNAProject.io.BinaryWriter;
import com.github.DNAProject.sdk.exception.SDKException;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.math.BigInteger;
import java.util.*;
public class BuildParams {
public enum Type {
ByteArrayType(0x00),
BooleanType(0x01),
IntegerType(0x02),
InterfaceType(0x40),
ArrayType(0x80),
StructType(0x81),
MapType(0x82);
private byte type;
private Type(int t) {
this.type = (byte)t;
}
public byte getValue(){
return type;
}
}
/**
* @param builder
* @param list
* @return
*/
private static byte[] createCodeParamsScript(ScriptBuilder builder, List list) {
try {
for (int i = list.size() - 1; i >= 0; i--) {
Object val = list.get(i);
if (val instanceof byte[]) {
builder.emitPushByteArray((byte[]) val);
} else if (val instanceof Address) {
builder.emitPushByteArray(((Address) val).toArray());
} else if (val instanceof String) {
builder.emitPushByteArray(((String) val).getBytes());
} else if (val instanceof Boolean) {
builder.emitPushBool((Boolean) val);
} else if(val instanceof Integer){
builder.emitPushByteArray(Helper.BigIntToNeoBytes(BigInteger.valueOf((int)val)));
} else if (val instanceof Long) {
builder.emitPushByteArray(Helper.BigIntToNeoBytes(BigInteger.valueOf((long)val)));
} else if(val instanceof Map){
pushMap(builder,val);
// byte[] bys = getMapBytes(val);
// builder.emitPushByteArray(bys);
} else if(val instanceof Struct){
pushStruct(builder,val);
// byte[] bys = getStructBytes(val);
// builder.emitPushByteArray(bys);
} else if (val instanceof List) {
List tmp = (List) val;
createCodeParamsScript(builder, tmp);
builder.emitPushInteger(new BigInteger(String.valueOf(tmp.size())));
builder.pushPack();
} else {
}
}
} catch (Exception e) {
e.printStackTrace();
}
return builder.toArray();
}
public static Object deserializeItem(byte[] mBytes){
ByteArrayInputStream ms = new ByteArrayInputStream(mBytes);
BinaryReader reader = new BinaryReader(ms);
return deserializeItem(reader);
}
public static Object deserializeItem(BinaryReader reader){
try {
byte t = reader.readByte();
if (t == Type.ByteArrayType.getValue()) {
return reader.readVarBytes();
}else if (t == Type.BooleanType.getValue()) {
return reader.readBoolean();
} else if (t == Type.IntegerType.getValue()) {
long v = Helper.BigIntFromNeoBytes(reader.readVarBytes()).longValue();
return v;
} else if (t == Type.ArrayType.getValue() || t == Type.StructType.getValue()) {
int count = (int)reader.readVarInt();
List list = new ArrayList();
for (int i = count; i > 0; i--) {
Object ele = deserializeItem(reader);
if(ele instanceof byte[]){
ele = new String((byte[])ele);
}
list.add(ele);
count--;
}
return list;
} else if (t == Type.MapType.getValue()) {
int count = (int)reader.readVarInt();
Map map = new HashMap();
for (int i = count; i > 0; i--) {
byte[] key = (byte[])deserializeItem(reader);
Object value = deserializeItem(reader);
if(value instanceof byte[]){
value = Helper.toHexString((byte[])value);
} else if(value instanceof Long){
if((Long)value == 0){
value = "00";
}else {
value = Helper.toHexString(Helper.BigIntToNeoBytes(BigInteger.valueOf((long) value)));
}
}
map.put(new String(key),value);
count--;
}
return map;
} else {
throw new SDKException(ErrorCode.ParamError);
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public static void pushParam(ScriptBuilder sb,Object eValue){
try {
if (eValue instanceof byte[]) {
sb.emitPushByteArray((byte[]) eValue);
} else if (eValue instanceof String) {
sb.emitPushByteArray(((String) eValue).getBytes());
} else if (eValue instanceof Boolean) {
sb.emitPushBool((Boolean) eValue);
sb.add(ScriptOp.OP_PUSH0);
sb.add(ScriptOp.OP_BOOLOR);
} else if (eValue instanceof Map) {
pushMap(sb,eValue);
} else if (eValue instanceof Struct) {
List list = (List) ((Struct) eValue).list;
for (int i = list.size() - 1; i >= 0; i--) {
Object val = list.get(i);
pushParam(sb,val);
}
sb.emitPushInteger(new BigInteger(String.valueOf(list.size())));
sb.pushPack();
} else if (eValue instanceof List) {
List list = (List) eValue;
for (int i = list.size() - 1; i >= 0; i--) {
Object val = list.get(i);
pushParam(sb,val);
}
sb.emitPushInteger(new BigInteger(String.valueOf(list.size())));
sb.pushPack();
} else if (eValue instanceof Integer) {
sb.emitPushByteArray(Helper.BigIntToNeoBytes(BigInteger.valueOf((Integer) eValue)));
sb.add(ScriptOp.OP_PUSH0);
sb.add(ScriptOp.OP_ADD);
} else if (eValue instanceof Long) {
sb.emitPushByteArray(Helper.BigIntToNeoBytes(BigInteger.valueOf((Long) eValue)));
sb.add(ScriptOp.OP_PUSH0);
sb.add(ScriptOp.OP_ADD);
} else {
throw new SDKException(ErrorCode.ParamError);
}
}catch (SDKException e) {
e.printStackTrace();
}
}
public static void pushStruct(ScriptBuilder sb,Object val) {
Struct struct = (Struct) val;
sb.add(ScriptOp.OP_NEWSTRUCT);
sb.add(ScriptOp.OP_TOALTSTACK);
for (int i =0;i < struct.list.size();i++) {
pushParam(sb, struct.list.get(i));
sb.add(ScriptOp.OP_DUPFROMALTSTACK);
sb.add(ScriptOp.OP_SWAP);
sb.add(ScriptOp.OP_APPEND);
}
sb.add(ScriptOp.OP_FROMALTSTACK);
}
public static void pushMap(ScriptBuilder sb,Object val) {
Map map = (Map) val;
sb.add(ScriptOp.OP_NEWMAP);
sb.add(ScriptOp.OP_TOALTSTACK);
for (Map.Entry e : map.entrySet()) {
sb.add(ScriptOp.OP_DUPFROMALTSTACK);
pushParam(sb, e.getKey());
pushParam(sb, e.getValue());
sb.add(ScriptOp.OP_SETITEM);
}
sb.add(ScriptOp.OP_FROMALTSTACK);
}
public static void serializeStackItem(BinaryWriter bw,Object eValue){
try {
if(eValue instanceof byte[]){
bw.writeByte(Type.ByteArrayType.getValue());
bw.writeVarBytes((byte[]) eValue);
} else if(eValue instanceof String){
bw.writeByte(Type.ByteArrayType.getValue());
bw.writeVarBytes(((String) eValue).getBytes());
} else if (eValue instanceof Boolean) {
bw.writeByte(Type.BooleanType.getValue());
bw.writeBoolean((Boolean) eValue);
} else if (eValue instanceof Map) {
bw.write(getMapBytes(eValue));
} else if (eValue instanceof Struct) {
bw.writeVarBytes(getStructBytes(eValue));
} else if (eValue instanceof List) {
List tmp = (List) eValue;
bw.writeByte(Type.ArrayType.getValue());
bw.writeVarInt(tmp.size());
for (int i = 0; i < tmp.size(); i++) {
serializeStackItem(bw, tmp.get(i));
}
}else if(eValue instanceof Integer){
bw.writeByte(Type.IntegerType.getValue());
bw.writeVarBytes(Helper.BigIntToNeoBytes(BigInteger.valueOf((Integer) eValue)));
} else if(eValue instanceof Long){
bw.writeByte(Type.IntegerType.getValue());
bw.writeVarBytes(Helper.BigIntToNeoBytes(BigInteger.valueOf((Long) eValue)));
} else {
throw new SDKException(ErrorCode.ParamError);
}
} catch (Exception e) {
e.printStackTrace();
}
}
public static byte[] getStructBytes(Object val){
ByteArrayOutputStream baos = new ByteArrayOutputStream();
BinaryWriter bw = new BinaryWriter(baos);
try {
List list = ((Struct)val).list;
bw.writeByte(Type.StructType.getValue());
bw.writeVarInt(list.size());
for (int i = 0; i < list.size(); i++) {
Object eValue = list.get(i);
serializeStackItem(bw,eValue);
}
} catch (Exception e) {
e.printStackTrace();
}
return baos.toByteArray();
}
public static byte[] getMapBytes(Object val){
ByteArrayOutputStream baos = new ByteArrayOutputStream();
BinaryWriter bw = new BinaryWriter(baos);
try {
Map map = (Map)val;
bw.writeByte(Type.MapType.getValue());
bw.writeVarInt(map.size());
for(Map.Entry e:map.entrySet()){
bw.writeByte(Type.ByteArrayType.getValue());
bw.writeVarBytes(((String) e.getKey()).getBytes());
Object eValue = e.getValue();
serializeStackItem(bw,eValue);
}
bw.flush();
} catch (Exception e) {
e.printStackTrace();
}
return baos.toByteArray();
}
/**
* @param list
* @return
*/
public static byte[] createCodeParamsScript(List list) {
ScriptBuilder sb = new ScriptBuilder();
try {
createCodeParamsScript(sb, list);
} catch (Exception e) {
e.printStackTrace();
}
return sb.toArray();
}
/**
* @param abiFunction
* @return
* @throws Exception
*/
public static byte[] serializeAbiFunction( AbiFunction abiFunction) throws Exception {
List list = new ArrayList();
list.add(abiFunction.getName().getBytes());
List tmp = new ArrayList();
for (Parameter obj : abiFunction.getParameters()) {
if ("ByteArray".equals(obj.getType())) {
tmp.add(JSON.parseObject(obj.getValue(), byte[].class));
} else if ("String".equals(obj.getType())) {
tmp.add(obj.getValue());
} else if ("Boolean".equals(obj.getType())) {
tmp.add(JSON.parseObject(obj.getValue(), boolean.class));
} else if ("Integer".equals(obj.getType())) {
tmp.add(JSON.parseObject(obj.getValue(), Long.class));
} else if ("Array".equals(obj.getType())) {
List l = JSON.parseObject(obj.getValue(), List.class);
l = listConvert(l);
tmp.add(l);
} else if ("InteropInterface".equals(obj.getType())) {
tmp.add(JSON.parseObject(obj.getValue(), Object.class));
} else if ("Void".equals(obj.getType())) {
} else if ("Map".equals(obj.getType())) {
tmp.add(JSON.parseObject(obj.getValue(), Map.class));
} else if ("Struct".equals(obj.getType())) {
tmp.add(JSON.parseObject(obj.getValue(), Struct.class));
} else {
throw new SDKException(ErrorCode.TypeError);
}
}
if(list.size()>0) {
list.add(tmp);
}
byte[] params = createCodeParamsScript(list);
return params;
}
private static List listConvert(List l){
for(int i = 0; i < l.size();i++){
if(l.get(i) instanceof String) {
if (l.get(i) instanceof String) {
l.set(i, Base64.getDecoder().decode((String) l.get(i)));
}
}else if (l.get(i) instanceof List) {
l.set(i,listConvert((List)l.get(i)));
}
}
return l;
}
}