Cien líneas de código go para construir una sala de chat p2p

Con solo cien líneas de código, puede construir una sala de chat p2p completa, y los mensajes están encriptados y no se pueden rastrear; y no hay necesidad de un servidor, y nunca se detendrá, ¿es genial?

系统实际上基于以太坊的whisper,它本来是为以太坊上的DAPPS通信构建的,这里直接拿来做聊天室一点问题都没有.

1. Empiece

Hablemos de la utilización en primer lugar, para experimentar el completo sistema de chat anónimo P2P.
Ejecutar p2pmessage.exe en el terminal y esperar a que aparezca. En
Connected to peer,you can type message now.este momento, ya está conectado a la red p2p susurro. Puede tomar unos minutos para
que tenga éxito. Usted Puede recibir mensajes de otras personas o enviar mensajes a otras personas.
Puede iniciar programas en diferentes máquinas al mismo tiempo para sentir los resultados.

2017-09-11 11:31:18 <mine>: hello
input ~Q to quit>
2017-09-11 11:33:10 [182cbbaac94313b3b96b25d9c9a0a1adea4519e9]: who am i

La primera línea es el mensaje que envié, la segunda línea es la entrada de solicitud y la tercera línea es el mensaje enviado por 182cbbaac94313b3b96b25d9c9a0a1adea4519e9.
Entre ellos, 182cbbaac94313b3b96b25d9c9a0a1adea4519e9 es el identificador de nodo.

2. Principio del susurro

Conectando al nodo en la red de susurros, al recibir cualquier mensaje, primero verificará la carga de trabajo (consulte bitmessage), y si no hay problema, luego lo reenviará.
Al mismo tiempo, también verá si me lo envían, y si es así, avisar al usuario.
En cuanto a cómo saber si me lo envían, hay muchas formas, aquí solo se usa el tema y la coincidencia de contraseña. En
otras palabras, debe ser el tema que me interesa, y la contraseña encriptada también la especifico yo. Entonces puedes chatear alegremente a.
Por supuesto, no puedo saber quién es, a menos que él me dice.

3. Interpretación del código fuente

Puede descargar el código fuente completo desde github .

3.1 Descripción de parámetros

Hay un total de tres parámetros
-verbosity para imprimir información de depuración
-Tema El tema de la sala de chat (cualquiera de los cuatro bytes), debe conocer el tema con antelación a unirse, si se escribe una al azar, va a crear una sala de chat a sí mismo.
-Password La contraseña de la sala de chat y la contraseña del asunto son las mismas para ingresar a la misma sala de chat.

3.1 Conectarse al nodo maestro

Aunque la red p2p no tiene servidor, debe haber un nodo conocido, de lo contrario no se puede iniciar la red, lo
primero es conectarse al nodo maestro de Ethereum.

	for _, node := range ethparams.MainnetBootnodes {
		peer := discover.MustParseNode(node)
		peers = append(peers, peer)
	}
    peer := discover.MustParseNode("enode://b89172e36cb79202dd0c0822d4238b7a7ddbefe8aa97489049c9afe68f71b10c5c9ce588ef9b5df58939f982c718c59243cc5add6cebf3321b88d752eac02626@182.254.155.208:33333")
	peers = append(peers, peer)

Este último nodo lo construyo yo. Es conveniente que los usuarios domésticos se comuniquen rápidamente, porque la comunicación basada en el nodo maestro puede ser más lenta y la demora es mayor.

3.2 Mi logo

Cada nodo tiene su propia clave privada y la identidad es su propia clave pública.
Por supuesto, puede usar la misma clave privada cada vez. Para simplificar, se genera automáticamente cada vez.

    asymKeyID, err = shh.NewKeyPair()
	if err != nil {
		utils.Fatalf("Failed to generate a new key pair: %s", err)
	}

	asymKey, err = shh.GetPrivateKey(asymKeyID)
	if err != nil {
		utils.Fatalf("Failed to retrieve a new key pair: %s", err)
	}

3.2 Configurar mi nodo

Un nodo reenvía constantemente mensajes que cumplen con Pow. Si es un mensaje de mi sala de chat, dígaselo al usuario. Por lo tanto, el nodo tiene que interactuar con otros nodos. Cuantos más nodos interactúen, más rápido se propagará el mensaje.
Por supuesto, el número de estos nodos Debe haber un límite superior, aquí es 80. La variable de pares es 3.1 el nodo maestro conectado al nodo maestro.

maxPeers := 80

	server = &p2p.Server{
		Config: p2p.Config{
			PrivateKey:     asymKey,
			MaxPeers:       maxPeers,
			Name:           common.MakeName("p2p chat group", "5.0"),
			Protocols:      shh.Protocols(),
			NAT:            nat.Any(),
			BootstrapNodes: peers,
			StaticNodes:    peers,
			TrustedNodes:   peers,
		},
	}

