Blanco simple sistema de Bitcoin programación analógica, un movimiento de la mano y le llevará a escribir! (Con el código)

Autor | VV sonrisaヽ 

Zebian | Carol

Producido | bloque de la cadena campo base (blockchain_camp)

Cubierta | RDCC pagar para descargar el visual de China

Si hay un P2P D del emo, ¿cómo las aplicamos a la cadena de bloque?

Reunido hoy para tratar de mirada en ella!

Primero, necesitamos para simular una pluralidad de nodos de la red comunicarse entre sí, se supone que la situación actual es AB tiene dos nodos en todo el proceso que se muestra a continuación:

proceso de peinado

especie de dejar salir lo que todo el proceso, específicamente en el P2P que necesita la red para hacerse.

  1. nodo de inicio A. Una primera crear un bloque de la Creación

  2. Crear una cartera A1. Un nodo se crea llamadas a la API proporcionadas por una cartera, entonces la moneda A1 Esfera es cero.

  3. la minería A1. Una llamada al nodo proporcionada por API minería, para generar un nuevo bloque, así como el monedero de la moneda A1 con el sistema de bolas de recompensa.

  4. A partir de un nodo B. Para un Nodo B información de sincronización , la cadena de bloque actual, en la actualidad el comercio de la piscina, todos los fondos públicos actual.

  5. Crear una cartera B1, A2, llamar a la API nodo A y B, que se emitirá (notificar a cada nodo) para crear una cartera de (público) , sólo hay dos nodos, por lo que una necesidad de decir B, A2 cartera. B necesidad de decir A, B1 billetera.

  6. A1 transfiere a B1. API Una llamada a la oferta, mientras que las transacciones de difusión .

  7. contabilidad de la minería A2. API Una llamada a la oferta, así como la emisión de un bloque de la nueva generación .

En resumen, el nodo se añade al principio de la red de la cadena de bloque, otros nodos necesitan ser sincronizado

  • información sobre la cadena de bloque

  • información del monedero

  • Información sobre la Operativa

Tiene un nodo de la red, la necesidad de notificar a otros nodos de la red en los siguientes casos

  • La nueva transacción

  • Crear una nueva cartera

  • Un nuevo bloque de la minería

proceso general P2P para algunos abajo, que combinará detrás de la realización de este proceso.

  1. → cliente servidor envía un mensaje, típicamente datos de la solicitud;

  2. Después de que el servidor recibe un mensaje, se envía un mensaje al cliente (call-servicio, el procesamiento devuelve datos);

  3. los datos de procesamiento de mensajes recibidos de los clientes (servicio de llamada, procesamiento de datos).

El código en cuestión

En la implementación, ya que muchos tipos de mensaje, encapsula el objeto de mensaje utilizado para transmitir un mensaje, el tipo de mensaje está codificado, el mensaje, objeto de mensaje, implementos unitarias interfaz Serializable, por lo que el objeto se puede serializar:

public class Message implements Serializable {
/**
     * 消息内容,就是我们的区块链、交易池等所需要的信息,使用JSON.toString转化到的json字符串
     */
private String data;
/**
     * 消息类型
     */
private int type;
}

En relación con el tipo de mensaje (tipo) son:

/**
 * 查询最新的区块
 */
private final static int QUERY_LATEST_BLOCK = 0;
/**
 * 查询整个区块链
 */
private final static int QUERY_BLOCK_CHAIN = 1;
/**
 * 查询交易集合
 */
private final static int QUERY_TRANSACTION = 2;
/**
 * 查询已打包的交易集合
 */
private final static int QUERY_PACKED_TRANSACTION = 3;
/**
 * 查询钱包集合
 */
private final static int QUERY_WALLET = 4;
/**
 * 返回区块集合
 */
private final static int RESPONSE_BLOCK_CHAIN = 5;
/**
 * 返回交易集合
 */
private final static int RESPONSE_TRANSACTION = 6;
/**
 * 返回已打包交易集合
 */
private final static int RESPONSE_PACKED_TRANSACTION = 7;
/**
 * 返回钱包集合
 */
private final static int RESPONSE_WALLET = 8;

Debido a demasiados códigos, no todos atrapados aquí, con el fin de sincronizar otra información al cliente nodos cartera, por ejemplo, en relación con lo anterior P2P red de interacciones de tres pasos, se dan cuenta relevante introducir siguiente.

