| 
                         搞定了块的生成,接下来我们需要有函数帮我们判断一个块是否有被篡改。检查 Index 来看这个块是否正确得递增,检查 PrevHash 与前一个块的 Hash 是否一致,再来通过 calculateHash 检查当前块的 Hash 值是否正确。通过这几步我们就能写出一个校验函数: 
- public static boolean isBlockValid(Block newBlock, Block oldBlock) {  
 -        if (oldBlock.getIndex() + 1 != newBlock.getIndex()) {  
 -            return false;  
 -        }  
 -        if (!oldBlock.getHash().equals(newBlock.getPrevHash())) {  
 -            return false;  
 -        }  
 -        if (!calculateHash(newBlock).equals(newBlock.getHash())) {  
 -            return false;  
 -        }  
 -        return true;  
 -     } 
 
  
除了校验块以外,我们还会遇到一个问题:两个节点都生成块并添加到各自的链上,那我们应该以谁为准?这里的细节我们留到下一篇文章,这里先让我们记住一个原则:始终选择最长的链。 
[block 1] -> [block 2] -> [block 3] -> [block 4] -> [block 5] -> 认可 
[block 1] -> [block 2] -> [block 3] -> [block 4] ->  丢弃 
通常来说,更长的链表示它的数据(状态)是更加新的,所以我们需要一个函数能帮我们将本地的过期的链切换成最新的链: 
- public void replaceChain(ArrayList<Block> newBlocks) {  
 -        if (newBlocks.size() > blockChain.size()) {  
 -            blockChain = newBlocks;  
 -        }  
 -     } 
 
  
到这一步,我们基本就把所有重要的函数完成了。接下来,我们需要一个方便直观的方式来查看我们的链,包括数据及状态。通过浏览器查看 web 页面可能是最合适的方式。 
Web 服务 
我猜你一定对传统的 web 服务及开发非常熟悉,所以这部分你肯定一看就会。 
借助 Spark Web Framework,来完成我们的 web 服务,代码如下: 
- public static void main(String[] args) {  
 -        // port(5678); //默认端口是4567,你可以设置别的端口   
 - } 
 
  
OK,完成,对,你没看错,就是一个空的main方法,就可以了。 
接下来我们定义不同 endpoint 以及对应的 handler。例如,对“/”的 GET 请求我们可以查看整个链,对“/”的 POST 请求可以创建一个新的块。 
GET 请求的 handler: 
- get("/", (q, a) ->{return gson.toJson(blockChain)}); 
 
  
为了简化,我们直接以 JSON 格式返回整个链,你可以在浏览器中访问 localhost:4567 或者 127.0.0.1:4567 来查看 
POST 请求的 handler 稍微有些复杂,我们先来定义一下 POST 请求的 payload: 
- public class Message {  
 -     private int vac;  
 - //getters and setters  
 - } 
 
  
再看看 handler 的实现: 
- post("/", (q, a) -> {  
 - String body = request.body();  
 -               Message m = gson.fromJson(body, Message.class);  
 -               if (m == null) {  
 -                   return "vac is NULL";  
 -               }  
 -               int vac = m.getVac();  
 -               Block lastBlock = blockChain.get(blockChain.size() - 1);  
 -               Block newBlock = generateBlock(lastBlock, vac);  
 -               if (isBlockValid(newBlock, lastBlock)) {  
 -                   blockChain.add(newBlock);  
 -                   LOGGER.debug(gson.toJson(blockChain));  
 -               } else {  
 -                   return "HTTP 500: Invalid Block Error";  
 -               }  
 -               return "success!";  
 - }); 
 
  
我们的 POST 请求体中可以使用上面定义的 payload,比如: 
{"vac":7500}                         (编辑:我爱故事小小网_铜陵站长网) 
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! 
                     |