Java语言实现区块链(一)

一、定义账本

(1)定义账本类

// 账本
public class NoteBook {
    // 保存区块的集合
    private List<String> blocks = new ArrayList<>();
    
    /** 添加创世块
     * @param data : 区块数据
     */
    public void addGenesisBlock(String data) {
        
    }

    /** 添加普通创世块
     * @param data : 区块数据
     */
    public void addBlock(String data) {
        
    }

    // 显示账本数据
    public void showList() {
       
    }

    // 把账本保存到文件中
    public void save2File() {
        
    }

}

(2)实现方法

/** 添加创世块
     * @param data : 区块数据
     */
    public void addGenesisBlock(String data) throws IOException {
        // 只有账本为空,才可以添加创世块
        if (blocks.size() > 0) {
            throw new RuntimeException("账本不为空,添加创世块失败!");
        }
        blocks.add(data);
        // 保存数据
        save2File();
    }

    /** 添加普通创世块
     * @param data : 区块数据
     */
    public void addBlock(String data) throws IOException {
        // 只有账本不为空,才可以添加普通区块
        if (blocks.size() == 0) {
            throw new RuntimeException("账本为空,添加普通区块失败!");
        }
        blocks.add(data);
        // 保存数据
        save2File();
    }

    // 显示账本数据
    public void showList() {
        for (String block : blocks) {
            // sout
            System.out.println(block);
        }
    }

    // 把账本保存到文件中
    public void save2File() throws IOException {
        // 使用jackson对blocks对象执行序列化操作
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.writeValue(new File("blocks.json"), blocks);
    }

(3)定义main函数

public static void main(String[] args) throws Exception {
    NoteBook nb = new NoteBook();
    nb.addGenesisBlock("aa给bb转账10个比特币...");
    nb.addBlock("bb给cc转账5个比特币...");
    nb.showList();
}

(4)定义构造函数,对blocks集合执行初始化。

public NoteBook() throws IOException {
    // 读取json文件,执行反序列化操作
    File f = new File("blocks.json");
    if (f.exists() && f.length() > 0) {
         ObjectMapper objectMapper = new ObjectMapper();
        JavaType javaType = objectMapper.getTypeFactory()
                .constructParametricType(ArrayList.class, String.class);
        blocks = objectMapper.readValue(f, javaType);
    }
}

 

二、提供用户操作界面

(1)定义控制器类

@RestController
public class BlockController {
    private NoteBook noteBook = new NoteBook();

    @RequestMapping(value = "/addGenesisBlock", method = RequestMethod.POST)
    public String addGenesisBlock(String content) {
        try {
            noteBook.addGenesisBlock(content);
            return "添加创世块成功!";
        } catch (Exception e) {
            return "添加失败:" + e.getMessage();
        }
    }

    @RequestMapping(value = "/addBlock", method = RequestMethod.POST)
    public String addBlock(String content) {
        try {
            noteBook.addBlock(content);
            return "添加区块成功!";
        } catch (Exception e) {
            return "添加失败:" + e.getMessage();
        }
    }

    @RequestMapping(value = "/showList", method = RequestMethod.GET)
    public List<String> showList() {
        return noteBook.showList();
    }

}

(2)创建操作界面

第一步:拷贝资源文件到src/main/resources/static目录下。

资源下载地址:https://pan.baidu.com/s/1ojsg9ThOWTb8hJVLede1Gw  提取码:uz2d

第二步:创建前台页面。

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8"/>
    <title></title>
    <link rel="stylesheet" type="text/css" href="css/bootstrap.css"/>
    <link rel="stylesheet" type="text/css" href="css/pb.css"/>
    <script src="js/jquery-1.12.4.min.js" type="text/javascript" charset="utf-8"></script>
    <script src="js/bootstrap.js" type="text/javascript" charset="utf-8"></script>
    <script src="js/pb.js" type="text/javascript" charset="utf-8"></script>
    <script src="js/jsrsasign-all-min.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>

</body>
</html>

pb工具是用来展示进度条,jsrsasign工具是用来生成签名。

第三步:提供功能按钮。

<!-- 输入框 -->
<input type="text" class="form-control" id="content" placeholder="请输入内容">
<!-- 按钮组 -->
<div class="btn-group btn-group-lg">
    <button type="button" class="btn btn-default" onclick="addGenesisBlock()">创建创世块</button>
    <button type="button" class="btn btn-default" onclick="addBlock()">创建普通区块</button>
    <button type="button" class="btn btn-default" onclick="showList()">显示数据</button>
</div>
<!-- 用于展示结果 -->
<p class="bg-info" id="result"></p>

为了让页面看得舒服,可以添加以下样式。

<style>
    body {
        margin: 30px;
    }

    #id {
        width: 500px;
    }

    #result {
        padding: 15px;
        font-size: 18px;
    }
</style>

第四步:添加按钮事件。

// 创建创世块
function addGenesisBlock() {
	// 获取用户输入的内容
	var content = $("#content").val();
	// 显示进度条
	loading.baosight.showPageLoadingMsg(false);
	// 发起请求
	$.post("addGenesisBlock", "content=" + content, function(data) {
		// 展示操作结果
		$("#result").html(data)
		// 展示最新数据
		showList();
		// 清空输入框
		$("#content").val("");
		// 隐藏进度条
		loading.baosight.hidePageLoadingMsg();
	});
}

// 创建普通区块
function addBlock() {
	// 获取用户输入的内容
	var content = $("#content").val();
	// 显示进度条
	loading.baosight.showPageLoadingMsg(false);
	// 发起请求
	$.post("addBlock", "content=" + content, function(data) {
		// 展示操作结果
		$("#result").html(data)
		// 展示最新数据
		showList();
		// 清空输入框
		$("#content").val("");
		// 隐藏进度条
		loading.baosight.hidePageLoadingMsg();
	});
}

// 显示数据
function showList() {
	// 显示进度条
	loading.baosight.showPageLoadingMsg(false)
	// 发起请求
	$.get("showList", function (data) {
		// 清空数据
		$("#tbody").html("");
		//展示结果
		$("#result").html(data);
		// 隐藏进度条
		loading.baosight.hidePageLoadingMsg();
	});
}

(3)启动项目测试,界面效果如下图所示:

猜你喜欢

转载自blog.csdn.net/zhongliwen1981/article/details/89705208