Using Go-IPFS Programmatically

Can you guys answer this question?

You’re probably better off using the go-ipfs-api for what you want:

If you want some examples on working with IPFS using Golang, feel free to check out these folders of my project:
https://github.com/RTradeLtd/Temporal/tree/V2/rtfs
https://github.com/RTradeLtd/Temporal/tree/V2/rtfs_cluster
https://github.com/RTradeLtd/Temporal/tree/V2/rtfsp
https://github.com/RTradeLtd/Temporal/tree/V2/rtns

@postables Thank you very much for your help, however I really don’t like the API that’s the reason I am asking the question in the first place. I don’t want to be forced in this client-server architecture and I don’t understand why the want to do this to us. I want to be able to decide myself how to design my systems.

1 Like

You’re doing the same thing right now that you would be doing with go-ipfs-api and running ipfs-daemon. I’m not sure how they are forcing us into a client server architecture? IPFS is a fairly intricate system, and IMO at least you’re better off using go-ipfs-api and play around with the IPFS daemon, then moving onto stuff like this.

Here you are starting a node

   node, err := core.NewNode(ctx, &core.BuildCfg{})
    if err != nil {
        log.Fatalf("Failed to start IPFS node: %v", err)
    }

And here you are running the cat command

    reader, err := coreunix.Cat(ctx, node, "QmPZ9gcCEpqKTo6aq61g2nXGUhM4iCL3ewB6LDXZCtioEB")
    if err != nil {
        log.Fatalf("Failed to look up IPFS welcome page: %v", err)
    }

Even in your own stack overflow post you mention wanting to basically re-do the same thing the ipfs-daemon does. I’m not sure why you would want to do this, as go-ipfs and the ipfs-daemon already handle all of this heavy lifting for you. You can simply run your own ipfs-daemon on your node, and have your golang program use go-ipfs-api to talk to it, rather than build your node dynamically the way you are now, and then talking to it.

EDIT: To answer some of your questions

Whenever you add a file to IPFS, the bitswap agent will search through a “want list” which is a list of blocks that your node wants. I believe it initially adds the file into memory, however you may want someone else to clear that part up.

As for your question on the differences of context that is more focused on Golang as opposed to IPFS https://siadat.github.io/post/context

I lightly annotated some of the function calls here

func addFile(ctx *context.Context, node *core.IpfsNode, path *string) error {
    file, err := os.Open(*path) <-- here we are opening up a file from disk
    if err != nil {
        return err
    }
    adder, err := coreunix.NewAdder(*ctx, node.Pinning, node.Blockstore, node.DAG) <- here we creating a method utilizing a blockstore which will allow us to store, and pin blocks
    if err != nil {
        return err
    }
    filename := filepath.Base(*path)
    fileReader := files.NewReaderFile(filename, filename, file, nil)
    adder.AddFile(fileReader) <-- here we are adding the file to our repo
    adder.PinRoot() <-- here we are pinning the root node
    return nil
}

I took a look at the function AddFile which in turn calls addFile and IIRC it streams the file into memory where it gets chunked and hashed before being flushed to disk as it chunks and hashes although someone else might want to clarify this:

IPFS is pretty undocumented right now (but you can help with that! :D) I gathered some quick godoc links that will help to look at code to get a better understanding of the system to do what you’re doing:


https://godoc.org/github.com/ipfs/go-ipfs/core/coredag
https://godoc.org/github.com/ipfs/go-ipfs/core/corerepo