package main import ( "context" "fmt" "log" "os" "os/signal" "syscall" "time" libp2p "github.com/libp2p/go-libp2p" dht "github.com/libp2p/go-libp2p-kad-dht" "github.com/libp2p/go-libp2p/core/crypto" "github.com/libp2p/go-libp2p/core/host" ) func main() { ctx, cancel := context.WithCancel(context.Background()) defer cancel() priv, err := loadOrCreateKey("bootstrap.key") if err != nil { log.Fatal(err) } h, err := libp2p.New( libp2p.Identity(priv), libp2p.ListenAddrStrings( "/ip4/0.0.0.0/tcp/4001", ), ) if err != nil { log.Fatal(err) } kad, err := dht.New(ctx, h, dht.Mode(dht.ModeServer), dht.BootstrapPeers(), ) if err != nil { log.Fatal(err) } if err := kad.Bootstrap(ctx); err != nil { log.Fatal(err) } printAddrs(h) waitForSignal() } func loadOrCreateKey(path string) (crypto.PrivKey, error) { if data, err := os.ReadFile(path); err == nil { return crypto.UnmarshalPrivateKey(data) } priv, _, err := crypto.GenerateEd25519Key(nil) if err != nil { return nil, err } data, err := crypto.MarshalPrivateKey(priv) if err != nil { return nil, err } if err := os.WriteFile(path, data, 0600); err != nil { return nil, err } return priv, nil } func printAddrs(h host.Host) { fmt.Println("Bootstrap node started") fmt.Println("PeerID:", h.ID()) for _, a := range h.Addrs() { fmt.Printf("%s/p2p/%s\n", a, h.ID()) } } func waitForSignal() { ch := make(chan os.Signal, 1) signal.Notify(ch, syscall.SIGINT, syscall.SIGTERM) <-ch fmt.Println("Shutting down bootstrap node") time.Sleep(1 * time.Second) }