158 lines
3.6 KiB
Go
158 lines
3.6 KiB
Go
package main
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/base64"
|
|
"encoding/hex"
|
|
"fmt"
|
|
"os"
|
|
"text/tabwriter"
|
|
|
|
"github.com/ipfs/go-cid"
|
|
cbor "github.com/ipfs/go-ipld-cbor"
|
|
"github.com/ipld/go-car"
|
|
mh "github.com/multiformats/go-multihash"
|
|
"github.com/urfave/cli/v2"
|
|
cbg "github.com/whyrusleeping/cbor-gen"
|
|
"golang.org/x/xerrors"
|
|
|
|
"github.com/filecoin-project/go-state-types/abi"
|
|
|
|
"github.com/filecoin-project/lotus/blockstore"
|
|
"github.com/filecoin-project/lotus/chain/actors"
|
|
"github.com/filecoin-project/lotus/chain/actors/adt"
|
|
)
|
|
|
|
var cidCmd = &cli.Command{
|
|
Name: "cid",
|
|
Usage: "Cid command",
|
|
Subcommands: cli.Commands{
|
|
cidIdCmd,
|
|
inspectBundleCmd,
|
|
cborCid,
|
|
},
|
|
}
|
|
|
|
var cborCid = &cli.Command{
|
|
Name: "cbor",
|
|
Usage: "Serialize cid to cbor",
|
|
ArgsUsage: "[cid]",
|
|
Action: func(cctx *cli.Context) error {
|
|
c, err := cid.Decode(cctx.Args().First())
|
|
if err != nil {
|
|
return err
|
|
}
|
|
cbgc := cbg.CborCid(c)
|
|
buf := bytes.NewBuffer(make([]byte, 0))
|
|
cbgc.MarshalCBOR(buf)
|
|
fmt.Printf("%x\n", buf.Bytes())
|
|
return nil
|
|
},
|
|
}
|
|
|
|
var cidIdCmd = &cli.Command{
|
|
Name: "id",
|
|
Usage: "Create identity CID from hex or base64 data",
|
|
ArgsUsage: "[data]",
|
|
Flags: []cli.Flag{
|
|
&cli.StringFlag{
|
|
Name: "encoding",
|
|
Aliases: []string{"e"},
|
|
Value: "base64",
|
|
Usage: "specify input encoding to parse",
|
|
},
|
|
&cli.StringFlag{
|
|
Name: "codec",
|
|
Value: "id",
|
|
Usage: "multicodec-packed content types: abi or id",
|
|
},
|
|
},
|
|
Action: func(cctx *cli.Context) error {
|
|
if !cctx.Args().Present() {
|
|
return fmt.Errorf("must specify data")
|
|
}
|
|
|
|
var dec []byte
|
|
switch cctx.String("encoding") {
|
|
case "base64":
|
|
data, err := base64.StdEncoding.DecodeString(cctx.Args().First())
|
|
if err != nil {
|
|
return xerrors.Errorf("decoding base64 value: %w", err)
|
|
}
|
|
dec = data
|
|
case "hex", "x":
|
|
data, err := hex.DecodeString(cctx.Args().First())
|
|
if err != nil {
|
|
return xerrors.Errorf("decoding hex value: %w", err)
|
|
}
|
|
dec = data
|
|
case "raw", "r":
|
|
dec = []byte(cctx.Args().First())
|
|
default:
|
|
return xerrors.Errorf("unrecognized encoding: %s", cctx.String("encoding"))
|
|
}
|
|
|
|
switch cctx.String("codec") {
|
|
case "abi":
|
|
aCid, err := abi.CidBuilder.Sum(dec)
|
|
if err != nil {
|
|
return xerrors.Errorf("cidBuilder abi: %w", err)
|
|
}
|
|
fmt.Println(aCid)
|
|
case "id":
|
|
builder := cid.V1Builder{Codec: cid.Raw, MhType: mh.IDENTITY}
|
|
rCid, err := builder.Sum(dec)
|
|
if err != nil {
|
|
return xerrors.Errorf("cidBuilder raw: %w", err)
|
|
}
|
|
fmt.Println(rCid)
|
|
default:
|
|
return xerrors.Errorf("unrecognized codec: %s", cctx.String("codec"))
|
|
}
|
|
|
|
return nil
|
|
},
|
|
}
|
|
|
|
var inspectBundleCmd = &cli.Command{
|
|
Name: "inspect-bundle",
|
|
Usage: "Get the manifest CID from a car file, as well as the actor code CIDs",
|
|
ArgsUsage: "[path]",
|
|
Action: func(cctx *cli.Context) error {
|
|
ctx := cctx.Context
|
|
|
|
cf := cctx.Args().Get(0)
|
|
f, err := os.OpenFile(cf, os.O_RDONLY, 0664)
|
|
if err != nil {
|
|
return xerrors.Errorf("opening the car file: %w", err)
|
|
}
|
|
|
|
bs := blockstore.NewMemory()
|
|
wrapBs := adt.WrapStore(ctx, cbor.NewCborStore(bs))
|
|
|
|
hdr, err := car.LoadCar(ctx, bs, f)
|
|
if err != nil {
|
|
return xerrors.Errorf("error loading car file: %w", err)
|
|
}
|
|
|
|
manifestCid := hdr.Roots[0]
|
|
|
|
fmt.Printf("Manifest CID: %s\n", manifestCid.String())
|
|
|
|
entries, err := actors.ReadManifest(ctx, wrapBs, manifestCid)
|
|
if err != nil {
|
|
return xerrors.Errorf("error loading manifest: %w", err)
|
|
}
|
|
|
|
tw := tabwriter.NewWriter(os.Stdout, 2, 4, 2, ' ', 0)
|
|
_, _ = fmt.Fprintln(tw, "\nActor\tCID\t")
|
|
|
|
for name, cid := range entries {
|
|
_, _ = fmt.Fprintf(tw, "%v\t%v\n", name, cid)
|
|
|
|
}
|
|
|
|
return tw.Flush()
|
|
},
|
|
}
|