1, cliente → servidor envía un mensaje, los datos de la solicitud es típicamente

Creado en el objeto de cliente de clase de cliente nodo de inicio, llamar a los métodos internos del cliente, la conexión del servidor.

código de clave de clase de partida método Main (Args dispuestos en los parámetros del puerto):

P2PClient p2PClient = new P2PClient();
String url = "ws://localhost:"+args[0]+"/test";       
p2PClient.connectToPeer(url);

P2PClientEl connectToPeermétodo:

public void connectToPeer(String url) throws IOException, DeploymentException {
    WebSocketContainer container = ContainerProvider.getWebSocketContainer();
    URI uri = URI.create(url);
this.session = container.connectToServer(P2PClient.class, uri);
}

P2PClient, El WebSocketContainer.connectToServertiempo será de devolución de llamada onOpende función, se supone que la cartera investigación de la información pública única, entonces el servidor recibirá la solicitud correspondiente.

@OnOpen
public void onOpen(Session session) {
this.session = session;
    p2PService.sendMsg(session, p2PService.queryWalletMsg());
}

Nota: I mensajes de análisis sintáctico relacionados paquete de operaciones a un servicio, una unificado fácil de usar servidor y cliente. Da el correspondiente queryWalletMsgmétodo:

public String queryWalletMsg() {
return JSON.toJSONString(new Message(QUERY_WALLET));
}

Además de los anteriormente mencionados sendMsgmétodos:

@Override
public void sendMsg(Session session, String msg) {
session.getAsyncRemote().sendText(msg);
}

2, S erver después de recibir el mensaje, el envío de un mensaje al cliente ( llamada S ervice, devoluciones datos procesados )

Servidor recibe el mensaje , introduzca P2PServerel OnMessagemétodo

/**
 * 收到客户端发来消息
 * @param msg  消息对象
 */
@OnMessage
public void onMessage(Session session, String msg) {
    p2PService.handleMessage(session, msg);
}

p2PService.handleMessageEs el mensaje (MSG) analizar la recibieron, de acuerdo con otros métodos de diferentes tipos de llamadas (una declaración del interruptor gigante aquí introducir una pequeña parte), en los que hemos recibido el código de información de cliente que viene QUERY_WALLET.

