|
| 1 | +--- |
| 2 | +title: "Create A libp2p Node (Tutorial)" |
| 3 | +description: "Use libp2p-go to create to a libp2p node" |
| 4 | +draft: false |
| 5 | +menu: |
| 6 | + curriculum: |
| 7 | + parent: "curriculum-libp2p" |
| 8 | +weight: 312 |
| 9 | +category: tutorial |
| 10 | +level: |
| 11 | +- deep |
| 12 | +--- |
| 13 | +## Background |
| 14 | +In this tutorial, you will use a boilerplate Go project to set up two libp2p nodes and connect them, so you can begin to explore the capabilities of libp2p, such as data transmission, peer identification, routing, messaging, content discovery, and more. |
| 15 | + |
| 16 | +By the end of the exercise, you should be able to: |
| 17 | + |
| 18 | +* Create a new libp2p node |
| 19 | +* Print the node's ID and multiaddresses |
| 20 | +* Configure the node at a basic level |
| 21 | +* Connect to another node |
| 22 | + |
| 23 | + |
| 24 | + |
| 25 | +## Prerequisites |
| 26 | + |
| 27 | +* You must have [Go installed](https://go.dev/doc/install). In this exercise, version 1.18 is used. |
| 28 | + * You can also install [multiple versions of Go](https://go.dev/doc/manage-install#installing-multiple). |
| 29 | +* Clone or fork the `https://github.com/protocol/launchpad-tutorials` [Git repository](https://github.com/protocol/launchpad-tutorials), which contains all the sample applications used in the Launchpad program. |
| 30 | + |
| 31 | +## Instructions |
| 32 | + |
| 33 | +* Open the `/libp2p-go-simple-code` folder of the `launchpad-tutorials` repository in an IDE of your preference. The `app` subfolder contains the template that you will complete. |
| 34 | + |
| 35 | +### Video |
| 36 | +This video will demonstrate how you can create simple libp2p node in a Go application. |
| 37 | + |
| 38 | +{{< youtube Qa-eAvXp6LY >}} |
| 39 | + |
| 40 | +### Review the "main" Function |
| 41 | + |
| 42 | +In the `main.go` file, review the code, at about line 40. |
| 43 | +There are several functions that are called which you will implement in this tutorial. |
| 44 | +The `main()` function manages the flow of the program by calling different helper functions. |
| 45 | + |
| 46 | +### Create the Source Node |
| 47 | + |
| 48 | +* In the `createSourceNode` function, create a libp2p node by using the `libp2p.New()` function. |
| 49 | +This method returns a [host.Host](https://github.com/libp2p/go-libp2p/blob/master/core/host/host.go#L25) interface, which you can use to manage the node. |
| 50 | + |
| 51 | +```go |
| 52 | +func createSourceNode() host.Host { |
| 53 | + node, err := libp2p.New() |
| 54 | + if err != nil { |
| 55 | + panic(err) |
| 56 | + } |
| 57 | + |
| 58 | + return node |
| 59 | +} |
| 60 | +``` |
| 61 | + |
| 62 | +By default, the node gets an ID and listens at a random TCP port. |
| 63 | + |
| 64 | +### Create the Target Node |
| 65 | + |
| 66 | +* Now, in the `createTargetNode` function, create a new node that listens at the `8007` TCP port. You can configure a node by passing several [Option](https://github.com/libp2p/go-libp2p/blob/master/libp2p.go#L13) structs to the `New(...)` method. |
| 67 | + |
| 68 | +```go |
| 69 | +func createTargetNode() host.Host { |
| 70 | + node, err := libp2p.New( |
| 71 | + libp2p.ListenAddrStrings( |
| 72 | + "/ip4/0.0.0.0/tcp/8007", |
| 73 | + ), |
| 74 | + ) |
| 75 | + if err != nil { |
| 76 | + panic(err) |
| 77 | + } |
| 78 | + |
| 79 | + return node |
| 80 | +} |
| 81 | +``` |
| 82 | + |
| 83 | +### Connect the Nodes |
| 84 | + |
| 85 | +* So far, you have created two nodes; now, let's connect `sourceNode` to `targetNode`. |
| 86 | +The `host.Host` interface contains a `Connect` method that you can use. |
| 87 | +The `Connect` method expects a `peer.AddrInfo` struct, which is an abstraction that represents the _location_ of a peer. |
| 88 | +To create a `peer.AddrInfo` struct with the data of the node, you can use the [host.InfoFromHost](https://github.com/libp2p/go-libp2p/blob/master/core/host/helpers.go#L6) function. |
| 89 | + |
| 90 | +```go |
| 91 | +func connectToTargetNode(sourceNode host.Host, targetNode host.Host) { |
| 92 | + targetNodeAddressInfo := host.InfoFromHost(targetNode) |
| 93 | + |
| 94 | + err := sourceNode.Connect(context.Background(), *targetNodeAddressInfo) |
| 95 | + if err != nil { |
| 96 | + panic(err) |
| 97 | + } |
| 98 | +} |
| 99 | +``` |
| 100 | + |
| 101 | +### Count the Number of Peers of the Source Node |
| 102 | + |
| 103 | +* To verify that the connection works, you can list the peers connected to the node. In this example, you will simply count the number of peers and return that number to verify that your libp2p node is connected to peers. |
| 104 | + |
| 105 | +```go |
| 106 | +func countSourceNodePeers(sourceNode host.Host) int { |
| 107 | + return len(sourceNode.Network().Peers()) |
| 108 | +} |
| 109 | +``` |
| 110 | + |
| 111 | +### Run the Program |
| 112 | + |
| 113 | +* Now, test that the two nodes are connected by running the application. In your terminal, `cd` to the `/libp2p-go-simple-node/app` directory and run `go run .` |
| 114 | + |
| 115 | +You should see the following output, with the number of source node peers: |
| 116 | + |
| 117 | +```bash |
| 118 | +> go run . |
| 119 | +-- SOURCE NODE INFORMATION -- |
| 120 | +ID: 12D3KooWCGcgrrrfDwzLmNeZ25543kYcewKxXzgDkGJGNXw1ZUf3 |
| 121 | +Multiaddresses: /ip4/192.168.0.10/tcp/63678, /ip4/127.0.0.1/tcp/63678, /ip6/::1/tcp/63681 |
| 122 | +-- TARGET NODE INFORMATION -- |
| 123 | +ID: 12D3KooWLkzhtJxcSnasfzkXGQzgKGqxGtUDpACZSXt3HM4Rn3op |
| 124 | +Multiaddresses: /ip4/192.168.0.10/tcp/8007, /ip4/127.0.0.1/tcp/8007 |
| 125 | +Source node peers: 1 |
| 126 | +``` |
| 127 | + |
| 128 | +You can see an example of the [completed code here](https://github.com/protocol/launchpad-tutorials/blob/main/libp2p-go-simple-node/solution/main.go) |
| 129 | + |
| 130 | +Now that you have two nodes connected and communicating, you can start to implement the many [features available with libp2p](https://libp2p.io/). In a later tutorial, you will learn how to start a libp2p stream. |
0 commit comments