code: func (n *Network) JoinChannel(name string, o *Orderer, peers ...*Peer) {
  	if len(peers) == 0 {
  		return
  	}
  
  	tempFile, err := ioutil.TempFile("", "genesis-block")
  	Expect(err).NotTo(HaveOccurred())
  	tempFile.Close()
  	defer os.Remove(tempFile.Name())
  
  	sess, err := n.PeerAdminSession(peers[0], commands.ChannelFetch{
  		Block:      "0",
  		ChannelID:  name,
  		Orderer:    n.OrdererAddress(o, ListenPort),
  		OutputFile: tempFile.Name(),
  	})
  	Expect(err).NotTo(HaveOccurred())
  	Eventually(sess, n.EventuallyTimeout).Should(gexec.Exit(0))
  
  	for _, p := range peers {
  		sess, err := n.PeerAdminSession(p, commands.ChannelJoin{
  			BlockPath: tempFile.Name(),
  		})
  		Expect(err).NotTo(HaveOccurred())
  		Eventually(sess, n.EventuallyTimeout).Should(gexec.Exit(0))
  	}
  }
docs: // JoinChannel will join peers to the specified channel. The orderer is used to
  // obtain the current configuration block for the channel.
  //
  // The orderer and listed peers must be running before this is called.