@Override
public void handleMessage(Session session, String msg) {
    Message message = JSON.parseObject(msg, Message.class);
switch (message.getType()){
case QUERY_WALLET:
            sendMsg(session, responseWallets());
break;
case RESPONSE_WALLET:
            handleWalletResponse(message.getData());
break;
            ......
    }

El código de información es un QUERY_WALLETllamado  responseWallets()método, para obtener datos .

private String responseWallets() {
String wallets = blockService.findAllWallets();
return JSON.toJSONString(new Message(RESPONSE_WALLET, wallets));
}

Aquí pongo la cadena de bloques de las operaciones relacionadas también encapsular un servicio, lo que sigue se dan findAllWalletsrealización concreta, de hecho, que atraviesa una colección de bolsos, carteras estadística pública, no hay ninguna dificultad.

@Override
public String findAllWallets() {
    List<Wallet> wallets = new ArrayList<>();
    myWalletMap.forEach((address, wallet) ->{
        wallets.add(Wallet.builder().publicKey(wallet.getPublicKey()).build());
    });
    otherWalletMap.forEach((address, wallet) ->{
        wallets.add(wallet);
    });
return JSON.toJSONString(wallets);
}

Después de obtener los datos, y el retorno al Cliente:

Así que nuestro  responseWallets()enfoque, la última frase crea un objeto de mensaje y establece el código de información RESPONSE_WALLETde handleMessagela llamada sendmsgde regreso método para el cliente.

case QUERY_WALLET:
        sendMsg(session, responseWallets());
        break;

. 3, C Lien T recibido datos de mensaje (llamada de servicio, procesamiento de datos)

Las solicitudes de cliente recibidos los datos obtenidos en P2PClientel OnMessagemétodo:

@OnMessage
public void onMessage(String msg) {
    p2PService.handleMessage(this.session, msg);
}

También entre en nuestra mencionada p2PService.handleMessagemétodo, esta vez recibió código de información RESPONSE_WALLETen el handleWalletResponsemétodo:

case RESPONSE_WALLET:
        handleWalletResponse(message.getData());
        break;

handleWalletResponseImplementación, el análisis de la información recibida de la cartera de clave pública, y almacenar el nodo cliente blockServiceen.

private void handleWalletResponse(String msg) {
    List<Wallet> wallets = "\"[]\"".equals(msg)?new ArrayList<>():JSON.parseArray(msg, Wallet.class);
    wallets.forEach(wallet -> {
        blockService.addOtherWallet(walletService.getWalletAddress(wallet.getPublicKey()),wallet );
    });
}

Cuando la aplicación específica, debido a la forma en que el uso de los servicios de inyección, el uso de anotaciones a @Autowired servidor (@ServerEndpoint) y el cliente (@ClientEndpoint) inyecta Bean, cuenta con la primavera de arranque debido Singleton.

Y cada vez WebSocket crear un nuevo objeto, por lo que cuando se utiliza el servicio dará lugar a una excepción de puntero nulo, por lo tanto, hemos creado una herramienta como la primavera hasta que, cada vez que necesitan servicios están disponibles en el recipiente de la primavera nos deseada Bean, código de clase herramientas es la siguiente.

public class SpringUtil implements ApplicationContextAware {
public static ApplicationContext applicationContext;
    @Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
if (SpringUtil.applicationContext != null) {
            SpringUtil.applicationContext = applicationContext;
        }
    }
/**
     * 获取applicationContext
     */
public static ApplicationContext getApplicationContext() {
return applicationContext;
    }

/**
     * 通过name获取 Bean.
     */
public static Object getBean(String name) {
return getApplicationContext().getBean(name);
    }
/**
     * 通过class获取Bean.
     */
public static <T> T getBean(Class<T> clazz) {
return getApplicationContext().getBean(clazz);
    }

/**
     * 通过name,以及Clazz返回指定的Bean
     */
public static <T> T getBean(String name, Class<T> clazz) {
return getApplicationContext().getBean(name, clazz);
    }
}

Así tenemos que establecer antes de la prueba SpringUtilse applicationContextda a continuación inicio de la clase (para una prueba sencilla, de clase dos nodos comparten una bota, respectivamente, de acuerdo con el tratamiento de diferentes Args) la configuración y el nodo correspondiente.

public static void main(String[] args) {
    System.out.println("Hello world");
    SpringUtil.applicationContext  = SpringApplication.run(Hello.class, args);
if (args.length>0){
        P2PClient p2PClient = new P2PClient();
        String url = "ws://localhost:"+args[0]+"/test";
try {
            p2PClient.connectToPeer(url);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

En uso, tenemos que conseguir manualmente frijol :

//之前是这样//@Autowired//private P2PService p2PService;//改正后,去掉Autowired,每次使用都手动获取beanprivate P2PService p2PService;@OnOpenpublic void onOpen(Session session) {//如果不使用那些,在这里会报空指针异常,p2PService 为 null p2PService = SpringUtil.getBean(P2PService.class);//新增这句话从IVO容器中获取bean p2PService.sendMsg(session, p2PService.queryWalletMsg());}

Hola nodo, cuando se prueba como un servidor:

nodo de prueba, cuando se probó como un cliente.

Esto, nos damos cuenta el nodo de red P2P en la interacción de servidor y nodo cliente. Le sugiero que puede probar, y luego se discute en el área de comentarios y Oh!

lectura recomendada 

no tienen un pelo fuera! Con aleteo + dardo construir rápidamente una hermosa App móviles

Mira lo que encontré una buena cosa? Java opcional, definitivamente vale la pena el aprendizaje | programa de la Fuerza

Tencent combina ACNET mención clasificación de grano fino, el efecto es hasta la última SOTA | CVPR 2020

Mi recomendación nube IDE favorito!

Las funciones avanzadas de Solidez contrato escrito de la inteligencia

retorno personal E para volver al trabajo readme: volver al trabajo, Wuhan, Hefei vuela primero, y luego volver y recoger fletado por la empresa

Nos fijamos en cada punto, en serio como favorito

Liberadas 1830 artículos originales · ganado elogios 40000 + · Vistas 16,540,000 +

Supongo que te gusta

Origin blog.csdn.net/csdnnews/article/details/104890435
Recomendado
Clasificación