github.com/yinchengtsinghua/golang-Eos-dpos-Ethereum@v0.0.0-20190121132951-92cc4225ed8e/cmd/swarm/main.go (about)

     1  
     2  //此源码被清华学神尹成大魔王专业翻译分析并修改
     3  //尹成QQ77025077
     4  //尹成微信18510341407
     5  //尹成所在QQ群721929980
     6  //尹成邮箱 yinc13@mails.tsinghua.edu.cn
     7  //尹成毕业于清华大学,微软区块链领域全球最有价值专家
     8  //https://mvp.microsoft.com/zh-cn/PublicProfile/4033620
     9  //版权所有2016 Go Ethereum作者
    10  //此文件是Go以太坊的一部分。
    11  //
    12  //Go以太坊是免费软件:您可以重新发布和/或修改它
    13  //根据GNU通用公共许可证的条款
    14  //自由软件基金会,或者许可证的第3版,或者
    15  //(由您选择)任何更高版本。
    16  //
    17  //Go以太坊的分布希望它会有用,
    18  //但没有任何保证;甚至没有
    19  //适销性或特定用途的适用性。见
    20  //GNU通用公共许可证了解更多详细信息。
    21  //
    22  //你应该已经收到一份GNU通用公共许可证的副本
    23  //一起去以太坊吧。如果没有,请参见<http://www.gnu.org/licenses/>。
    24  
    25  package main
    26  
    27  import (
    28  	"crypto/ecdsa"
    29  	"fmt"
    30  	"io/ioutil"
    31  	"os"
    32  	"os/signal"
    33  	"runtime"
    34  	"sort"
    35  	"strconv"
    36  	"strings"
    37  	"syscall"
    38  
    39  	"github.com/ethereum/go-ethereum/accounts"
    40  	"github.com/ethereum/go-ethereum/accounts/keystore"
    41  	"github.com/ethereum/go-ethereum/cmd/utils"
    42  	"github.com/ethereum/go-ethereum/common"
    43  	"github.com/ethereum/go-ethereum/console"
    44  	"github.com/ethereum/go-ethereum/crypto"
    45  	"github.com/ethereum/go-ethereum/internal/debug"
    46  	"github.com/ethereum/go-ethereum/log"
    47  	"github.com/ethereum/go-ethereum/node"
    48  	"github.com/ethereum/go-ethereum/p2p/discover"
    49  	"github.com/ethereum/go-ethereum/swarm"
    50  	bzzapi "github.com/ethereum/go-ethereum/swarm/api"
    51  	swarmmetrics "github.com/ethereum/go-ethereum/swarm/metrics"
    52  	"github.com/ethereum/go-ethereum/swarm/tracing"
    53  	sv "github.com/ethereum/go-ethereum/swarm/version"
    54  
    55  	"gopkg.in/urfave/cli.v1"
    56  )
    57  
    58  const clientIdentifier = "swarm"
    59  const helpTemplate = `NAME:
    60  {{.HelpName}} - {{.Usage}}
    61  
    62  USAGE:
    63  {{if .UsageText}}{{.UsageText}}{{else}}{{.HelpName}}{{if .VisibleFlags}} [command options]{{end}} {{if .ArgsUsage}}{{.ArgsUsage}}{{else}}[arguments...]{{end}}{{end}}{{if .Category}}
    64  
    65  CATEGORY:
    66  {{.Category}}{{end}}{{if .Description}}
    67  
    68  DESCRIPTION:
    69  {{.Description}}{{end}}{{if .VisibleFlags}}
    70  
    71  OPTIONS:
    72  {{range .VisibleFlags}}{{.}}
    73  {{end}}{{end}}
    74  `
    75  
    76  var (
    77  gitCommit string //git sha1提交发布的哈希(通过链接器标志设置)
    78  )
    79  
    80  var (
    81  	ChequebookAddrFlag = cli.StringFlag{
    82  		Name:   "chequebook",
    83  		Usage:  "chequebook contract address",
    84  		EnvVar: SWARM_ENV_CHEQUEBOOK_ADDR,
    85  	}
    86  	SwarmAccountFlag = cli.StringFlag{
    87  		Name:   "bzzaccount",
    88  		Usage:  "Swarm account key file",
    89  		EnvVar: SWARM_ENV_ACCOUNT,
    90  	}
    91  	SwarmListenAddrFlag = cli.StringFlag{
    92  		Name:   "httpaddr",
    93  		Usage:  "Swarm HTTP API listening interface",
    94  		EnvVar: SWARM_ENV_LISTEN_ADDR,
    95  	}
    96  	SwarmPortFlag = cli.StringFlag{
    97  		Name:   "bzzport",
    98  		Usage:  "Swarm local http api port",
    99  		EnvVar: SWARM_ENV_PORT,
   100  	}
   101  	SwarmNetworkIdFlag = cli.IntFlag{
   102  		Name:   "bzznetworkid",
   103  		Usage:  "Network identifier (integer, default 3=swarm testnet)",
   104  		EnvVar: SWARM_ENV_NETWORK_ID,
   105  	}
   106  	SwarmSwapEnabledFlag = cli.BoolFlag{
   107  		Name:   "swap",
   108  		Usage:  "Swarm SWAP enabled (default false)",
   109  		EnvVar: SWARM_ENV_SWAP_ENABLE,
   110  	}
   111  	SwarmSwapAPIFlag = cli.StringFlag{
   112  		Name:   "swap-api",
   113  		Usage:  "URL of the Ethereum API provider to use to settle SWAP payments",
   114  		EnvVar: SWARM_ENV_SWAP_API,
   115  	}
   116  	SwarmSyncDisabledFlag = cli.BoolTFlag{
   117  		Name:   "nosync",
   118  		Usage:  "Disable swarm syncing",
   119  		EnvVar: SWARM_ENV_SYNC_DISABLE,
   120  	}
   121  	SwarmSyncUpdateDelay = cli.DurationFlag{
   122  		Name:   "sync-update-delay",
   123  		Usage:  "Duration for sync subscriptions update after no new peers are added (default 15s)",
   124  		EnvVar: SWARM_ENV_SYNC_UPDATE_DELAY,
   125  	}
   126  	SwarmLightNodeEnabled = cli.BoolFlag{
   127  		Name:   "lightnode",
   128  		Usage:  "Enable Swarm LightNode (default false)",
   129  		EnvVar: SWARM_ENV_LIGHT_NODE_ENABLE,
   130  	}
   131  	SwarmDeliverySkipCheckFlag = cli.BoolFlag{
   132  		Name:   "delivery-skip-check",
   133  		Usage:  "Skip chunk delivery check (default false)",
   134  		EnvVar: SWARM_ENV_DELIVERY_SKIP_CHECK,
   135  	}
   136  	EnsAPIFlag = cli.StringSliceFlag{
   137  		Name:   "ens-api",
   138  		Usage:  "ENS API endpoint for a TLD and with contract address, can be repeated, format [tld:][contract-addr@]url",
   139  		EnvVar: SWARM_ENV_ENS_API,
   140  	}
   141  	SwarmApiFlag = cli.StringFlag{
   142  		Name:  "bzzapi",
   143  		Usage: "Swarm HTTP endpoint",
   144  Value: "http://
   145  	}
   146  	SwarmRecursiveFlag = cli.BoolFlag{
   147  		Name:  "recursive",
   148  		Usage: "Upload directories recursively",
   149  	}
   150  	SwarmWantManifestFlag = cli.BoolTFlag{
   151  		Name:  "manifest",
   152  		Usage: "Automatic manifest upload (default true)",
   153  	}
   154  	SwarmUploadDefaultPath = cli.StringFlag{
   155  		Name:  "defaultpath",
   156  		Usage: "path to file served for empty url path (none)",
   157  	}
   158  	SwarmAccessGrantKeyFlag = cli.StringFlag{
   159  		Name:  "grant-key",
   160  		Usage: "grants a given public key access to an ACT",
   161  	}
   162  	SwarmAccessGrantKeysFlag = cli.StringFlag{
   163  		Name:  "grant-keys",
   164  		Usage: "grants a given list of public keys in the following file (separated by line breaks) access to an ACT",
   165  	}
   166  	SwarmUpFromStdinFlag = cli.BoolFlag{
   167  		Name:  "stdin",
   168  		Usage: "reads data to be uploaded from stdin",
   169  	}
   170  	SwarmUploadMimeType = cli.StringFlag{
   171  		Name:  "mime",
   172  		Usage: "Manually specify MIME type",
   173  	}
   174  	SwarmEncryptedFlag = cli.BoolFlag{
   175  		Name:  "encrypt",
   176  		Usage: "use encrypted upload",
   177  	}
   178  	SwarmAccessPasswordFlag = cli.StringFlag{
   179  		Name:   "password",
   180  		Usage:  "Password",
   181  		EnvVar: SWARM_ACCESS_PASSWORD,
   182  	}
   183  	SwarmDryRunFlag = cli.BoolFlag{
   184  		Name:  "dry-run",
   185  		Usage: "dry-run",
   186  	}
   187  	CorsStringFlag = cli.StringFlag{
   188  		Name:   "corsdomain",
   189  		Usage:  "Domain on which to send Access-Control-Allow-Origin header (multiple domains can be supplied separated by a ',')",
   190  		EnvVar: SWARM_ENV_CORS,
   191  	}
   192  	SwarmStorePath = cli.StringFlag{
   193  		Name:   "store.path",
   194  		Usage:  "Path to leveldb chunk DB (default <$GETH_ENV_DIR>/swarm/bzz-<$BZZ_KEY>/chunks)",
   195  		EnvVar: SWARM_ENV_STORE_PATH,
   196  	}
   197  	SwarmStoreCapacity = cli.Uint64Flag{
   198  		Name:   "store.size",
   199  		Usage:  "Number of chunks (5M is roughly 20-25GB) (default 5000000)",
   200  		EnvVar: SWARM_ENV_STORE_CAPACITY,
   201  	}
   202  	SwarmStoreCacheCapacity = cli.UintFlag{
   203  		Name:   "store.cache.size",
   204  		Usage:  "Number of recent chunks cached in memory (default 5000)",
   205  		EnvVar: SWARM_ENV_STORE_CACHE_CAPACITY,
   206  	}
   207  	SwarmResourceMultihashFlag = cli.BoolFlag{
   208  		Name:  "multihash",
   209  		Usage: "Determines how to interpret data for a resource update. If not present, data will be interpreted as raw, literal data that will be included in the resource",
   210  	}
   211  	SwarmResourceNameFlag = cli.StringFlag{
   212  		Name:  "name",
   213  		Usage: "User-defined name for the new resource",
   214  	}
   215  	SwarmResourceDataOnCreateFlag = cli.StringFlag{
   216  		Name:  "data",
   217  		Usage: "Initializes the resource with the given hex-encoded data. Data must be prefixed by 0x",
   218  	}
   219  )
   220  
   221  //声明几个常量错误消息,对以后测试中的错误检查比较很有用
   222  var (
   223  	SWARM_ERR_NO_BZZACCOUNT   = "bzzaccount option is required but not set; check your config file, command line or environment variables"
   224  	SWARM_ERR_SWAP_SET_NO_API = "SWAP is enabled but --swap-api is not set"
   225  )
   226  
   227  //
   228  var defaultSubcommandHelp = cli.Command{
   229  	Action:             func(ctx *cli.Context) { cli.ShowCommandHelpAndExit(ctx, "", 1) },
   230  	CustomHelpTemplate: helpTemplate,
   231  	Name:               "help",
   232  	Usage:              "shows this help",
   233  	Hidden:             true,
   234  }
   235  
   236  var defaultNodeConfig = node.DefaultConfig
   237  
   238  //
   239  func init() {
   240  	defaultNodeConfig.Name = clientIdentifier
   241  	defaultNodeConfig.Version = sv.VersionWithCommit(gitCommit)
   242  	defaultNodeConfig.P2P.ListenAddr = ":30399"
   243  	defaultNodeConfig.IPCPath = "bzzd.ipc"
   244  //
   245  	utils.ListenPortFlag.Value = 30399
   246  }
   247  
   248  var app = utils.NewApp(gitCommit, "Ethereum Swarm")
   249  
   250  //这个init函数创建cli.app。
   251  func init() {
   252  	app.Action = bzzd
   253  app.HideVersion = true //我们有打印版本的命令
   254  	app.Copyright = "Copyright 2013-2016 The go-ethereum Authors"
   255  	app.Commands = []cli.Command{
   256  		{
   257  			Action:             version,
   258  			CustomHelpTemplate: helpTemplate,
   259  			Name:               "version",
   260  			Usage:              "Print version numbers",
   261  			Description:        "The output of this command is supposed to be machine-readable",
   262  		},
   263  		{
   264  			Action:             upload,
   265  			CustomHelpTemplate: helpTemplate,
   266  			Name:               "up",
   267  			Usage:              "uploads a file or directory to swarm using the HTTP API",
   268  			ArgsUsage:          "<file>",
   269  			Flags:              []cli.Flag{SwarmEncryptedFlag},
   270  			Description:        "uploads a file or directory to swarm using the HTTP API and prints the root hash",
   271  		},
   272  		{
   273  			CustomHelpTemplate: helpTemplate,
   274  			Name:               "access",
   275  			Usage:              "encrypts a reference and embeds it into a root manifest",
   276  			ArgsUsage:          "<ref>",
   277  			Description:        "encrypts a reference and embeds it into a root manifest",
   278  			Subcommands: []cli.Command{
   279  				{
   280  					CustomHelpTemplate: helpTemplate,
   281  					Name:               "new",
   282  					Usage:              "encrypts a reference and embeds it into a root manifest",
   283  					ArgsUsage:          "<ref>",
   284  					Description:        "encrypts a reference and embeds it into a root access manifest and prints the resulting manifest",
   285  					Subcommands: []cli.Command{
   286  						{
   287  							Action:             accessNewPass,
   288  							CustomHelpTemplate: helpTemplate,
   289  							Flags: []cli.Flag{
   290  								utils.PasswordFileFlag,
   291  								SwarmDryRunFlag,
   292  							},
   293  							Name:        "pass",
   294  							Usage:       "encrypts a reference with a password and embeds it into a root manifest",
   295  							ArgsUsage:   "<ref>",
   296  							Description: "encrypts a reference and embeds it into a root access manifest and prints the resulting manifest",
   297  						},
   298  						{
   299  							Action:             accessNewPK,
   300  							CustomHelpTemplate: helpTemplate,
   301  							Flags: []cli.Flag{
   302  								utils.PasswordFileFlag,
   303  								SwarmDryRunFlag,
   304  								SwarmAccessGrantKeyFlag,
   305  							},
   306  							Name:        "pk",
   307  							Usage:       "encrypts a reference with the node's private key and a given grantee's public key and embeds it into a root manifest",
   308  							ArgsUsage:   "<ref>",
   309  							Description: "encrypts a reference and embeds it into a root access manifest and prints the resulting manifest",
   310  						},
   311  						{
   312  							Action:             accessNewACT,
   313  							CustomHelpTemplate: helpTemplate,
   314  							Flags: []cli.Flag{
   315  								SwarmAccessGrantKeysFlag,
   316  								SwarmDryRunFlag,
   317  							},
   318  							Name:        "act",
   319  							Usage:       "encrypts a reference with the node's private key and a given grantee's public key and embeds it into a root manifest",
   320  							ArgsUsage:   "<ref>",
   321  							Description: "encrypts a reference and embeds it into a root access manifest and prints the resulting manifest",
   322  						},
   323  					},
   324  				},
   325  			},
   326  		},
   327  		{
   328  			CustomHelpTemplate: helpTemplate,
   329  			Name:               "resource",
   330  			Usage:              "(Advanced) Create and update Mutable Resources",
   331  			ArgsUsage:          "<create|update|info>",
   332  			Description:        "Works with Mutable Resource Updates",
   333  			Subcommands: []cli.Command{
   334  				{
   335  					Action:             resourceCreate,
   336  					CustomHelpTemplate: helpTemplate,
   337  					Name:               "create",
   338  					Usage:              "creates a new Mutable Resource",
   339  					ArgsUsage:          "<frequency>",
   340  					Description:        "creates a new Mutable Resource",
   341  					Flags:              []cli.Flag{SwarmResourceNameFlag, SwarmResourceDataOnCreateFlag, SwarmResourceMultihashFlag},
   342  				},
   343  				{
   344  					Action:             resourceUpdate,
   345  					CustomHelpTemplate: helpTemplate,
   346  					Name:               "update",
   347  					Usage:              "updates the content of an existing Mutable Resource",
   348  					ArgsUsage:          "<Manifest Address or ENS domain> <0x Hex data>",
   349  					Description:        "updates the content of an existing Mutable Resource",
   350  					Flags:              []cli.Flag{SwarmResourceMultihashFlag},
   351  				},
   352  				{
   353  					Action:             resourceInfo,
   354  					CustomHelpTemplate: helpTemplate,
   355  					Name:               "info",
   356  					Usage:              "obtains information about an existing Mutable Resource",
   357  					ArgsUsage:          "<Manifest Address or ENS domain>",
   358  					Description:        "obtains information about an existing Mutable Resource",
   359  				},
   360  			},
   361  		},
   362  		{
   363  			Action:             list,
   364  			CustomHelpTemplate: helpTemplate,
   365  			Name:               "ls",
   366  			Usage:              "list files and directories contained in a manifest",
   367  			ArgsUsage:          "<manifest> [<prefix>]",
   368  			Description:        "Lists files and directories contained in a manifest",
   369  		},
   370  		{
   371  			Action:             hash,
   372  			CustomHelpTemplate: helpTemplate,
   373  			Name:               "hash",
   374  			Usage:              "print the swarm hash of a file or directory",
   375  			ArgsUsage:          "<file>",
   376  			Description:        "Prints the swarm hash of file or directory",
   377  		},
   378  		{
   379  			Action:      download,
   380  			Name:        "down",
   381  			Flags:       []cli.Flag{SwarmRecursiveFlag, SwarmAccessPasswordFlag},
   382  			Usage:       "downloads a swarm manifest or a file inside a manifest",
   383  			ArgsUsage:   " <uri> [<dir>]",
   384  			Description: `Downloads a swarm bzz uri to the given dir. When no dir is provided, working directory is assumed. --recursive flag is expected when downloading a manifest with multiple entries.`,
   385  		},
   386  		{
   387  			Name:               "manifest",
   388  			CustomHelpTemplate: helpTemplate,
   389  			Usage:              "perform operations on swarm manifests",
   390  			ArgsUsage:          "COMMAND",
   391  			Description:        "Updates a MANIFEST by adding/removing/updating the hash of a path.\nCOMMAND could be: add, update, remove",
   392  			Subcommands: []cli.Command{
   393  				{
   394  					Action:             manifestAdd,
   395  					CustomHelpTemplate: helpTemplate,
   396  					Name:               "add",
   397  					Usage:              "add a new path to the manifest",
   398  					ArgsUsage:          "<MANIFEST> <path> <hash>",
   399  					Description:        "Adds a new path to the manifest",
   400  				},
   401  				{
   402  					Action:             manifestUpdate,
   403  					CustomHelpTemplate: helpTemplate,
   404  					Name:               "update",
   405  					Usage:              "update the hash for an already existing path in the manifest",
   406  					ArgsUsage:          "<MANIFEST> <path> <newhash>",
   407  					Description:        "Update the hash for an already existing path in the manifest",
   408  				},
   409  				{
   410  					Action:             manifestRemove,
   411  					CustomHelpTemplate: helpTemplate,
   412  					Name:               "remove",
   413  					Usage:              "removes a path from the manifest",
   414  					ArgsUsage:          "<MANIFEST> <path>",
   415  					Description:        "Removes a path from the manifest",
   416  				},
   417  			},
   418  		},
   419  		{
   420  			Name:               "fs",
   421  			CustomHelpTemplate: helpTemplate,
   422  			Usage:              "perform FUSE operations",
   423  			ArgsUsage:          "fs COMMAND",
   424  			Description:        "Performs FUSE operations by mounting/unmounting/listing mount points. This assumes you already have a Swarm node running locally. For all operation you must reference the correct path to bzzd.ipc in order to communicate with the node",
   425  			Subcommands: []cli.Command{
   426  				{
   427  					Action:             mount,
   428  					CustomHelpTemplate: helpTemplate,
   429  					Name:               "mount",
   430  					Flags:              []cli.Flag{utils.IPCPathFlag},
   431  					Usage:              "mount a swarm hash to a mount point",
   432  					ArgsUsage:          "swarm fs mount --ipcpath <path to bzzd.ipc> <manifest hash> <mount point>",
   433  					Description:        "Mounts a Swarm manifest hash to a given mount point. This assumes you already have a Swarm node running locally. You must reference the correct path to your bzzd.ipc file",
   434  				},
   435  				{
   436  					Action:             unmount,
   437  					CustomHelpTemplate: helpTemplate,
   438  					Name:               "unmount",
   439  					Flags:              []cli.Flag{utils.IPCPathFlag},
   440  					Usage:              "unmount a swarmfs mount",
   441  					ArgsUsage:          "swarm fs unmount --ipcpath <path to bzzd.ipc> <mount point>",
   442  					Description:        "Unmounts a swarmfs mount residing at <mount point>. This assumes you already have a Swarm node running locally. You must reference the correct path to your bzzd.ipc file",
   443  				},
   444  				{
   445  					Action:             listMounts,
   446  					CustomHelpTemplate: helpTemplate,
   447  					Name:               "list",
   448  					Flags:              []cli.Flag{utils.IPCPathFlag},
   449  					Usage:              "list swarmfs mounts",
   450  					ArgsUsage:          "swarm fs list --ipcpath <path to bzzd.ipc>",
   451  					Description:        "Lists all mounted swarmfs volumes. This assumes you already have a Swarm node running locally. You must reference the correct path to your bzzd.ipc file",
   452  				},
   453  			},
   454  		},
   455  		{
   456  			Name:               "db",
   457  			CustomHelpTemplate: helpTemplate,
   458  			Usage:              "manage the local chunk database",
   459  			ArgsUsage:          "db COMMAND",
   460  			Description:        "Manage the local chunk database",
   461  			Subcommands: []cli.Command{
   462  				{
   463  					Action:             dbExport,
   464  					CustomHelpTemplate: helpTemplate,
   465  					Name:               "export",
   466  					Usage:              "export a local chunk database as a tar archive (use - to send to stdout)",
   467  					ArgsUsage:          "<chunkdb> <file>",
   468  					Description: `
   469  Export a local chunk database as a tar archive (use - to send to stdout).
   470  
   471      swarm db export ~/.ethereum/swarm/bzz-KEY/chunks chunks.tar
   472  
   473  The export may be quite large, consider piping the output through the Unix
   474  pv(1) tool to get a progress bar:
   475  
   476      swarm db export ~/.ethereum/swarm/bzz-KEY/chunks - | pv > chunks.tar
   477  `,
   478  				},
   479  				{
   480  					Action:             dbImport,
   481  					CustomHelpTemplate: helpTemplate,
   482  					Name:               "import",
   483  					Usage:              "import chunks from a tar archive into a local chunk database (use - to read from stdin)",
   484  					ArgsUsage:          "<chunkdb> <file>",
   485  					Description: `Import chunks from a tar archive into a local chunk database (use - to read from stdin).
   486  
   487      swarm db import ~/.ethereum/swarm/bzz-KEY/chunks chunks.tar
   488  
   489  The import may be quite large, consider piping the input through the Unix
   490  pv(1) tool to get a progress bar:
   491  
   492      pv chunks.tar | swarm db import ~/.ethereum/swarm/bzz-KEY/chunks -`,
   493  				},
   494  				{
   495  					Action:             dbClean,
   496  					CustomHelpTemplate: helpTemplate,
   497  					Name:               "clean",
   498  					Usage:              "remove corrupt entries from a local chunk database",
   499  					ArgsUsage:          "<chunkdb>",
   500  					Description:        "Remove corrupt entries from a local chunk database",
   501  				},
   502  			},
   503  		},
   504  
   505  //参见CONG.GO
   506  		DumpConfigCommand,
   507  	}
   508  
   509  //
   510  //
   511  	addDefaultHelpSubcommands(app.Commands)
   512  
   513  	sort.Sort(cli.CommandsByName(app.Commands))
   514  
   515  	app.Flags = []cli.Flag{
   516  		utils.IdentityFlag,
   517  		utils.DataDirFlag,
   518  		utils.BootnodesFlag,
   519  		utils.KeyStoreDirFlag,
   520  		utils.ListenPortFlag,
   521  		utils.NoDiscoverFlag,
   522  		utils.DiscoveryV5Flag,
   523  		utils.NetrestrictFlag,
   524  		utils.NodeKeyFileFlag,
   525  		utils.NodeKeyHexFlag,
   526  		utils.MaxPeersFlag,
   527  		utils.NATFlag,
   528  		utils.IPCDisabledFlag,
   529  		utils.IPCPathFlag,
   530  		utils.PasswordFileFlag,
   531  //
   532  		CorsStringFlag,
   533  		EnsAPIFlag,
   534  		SwarmTomlConfigPathFlag,
   535  		SwarmSwapEnabledFlag,
   536  		SwarmSwapAPIFlag,
   537  		SwarmSyncDisabledFlag,
   538  		SwarmSyncUpdateDelay,
   539  		SwarmLightNodeEnabled,
   540  		SwarmDeliverySkipCheckFlag,
   541  		SwarmListenAddrFlag,
   542  		SwarmPortFlag,
   543  		SwarmAccountFlag,
   544  		SwarmNetworkIdFlag,
   545  		ChequebookAddrFlag,
   546  //上传标志
   547  		SwarmApiFlag,
   548  		SwarmRecursiveFlag,
   549  		SwarmWantManifestFlag,
   550  		SwarmUploadDefaultPath,
   551  		SwarmUpFromStdinFlag,
   552  		SwarmUploadMimeType,
   553  //存储标志
   554  		SwarmStorePath,
   555  		SwarmStoreCapacity,
   556  		SwarmStoreCacheCapacity,
   557  	}
   558  	rpcFlags := []cli.Flag{
   559  		utils.WSEnabledFlag,
   560  		utils.WSListenAddrFlag,
   561  		utils.WSPortFlag,
   562  		utils.WSApiFlag,
   563  		utils.WSAllowedOriginsFlag,
   564  	}
   565  	app.Flags = append(app.Flags, rpcFlags...)
   566  	app.Flags = append(app.Flags, debug.Flags...)
   567  	app.Flags = append(app.Flags, swarmmetrics.Flags...)
   568  	app.Flags = append(app.Flags, tracing.Flags...)
   569  	app.Before = func(ctx *cli.Context) error {
   570  		runtime.GOMAXPROCS(runtime.NumCPU())
   571  		if err := debug.Setup(ctx, ""); err != nil {
   572  			return err
   573  		}
   574  		swarmmetrics.Setup(ctx)
   575  		tracing.Setup(ctx)
   576  		return nil
   577  	}
   578  	app.After = func(ctx *cli.Context) error {
   579  		debug.Exit()
   580  		return nil
   581  	}
   582  }
   583  
   584  func main() {
   585  	if err := app.Run(os.Args); err != nil {
   586  		fmt.Fprintln(os.Stderr, err)
   587  		os.Exit(1)
   588  	}
   589  }
   590  
   591  func version(ctx *cli.Context) error {
   592  	fmt.Println(strings.Title(clientIdentifier))
   593  	fmt.Println("Version:", sv.VersionWithMeta)
   594  	if gitCommit != "" {
   595  		fmt.Println("Git Commit:", gitCommit)
   596  	}
   597  	fmt.Println("Go Version:", runtime.Version())
   598  	fmt.Println("OS:", runtime.GOOS)
   599  	return nil
   600  }
   601  
   602  func bzzd(ctx *cli.Context) error {
   603  //
   604  //
   605  
   606  	bzzconfig, err := buildConfig(ctx)
   607  	if err != nil {
   608  		utils.Fatalf("unable to configure swarm: %v", err)
   609  	}
   610  
   611  	cfg := defaultNodeConfig
   612  
   613  //
   614  	cfg.WSModules = append(cfg.WSModules, "pss")
   615  
   616  //
   617  //为了在Swarm中保持一致,如果我们通过环境变量传递--datadir
   618  //
   619  	if _, err := os.Stat(bzzconfig.Path); err == nil {
   620  		cfg.DataDir = bzzconfig.Path
   621  	}
   622  
   623  //
   624  	setSwarmBootstrapNodes(ctx, &cfg)
   625  //
   626  	utils.SetNodeConfig(ctx, &cfg)
   627  	stack, err := node.New(&cfg)
   628  	if err != nil {
   629  		utils.Fatalf("can't create node: %v", err)
   630  	}
   631  
   632  //
   633  //
   634  	initSwarmNode(bzzconfig, stack, ctx)
   635  //在以太坊节点中将bzz注册为node.service
   636  	registerBzzService(bzzconfig, stack)
   637  //
   638  	utils.StartNode(stack)
   639  
   640  	go func() {
   641  		sigc := make(chan os.Signal, 1)
   642  		signal.Notify(sigc, syscall.SIGTERM)
   643  		defer signal.Stop(sigc)
   644  		<-sigc
   645  		log.Info("Got sigterm, shutting swarm down...")
   646  		stack.Stop()
   647  	}()
   648  
   649  	stack.Wait()
   650  	return nil
   651  }
   652  
   653  func registerBzzService(bzzconfig *bzzapi.Config, stack *node.Node) {
   654  //定义Swarm服务引导功能
   655  	boot := func(_ *node.ServiceContext) (node.Service, error) {
   656  //
   657  		return swarm.NewSwarm(bzzconfig, nil)
   658  	}
   659  //
   660  	if err := stack.Register(boot); err != nil {
   661  		utils.Fatalf("Failed to register the Swarm service: %v", err)
   662  	}
   663  }
   664  
   665  func getAccount(bzzaccount string, ctx *cli.Context, stack *node.Node) *ecdsa.PrivateKey {
   666  //
   667  	if bzzaccount == "" {
   668  		utils.Fatalf(SWARM_ERR_NO_BZZACCOUNT)
   669  	}
   670  //尝试将arg作为十六进制密钥文件加载。
   671  	if key, err := crypto.LoadECDSA(bzzaccount); err == nil {
   672  		log.Info("Swarm account key loaded", "address", crypto.PubkeyToAddress(key.PublicKey))
   673  		return key
   674  	}
   675  //
   676  	am := stack.AccountManager()
   677  	ks := am.Backends(keystore.KeyStoreType)[0].(*keystore.KeyStore)
   678  
   679  	return decryptStoreAccount(ks, bzzaccount, utils.MakePasswordList(ctx))
   680  }
   681  
   682  //getprivkey返回指定bzzaccount的私钥
   683  //
   684  func getPrivKey(ctx *cli.Context) *ecdsa.PrivateKey {
   685  //像在bzzd操作中一样启动群节点
   686  	bzzconfig, err := buildConfig(ctx)
   687  	if err != nil {
   688  		utils.Fatalf("unable to configure swarm: %v", err)
   689  	}
   690  	cfg := defaultNodeConfig
   691  	if _, err := os.Stat(bzzconfig.Path); err == nil {
   692  		cfg.DataDir = bzzconfig.Path
   693  	}
   694  	utils.SetNodeConfig(ctx, &cfg)
   695  	stack, err := node.New(&cfg)
   696  	if err != nil {
   697  		utils.Fatalf("can't create node: %v", err)
   698  	}
   699  	return getAccount(bzzconfig.BzzAccount, ctx, stack)
   700  }
   701  
   702  func decryptStoreAccount(ks *keystore.KeyStore, account string, passwords []string) *ecdsa.PrivateKey {
   703  	var a accounts.Account
   704  	var err error
   705  	if common.IsHexAddress(account) {
   706  		a, err = ks.Find(accounts.Account{Address: common.HexToAddress(account)})
   707  	} else if ix, ixerr := strconv.Atoi(account); ixerr == nil && ix > 0 {
   708  		if accounts := ks.Accounts(); len(accounts) > ix {
   709  			a = accounts[ix]
   710  		} else {
   711  			err = fmt.Errorf("index %d higher than number of accounts %d", ix, len(accounts))
   712  		}
   713  	} else {
   714  		utils.Fatalf("Can't find swarm account key %s", account)
   715  	}
   716  	if err != nil {
   717  		utils.Fatalf("Can't find swarm account key: %v - Is the provided bzzaccount(%s) from the right datadir/Path?", err, account)
   718  	}
   719  	keyjson, err := ioutil.ReadFile(a.URL.Path)
   720  	if err != nil {
   721  		utils.Fatalf("Can't load swarm account key: %v", err)
   722  	}
   723  	for i := 0; i < 3; i++ {
   724  		password := getPassPhrase(fmt.Sprintf("Unlocking swarm account %s [%d/3]", a.Address.Hex(), i+1), i, passwords)
   725  		key, err := keystore.DecryptKey(keyjson, password)
   726  		if err == nil {
   727  			return key.PrivateKey
   728  		}
   729  	}
   730  	utils.Fatalf("Can't decrypt swarm account key")
   731  	return nil
   732  }
   733  
   734  //getpassphrase通过获取与bzz帐户关联的密码
   735  //
   736  func getPassPhrase(prompt string, i int, passwords []string) string {
   737  //非交互式
   738  	if len(passwords) > 0 {
   739  		if i < len(passwords) {
   740  			return passwords[i]
   741  		}
   742  		return passwords[len(passwords)-1]
   743  	}
   744  
   745  //回退到交互模式
   746  	if prompt != "" {
   747  		fmt.Println(prompt)
   748  	}
   749  	password, err := console.Stdin.PromptPassword("Passphrase: ")
   750  	if err != nil {
   751  		utils.Fatalf("Failed to read passphrase: %v", err)
   752  	}
   753  	return password
   754  }
   755  
   756  //adddefaulthelpsubcommand通过定义的cli命令扫描并添加
   757  //
   758  //
   759  func addDefaultHelpSubcommands(commands []cli.Command) {
   760  	for i := range commands {
   761  		cmd := &commands[i]
   762  		if cmd.Subcommands != nil {
   763  			cmd.Subcommands = append(cmd.Subcommands, defaultSubcommandHelp)
   764  			addDefaultHelpSubcommands(cmd.Subcommands)
   765  		}
   766  	}
   767  }
   768  
   769  func setSwarmBootstrapNodes(ctx *cli.Context, cfg *node.Config) {
   770  	if ctx.GlobalIsSet(utils.BootnodesFlag.Name) || ctx.GlobalIsSet(utils.BootnodesV4Flag.Name) {
   771  		return
   772  	}
   773  
   774  	cfg.P2P.BootstrapNodes = []*discover.Node{}
   775  
   776  	for _, url := range SwarmBootnodes {
   777  		node, err := discover.ParseNode(url)
   778  		if err != nil {
   779  			log.Error("Bootstrap URL invalid", "enode", url, "err", err)
   780  		}
   781  		cfg.P2P.BootstrapNodes = append(cfg.P2P.BootstrapNodes, node)
   782  	}
   783  	log.Debug("added default swarm bootnodes", "length", len(cfg.P2P.BootstrapNodes))
   784  }