简单的用java代码实现智能合约
简单理解智能合约:
所谓智能合约,从另一个角度望过去,就是写入了不可篡改的电子账簿中的,可执行但不可篡改的程序代码而已。
一、
编写生成jar包
二、
通过文件流的方式读取jar,获取到每个class对象对应的字节数组
1.首先获取到jar对应的字节输入流
String jarPath = "/nghb/jar/MyFirstDemo.jar";
File file = new File(jarPath);
System.out.println("文件的长度:"+file.length());
byte [] buffer = new byte[Integer.parseInt(String.valueOf(file.length()))];
FileInputStream fis = new FileInputStream(file);
int size = Integer.parseInt(String.valueOf(file.length()));
int offset;
int read =0;
//int result = fis.read(buffer,0,Integer.parseInt(String.valueOf(file.length())));
// 虽然知道了file文件的长度,但是还是要用for循环把流读到数组中,因为可能存在fis不一定会一次read完所有数据到字节数组中
for(offset = 0;(read = fis.read(buffer,offset,size-offset)) != -1 && offset < size; offset += read){
;
}
2.根据获取到的字节流输入数组,拆分字节流,拆分为jar包中每个类class对象对应的字节流
// JarInputStream专门用来处理jar包流的
JarInputStream jis = new JarInputStream(new ByteArrayInputStream(buffer));
Map byteMap = new HashMap<String,byte[]>();
JarEntry nextEntry = null;
while((nextEntry=jis.getNextJarEntry()) != null){
if(!nextEntry.isDirectory() && nextEntry.getName().endsWith(".class")){
// 层层获取到jar包的jarEntry,替换为class对象中的className形式
String name = nextEntry.getName().replaceAll("/",".").replaceAll(".class","");
byte [] classByte = generateByteOfClass(jis);
byteMap.put(name,classByte);
}
}
/*
* @Author ZDLS
* @Description 根据流的方式,读入jar中的class对象对应的字节流
* @Date 下午 16:44 2021/1/26 0026
* @Param
* @return
*/
private byte [] generateByteOfClass(JarInputStream jarInputStream) throws Exception{
List<byte[]> bufs = null;
byte [] result = null;
int total = 0;
// 整数的最大取值
int remaining = 2147483647;
int n=0;
do{
byte [] buf = new byte[Math.min(remaining,8192)];
int nread = 0;
// 跳出for循环的情况有:buf不够用,这个时间n为0;流读取完了n的返回值为-1
for(nread=0; (n = jarInputStream.read(buf,nread,Math.min(buf.length - nread,remaining)))>0;remaining -= n){
nread += n;
}
if(nread > 0){
if(2147483639 - total < nread){
System.out.println("抛出异常");
}
total += nread;
if(result == null){
result = buf;
}else {
if(bufs == null){
bufs = new ArrayList<byte[]>();
bufs.add(result);
}
bufs.add(buf);
}
}
}while (remaining>0 && n>= 0);
// while中的调用for循环次数小于2
if(bufs == null){
if(result == null){
return new byte[0];
}else {
return result.length == total ? result : Arrays.copyOfRange(result,0,total);
}
// 把bufs中的数组合并成一个数组,保证每个class对象对应的字节流只是自己
}else {
result = new byte[total];
int count = 0;
int offset = 0;
remaining = total;
for(Iterator var12 = bufs.iterator(); var12.hasNext() ; remaining-=count){
byte[] b = (byte[]) var12.next();
count = Math.min(b.length,remaining);
System.arraycopy(b,0,result,offset,count);
offset += count;
}
}
return result;
}
3.解析下特殊方法意义
n = jarInputStream.read(buf,nread,end)
返回值
入参:buf:本次流要写入的缓存字节数组,nread:本次流开始写入字节数组的起始位置,end:本次流最大写入字节的长度
返回值:本次流写入的字节数组的长度,-1:表示流读完了,如果返回的值为0,表示的就是本次读入的字节长度为0;一定要保证end - nread的值 > 缓存数据数组剩余的长度。
三、
通过获取到class对象,通过反射获取到jar包中的执行逻辑

浙公网安备 33010602011771号