func main() { flag.Parse() switch flag.Arg(0) { case "GeneratePrivateKey": if len(flag.Args()) < 2 { fmt.Println("PEM file and alias required: gitchain GeneratePrivateKey <alias>") os.Exit(1) } var alias = flag.Arg(1) var resp api.GeneratePrivateKeyReply err := jsonrpc("KeyService.GeneratePrivateKey", &api.GeneratePrivateKeyArgs{Alias: alias}, &resp) if err != nil { fmt.Printf("Can't generate private key because of %v\n", err) os.Exit(1) } if resp.Success { fmt.Printf("Private key has been successfully generated with an alias of %s, the public address is %s\n", alias, resp.PublicKey) } else { fmt.Printf("Server can't generate the private key\n") os.Exit(1) } case "SetMainKey": if len(flag.Args()) < 2 { fmt.Println("Alias required: gitchain SetMainKey <alias>") os.Exit(1) } var alias = flag.Arg(1) var resp api.SetMainKeyReply err := jsonrpc("KeyService.SetMainKey", &api.SetMainKeyArgs{Alias: alias}, &resp) if err != nil { fmt.Printf("Can't set main private key to %s because of %v\n", alias, err) os.Exit(1) } if !resp.Success { fmt.Printf("Can't set main private key to %s (doesn't exist?)\n", alias) os.Exit(1) } fmt.Printf("Successfully set main private key to %s\n", alias) case "ListPrivateKeys": var resp api.ListPrivateKeysReply err := jsonrpc("KeyService.ListPrivateKeys", &api.ListPrivateKeysArgs{}, &resp) if err != nil { fmt.Printf("Can't list private keys because of %v\n", err) os.Exit(1) } var mainKeyResp api.GetMainKeyReply err = jsonrpc("KeyService.GetMainKey", &api.GetMainKeyArgs{}, &mainKeyResp) if err != nil { fmt.Printf("Can't discover main private key because of %v\n", err) os.Exit(1) } for i := range resp.Aliases { fmt.Printf("%s %s\n", func() string { if resp.Aliases[i] == mainKeyResp.Alias { return "*" } else { return " " } }(), resp.Aliases[i]) } case "NameReservation": if len(flag.Args()) < 3 { fmt.Println("Command format required: gitchain NameReservation <private key alias> <name>") os.Exit(1) } alias := flag.Arg(1) name := flag.Arg(2) var resp api.NameReservationReply err := jsonrpc("NameService.NameReservation", &api.NameReservationArgs{Alias: alias, Name: name}, &resp) if err != nil { fmt.Printf("Can't make a name reservation because of %v\n", err) os.Exit(1) } fmt.Printf("Name reservation for %s has been submitted (%s)\nRecord this random number for use during allocation: %s\n", name, resp.Id, resp.Random) case "NameAllocation": if len(flag.Args()) < 4 { fmt.Println("Command format required: gitchain NameReservation <private key alias> <name> <random>") os.Exit(1) } alias := flag.Arg(1) name := flag.Arg(2) random := flag.Arg(3) var resp api.NameAllocationReply err := jsonrpc("NameService.NameAllocation", &api.NameAllocationArgs{Alias: alias, Name: name, Random: random}, &resp) if err != nil { fmt.Printf("Can't make a name allocation because of %v\n", err) os.Exit(1) } fmt.Printf("Name allocation for %s has been submitted (%s)\n", name, resp.Id) case "LastBlock": var resp api.GetLastBlockReply err := jsonrpc("BlockService.GetLastBlock", &api.GetLastBlockArgs{}, &resp) if err != nil { fmt.Printf("Can't get a block because of %v\n", err) os.Exit(1) } fmt.Printf("%s\n", resp.Hash) case "Block": if len(flag.Args()) < 2 { fmt.Println("Command format required: gitchain Block <block hash>") os.Exit(1) } hash := flag.Arg(1) var resp api.GetBlockReply err := jsonrpc("BlockService.GetBlock", &api.GetBlockArgs{Hash: hash}, &resp) if err != nil { fmt.Printf("Can't get a block because of %v\n", err) os.Exit(1) } fmt.Printf("Previous block hash: %v\nMerkle root hash: %v\nTimestamp: %v\nBits: %#x\nNonce: %v\nTransactions: %d\n", hex.EncodeToString(resp.PreviousBlockHash), hex.EncodeToString(resp.MerkleRootHash), time.Unix(resp.Timestamp, 0).String(), resp.Bits, resp.Nonce, resp.NumTransactions) case "Transactions": if len(flag.Args()) < 2 { fmt.Println("Command format required: gitchain Transactions <block hash>") os.Exit(1) } hash := flag.Arg(1) var resp api.BlockTransactionsReply err := jsonrpc("BlockService.BlockTransactions", &api.BlockTransactionsArgs{Hash: hash}, &resp) if err != nil { fmt.Printf("Can't get a list of block transactions because of %v\n", err) os.Exit(1) } for i := range resp.Transactions { fmt.Println(resp.Transactions[i]) } case "Info": resp, err := http.Get(fmt.Sprintf("http://localhost:%d/info", env.Port)) if err != nil { fmt.Printf("Can't retrieve info because of %v\n", err) os.Exit(1) } defer resp.Body.Close() body, err := ioutil.ReadAll(resp.Body) if err != nil { fmt.Printf("Can't retrieve info because of %v\n", err) os.Exit(1) } fmt.Println(string(body)) case "Serve": fallthrough default: go server.MiningFactory() go server.TransactionListener() api.Start() } }
func main() { var configFile, dataPath, assets, netHostname string var httpPort, netPort int var alias, repo, random, hash, node string app := kingpin.New("gitchain", "Gitchain daemon and command line interface") app.Flag("config", "configuration file").Short('c').ExistingFileVar(&configFile) app.Flag("data-path", "path to the data directory").Short('d').StringVar(&dataPath) app.Flag("development-mode-assets", "path to the assets (ui) directory, only for developmenty").ExistingDirVar(&assets) app.Flag("net-hostname", "Gitchain network hostname").StringVar(&netHostname) app.Flag("http-port", "HTTTP port to connect to or listen on").IntVar(&httpPort) app.Flag("net-port", "Network port to listen").IntVar(&netPort) keypairGenerate := app.Command("keypair-generate", "Generates a new keypair") keypairGenerate.Arg("alias", "Keypair name to save it under").Required().StringVar(&alias) keypairPrimary := app.Command("keypair-primary", "Sets or gets primary keypair") keypairPrimary.Arg("alias", "Keypair name to save it under").StringVar(&alias) app.Command("keypair-list", "Lists all keypairs") nameReservation := app.Command("name-reservation", "Submits a Name Reservation Transaction") nameReservation.Arg("alias", "Keypair name to save it under").Required().StringVar(&alias) nameReservation.Arg("name", "Repository name to reserve").Required().StringVar(&repo) nameAllocation := app.Command("name-allocation", "Submits a Name Allocation Transaction") nameAllocation.Arg("alias", "Keypair name to save it under").Required().StringVar(&alias) nameAllocation.Arg("name", "Repository name to allocate").Required().StringVar(&repo) nameAllocation.Arg("random", "Random number returned by the name-reservation command").Required().StringVar(&random) app.Command("repo-list", "Lists all repositories") block := app.Command("block", "Renders a block") block.Arg("block", "Block hash").Required().StringVar(&hash) app.Command("block-last", "Returns last block hash") transactions := app.Command("transactions", "Returns a list of transactions in a block") transactions.Arg("block", "Block hash").Required().StringVar(&hash) transaction := app.Command("transaction", "Renders a transaction") transaction.Arg("txn", "Transaction hash").Required().StringVar(&hash) app.Command("info", "Returns gitchain node information") join := app.Command("node-join", "Connect to another node") join.Arg("node", "Node address <host:port>").Required().StringVar(&node) command := kingpin.MustParse(app.Parse(os.Args[1:])) var cfg *config.T var err error cfg = config.Default() cfg.General.DataPath = dataPath if httpPort != 0 { cfg.API.HttpPort = httpPort } cfg.API.DevelopmentModeAssets = assets cfg.Network.Hostname = netHostname if netPort != 0 { cfg.Network.Port = netPort } if len(configFile) > 0 { err = config.ReadFile(configFile, cfg) if err != nil { log.Printf("Error read config file %s: %v", configFile, err) // don't use log15 here os.Exit(1) } } switch command { case "keypair-generate": var resp api.GeneratePrivateKeyReply err := jsonrpc(cfg, "KeyService.GeneratePrivateKey", &api.GeneratePrivateKeyArgs{Alias: alias}, &resp) if err != nil { fmt.Printf("Can't generate private key because of %v\n", err) os.Exit(1) } if resp.Success { fmt.Printf("Private key has been successfully generated with an alias of %s, the public address is %s\n", alias, resp.PublicKey) } else { fmt.Printf("Server can't generate the private key\n") os.Exit(1) } case "keypair-primary": if alias != "" { var resp api.SetMainKeyReply err := jsonrpc(cfg, "KeyService.SetMainKey", &api.SetMainKeyArgs{Alias: alias}, &resp) if err != nil { fmt.Printf("Can't set main private key to %s because of %v\n", alias, err) os.Exit(1) } if !resp.Success { fmt.Printf("Can't set main private key to %s (doesn't exist?)\n", alias) os.Exit(1) } fmt.Printf("Successfully set main private key to %s\n", alias) } else { var mainKeyResp api.GetMainKeyReply err = jsonrpc(cfg, "KeyService.GetMainKey", &api.GetMainKeyArgs{}, &mainKeyResp) if err != nil { fmt.Printf("Can't discover main private key because of %v\n", err) os.Exit(1) } fmt.Println(mainKeyResp.Alias) } case "keypair-list": var resp api.ListPrivateKeysReply err := jsonrpc(cfg, "KeyService.ListPrivateKeys", &api.ListPrivateKeysArgs{}, &resp) if err != nil { fmt.Printf("Can't list private keys because of %v\n", err) os.Exit(1) } var mainKeyResp api.GetMainKeyReply err = jsonrpc(cfg, "KeyService.GetMainKey", &api.GetMainKeyArgs{}, &mainKeyResp) if err != nil { fmt.Printf("Can't discover main private key because of %v\n", err) os.Exit(1) } for i := range resp.Aliases { fmt.Printf("%s %s\n", func() string { if resp.Aliases[i] == mainKeyResp.Alias { return "*" } else { return " " } }(), resp.Aliases[i]) } case "name-reservation": var resp api.NameReservationReply err := jsonrpc(cfg, "NameService.NameReservation", &api.NameReservationArgs{Alias: alias, Name: repo}, &resp) if err != nil { fmt.Printf("Can't make a name reservation because of %v\n", err) os.Exit(1) } fmt.Printf("Name reservation for %s has been submitted (%s)\nRecord the above transaction hash and following random number for use during allocation: %s\n", repo, resp.Id, resp.Random) case "name-allocation": var resp api.NameAllocationReply err := jsonrpc(cfg, "NameService.NameAllocation", &api.NameAllocationArgs{Alias: alias, Name: repo, Random: random}, &resp) if err != nil { fmt.Printf("Can't make a name allocation because of %v\n", err) os.Exit(1) } fmt.Printf("Name allocation for %s has been submitted (%s)\n", repo, resp.Id) case "repo-list": var resp api.ListRepositoriesReply err := jsonrpc(cfg, "RepositoryService.ListRepositories", &api.ListRepositoriesArgs{}, &resp) if err != nil { fmt.Printf("Can't list repositories because of %v\n", err) os.Exit(1) } for i := range resp.Repositories { fmt.Printf("%s %s %s\n", resp.Repositories[i].Name, resp.Repositories[i].Status, resp.Repositories[i].NameAllocationTx) } case "block-last": var resp api.GetLastBlockReply err := jsonrpc(cfg, "BlockService.GetLastBlock", &api.GetLastBlockArgs{}, &resp) if err != nil { fmt.Printf("Can't get a block because of %v\n", err) os.Exit(1) } fmt.Printf("%s\n", resp.Hash) case "block": var resp api.GetBlockReply err := jsonrpc(cfg, "BlockService.GetBlock", &api.GetBlockArgs{Hash: hash}, &resp) if err != nil { fmt.Printf("Can't get a block because of %v\n", err) os.Exit(1) } fmt.Printf("Previous block hash: %v\nNext block hash: %v\nMerkle root hash: %v\nTimestamp: %v\nBits: %#x\nNonce: %v\nTransactions: %d\n", resp.PreviousBlockHash, resp.NextBlockHash, resp.MerkleRootHash, time.Unix(resp.Timestamp, 0).String(), resp.Bits, resp.Nonce, resp.NumTransactions) case "transactions": var resp api.BlockTransactionsReply err := jsonrpc(cfg, "BlockService.BlockTransactions", &api.BlockTransactionsArgs{Hash: hash}, &resp) if err != nil { fmt.Printf("Can't get a list of block transactions because of %v\n", err) os.Exit(1) } for i := range resp.Transactions { fmt.Println(resp.Transactions[i]) } case "transaction": var resp api.GetTransactionReply err := jsonrpc(cfg, "TransactionService.GetTransaction", &api.GetTransactionArgs{Hash: hash}, &resp) if err != nil { fmt.Printf("Can't get a transaction because of %v\n", err) os.Exit(1) } fmt.Printf("Previous transaction hash: %v\nPublic key: %v\nNext public key: %v\nValid: %v\n%+v\n", resp.PreviousTransactionHash, resp.PublicKey, resp.NextPublicKey, resp.Valid, resp.Content) case "info": resp, err := http.Get(fmt.Sprintf("http://localhost:%d/info", cfg.API.HttpPort)) if err != nil { fmt.Printf("Can't retrieve info because of %v\n", err) os.Exit(1) } defer resp.Body.Close() body, err := ioutil.ReadAll(resp.Body) if err != nil { fmt.Printf("Can't retrieve info because of %v\n", err) os.Exit(1) } fmt.Println(string(body)) case "join": var resp api.JoinReply err := jsonrpc(cfg, "NetService.Join", &api.JoinArgs{Host: node}, &resp) if err != nil { fmt.Printf("Can't join because of %v\n", err) os.Exit(1) } default: srv := &context.T{Config: cfg} err := srv.Init() if err != nil { log.Printf("Error during server initialization: %v", err) // don't use log15 here os.Exit(1) } go netserver.Server(srv) go server.NameRegistrar(srv) go server.RepositoryServer(srv) go server.MiningFactory(srv) go server.TransactionListener(srv) httpserver.Server(srv) } }