3.3 Qué sala de chat


Aquellos con el mismo tema y contraseña son la misma sala de chat. SymKey está asociado con la contraseña especificada y el tema almacena el tema especificado de cuatro bytes.

func configureNode() {
	symKeyID, err := shh.AddSymKeyFromPassword(*argPass)
	if err != nil {
		utils.Fatalf("Failed to create symmetric key: %s", err)
	}
	symKey, err = shh.GetSymKey(symKeyID)
	if err != nil {
		utils.Fatalf("Failed to save symmetric key: %s", err)
	}
	copy(topic[:], common.FromHex(*argTopic))
	fmt.Printf("Filter is configured for the topic: %x \n", topic)
}

3.3 Únase a la sala de chat

Mi nodo puede recibir miles de mensajes, algunos de los cuales puedo descifrar y algunos de los cuales no puedo descifrar, pero solo una pequeña parte de ellos es lo que quiero ver.
Así que dile a mi nodo que solo siento acerca de esta sala de chat. Interés, avíseme si hay un mensaje.
SubscribeMessage se suscribe al mensaje del tema y contraseña especificados, preste atención al filterID, que es equivalente al manejador de suscribirse al sistema para un mensaje específico, y se usará más adelante.

func SubscribeMessage() {
	var err error

	filter := whisper.Filter{
		KeySym:   symKey,
		KeyAsym:  asymKey,
		Topics:   [][]byte{topic[:]},
		AllowP2P: true,
	}
	filterID, err = shh.Subscribe(&filter)
	if err != nil {
		utils.Fatalf("Failed to install filter: %s", err)
	}
}

3.4 Mensajería masiva

En la red p2p, la mensajería masiva es la más simple. Si quieres enviar mensajes punto a punto, hay más restricciones. Whisper proporciona una API para enviar mensajes. Lo
principal es construir una estructura de mensaje legal, principalmente para especificar el tema y la clave de cifrado. También está el cuerpo del mensaje (carga útil), asymKey se utiliza principalmente para identificar el ID, no para el cifrado asimétrico.

Enviar un mensaje es principalmente para calcular el hash de acuerdo con los requisitos de PoW especificados (Bitcoin, Litecoin, Ethereum, etc.) y luego enviar el mensaje a la red.

func sendMsg(payload []byte) common.Hash {
	params := whisper.MessageParams{
		Src:      asymKey,
		KeySym:   symKey,
		Payload:  payload,
		Topic:    topic,
		TTL:      whisper.DefaultTTL,
		PoW:      whisper.DefaultMinimumPoW,
		WorkTime: 5,
	}

	msg, err := whisper.NewSentMessage(&params)
	if err != nil {
		utils.Fatalf("failed to create new message: %s", err)
	}
	envelope, err := msg.Wrap(&params)
	if err != nil {
		fmt.Printf("failed to seal message: %v \n", err)
		return common.Hash{}
	}

	err = shh.Send(envelope)
	if err != nil {
		fmt.Printf("failed to send message: %v \n", err)
		return common.Hash{}
	}

	return envelope.Hash()
}

3.5 Recibir mensajes

En realidad, el sistema recibe mensajes y los reenvía constantemente. El mensaje recibido aquí es en realidad para extraer los mensajes que nos interesan, que es el mensaje de nuestra sala de chat.
Tenga en cuenta que el ID de filtro aquí es  3.3, la sala de chat mencionada Sí, se puede considerar como el ID de la sala de chat. Se
puede ver que messageLoop está constantemente sondeando noticias sobre la sala de chat. En la actualidad, Whisper no ha implementado la función de envío de mensajes.

func messageLoop() {
	f := shh.GetFilter(filterID)
	if f == nil {
		utils.Fatalf("filter is not installed")
	}
	ticker := time.NewTicker(time.Millisecond * 50)
	for {
		select {
		case <-ticker.C:
			messages := f.Retrieve()
			for _, msg := range messages {
				printMessageInfo(msg)
			}
		case <-done:
			return
		}
	}
}

4. Vuelva a utilizar p2pmessage

Ejecute en el host 1 y el host 2 al mismo tiempo p2pmessage -topic ffff0000 -password 7859931 y espereConnected to peer,you can type message now.

Puede ver la siguiente captura de pantalla:
Host 1:
Anfitrión 1
Host 2:
Anfitrión 2

5. Dirección de descarga del programa binario

versión
win64 versión linux64

Supongo que te gusta

Origin blog.csdn.net/weixin_39842528/article/details/108375922
Recomendado
Clasificación