From afa66c489e3bfd4f5a58cce4a51e0847236917a2 Mon Sep 17 00:00:00 2001 From: tobigiwa Date: Fri, 6 Oct 2023 01:39:48 -0400 Subject: [PATCH] Resolves #271, info command now output information about the stack not container. Signed-off-by: tobigiwa --- cmd/info.go | 35 +++- cmd/init_tezos.go | 65 +++++++ cmd/ps.go | 3 +- go.mod | 5 +- go.sum | 61 +++++-- internal/blockchain/ethereum/accounts.go | 3 +- .../blockchain/ethereum/besu/besu_provider.go | 3 +- internal/blockchain/ethereum/besu/genesis.go | 4 +- .../ethereum/connector/ethconnect/config.go | 6 +- .../ethereum/connector/evmconnect/config.go | 6 +- internal/blockchain/ethereum/contracts.go | 6 +- .../blockchain/ethereum/ethsigner/accounts.go | 4 +- .../blockchain/ethereum/ethsigner/config.go | 4 +- .../ethereum/ethsigner/ethsigner.go | 3 +- internal/blockchain/ethereum/geth/client.go | 4 +- internal/blockchain/ethereum/geth/genesis.go | 4 +- .../blockchain/fabric/cryptogen_config.go | 4 +- .../blockchain/fabric/fabconnect/client.go | 6 +- .../fabric/fabconnect/fabconnect_config.go | 4 +- internal/blockchain/fabric/fabric_provider.go | 3 +- internal/blockchain/fabric/network_config.go | 4 +- .../tezos/connector/connector_interface.go | 33 ++++ .../tezos/connector/tezosconnect/client.go | 39 +++++ .../tezos/connector/tezosconnect/config.go | 138 +++++++++++++++ .../tezos/connector/tezosconnect/docker.go | 54 ++++++ .../tezos/remoterpc/remoterpc_provider.go | 165 ++++++++++++++++++ internal/blockchain/tezos/tezos.go | 33 ++++ internal/core/config.go | 8 +- internal/core/http.go | 3 +- internal/core/manifest.go | 4 +- internal/stacks/stack_manager.go | 99 ++++++++--- pkg/types/firefly_config.go | 11 ++ pkg/types/manifest.go | 2 + pkg/types/options.go | 8 +- 34 files changed, 740 insertions(+), 94 deletions(-) create mode 100644 cmd/init_tezos.go create mode 100644 internal/blockchain/tezos/connector/connector_interface.go create mode 100644 internal/blockchain/tezos/connector/tezosconnect/client.go create mode 100644 internal/blockchain/tezos/connector/tezosconnect/config.go create mode 100644 internal/blockchain/tezos/connector/tezosconnect/docker.go create mode 100644 internal/blockchain/tezos/remoterpc/remoterpc_provider.go create mode 100644 internal/blockchain/tezos/tezos.go diff --git a/cmd/info.go b/cmd/info.go index e8ca102f..ea216646 100644 --- a/cmd/info.go +++ b/cmd/info.go @@ -19,6 +19,7 @@ package cmd import ( "context" "fmt" + "strings" "github.com/hyperledger/firefly-cli/internal/docker" "github.com/hyperledger/firefly-cli/internal/log" @@ -30,7 +31,7 @@ var infoCmd = &cobra.Command{ Use: "info ", Short: "Get info about a stack", Long: `Get info about a stack such as each container name - and image version.`, + and image version. If non is given, it run the "info" command for all stack on the local machine.`, RunE: func(cmd *cobra.Command, args []string) error { ctx := log.WithVerbosity(context.Background(), verbose) ctx = context.WithValue(ctx, docker.CtxIsLogCmdKey{}, true) @@ -42,17 +43,33 @@ var infoCmd = &cobra.Command{ } ctx = context.WithValue(ctx, docker.CtxComposeVersionKey{}, version) - stackManager := stacks.NewStackManager(ctx) - if len(args) == 0 { - return fmt.Errorf("no stack specified") + allStacks, err := stacks.ListStacks() + if err != nil { + return err } - stackName := args[0] - if err := stackManager.LoadStack(stackName); err != nil { - return err + if len(args) > 0 { + namedStacks := make([]string, 0, len(args)) + for _, stackName := range args { + if contains(allStacks, strings.TrimSpace(stackName)) { + namedStacks = append(namedStacks, stackName) + } else { + fmt.Printf("stack name - %s, is not present on your local machine. Run `ff ls` to see all available stacks.\n", stackName) + } + } + + allStacks = namedStacks // replace only the user specified stacks in the slice instead. } - if err := stackManager.PrintStackInfo(); err != nil { - return err + + stackManager := stacks.NewStackManager(ctx) + for _, stackName := range allStacks { + if err := stackManager.LoadStack(stackName); err != nil { + return err + } + + if err := stackManager.PrintStacksInfo(); err != nil { + return err + } } return nil }, diff --git a/cmd/init_tezos.go b/cmd/init_tezos.go new file mode 100644 index 00000000..e55f4db7 --- /dev/null +++ b/cmd/init_tezos.go @@ -0,0 +1,65 @@ +// Copyright © 2023 Kaleido, Inc. +// +// SPDX-License-Identifier: Apache-2.0 +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package cmd + +import ( + "context" + "fmt" + "path/filepath" + + "github.com/spf13/cobra" + + "github.com/hyperledger/firefly-cli/internal/log" + "github.com/hyperledger/firefly-cli/internal/stacks" + "github.com/hyperledger/firefly-cli/pkg/types" +) + +var initTezosCmd = &cobra.Command{ + Use: "tezos [stack_name] [member_count]", + Short: "Create a new FireFly local dev stack using an Tezos blockchain", + Long: `Create a new FireFly local dev stack using an Tezos blockchain`, + Args: cobra.MaximumNArgs(2), + RunE: func(cmd *cobra.Command, args []string) error { + ctx := log.WithVerbosity(context.Background(), verbose) + ctx = log.WithLogger(ctx, logger) + stackManager := stacks.NewStackManager(ctx) + initOptions.BlockchainProvider = types.BlockchainProviderTezos.String() + initOptions.BlockchainConnector = types.BlockchainConnectorTezosconnect.String() + initOptions.BlockchainNodeProvider = types.BlockchainNodeProviderRemoteRPC.String() + // By default we turn off multiparty mode while it's not supported yet + initOptions.MultipartyEnabled = false + initOptions.TokenProviders = []string{} + if err := initCommon(args); err != nil { + return err + } + if err := stackManager.InitStack(&initOptions); err != nil { + stackManager.RemoveStack() + return err + } + fmt.Printf("Stack '%s' created!\nTo start your new stack run:\n\n%s start %s\n", initOptions.StackName, rootCmd.Use, initOptions.StackName) + fmt.Printf("\nYour docker compose file for this stack can be found at: %s\n\n", filepath.Join(stackManager.Stack.StackDir, "docker-compose.yml")) + return nil + }, +} + +func init() { + initTezosCmd.Flags().IntVar(&initOptions.BlockPeriod, "block-period", -1, "Block period in seconds. Default is variable based on selected blockchain provider.") + initTezosCmd.Flags().StringVar(&initOptions.ContractAddress, "contract-address", "", "Do not automatically deploy a contract, instead use a pre-configured address") + initTezosCmd.Flags().StringVar(&initOptions.RemoteNodeURL, "remote-node-url", "", "For cases where the node is pre-existing and running remotely") + + initCmd.AddCommand(initTezosCmd) +} diff --git a/cmd/ps.go b/cmd/ps.go index 0f5f6323..fb432150 100644 --- a/cmd/ps.go +++ b/cmd/ps.go @@ -19,7 +19,8 @@ var psCmd = &cobra.Command{ Short: "Returns information on running stacks", Long: `ps returns currently running stacks on your local machine. - It also takes a continuous list of whitespace optional arguement - stack name.`, + It also takes a continuous list of whitespace optional arguement - stack name. If non + is given, it run the "ps" command for all stack on the local machine.`, Aliases: []string{"process"}, RunE: func(cmd *cobra.Command, args []string) error { diff --git a/go.mod b/go.mod index 189b41ef..11945eb8 100644 --- a/go.mod +++ b/go.mod @@ -19,19 +19,20 @@ module github.com/hyperledger/firefly-cli go 1.16 require ( + blockwatch.cc/tzgo v1.17.1 github.com/briandowns/spinner v1.12.0 github.com/btcsuite/btcd v0.22.1 github.com/google/go-containerregistry v0.8.0 github.com/hyperledger/firefly-common v1.1.2 github.com/hyperledger/firefly-signer v0.9.6 - github.com/mattn/go-isatty v0.0.14 + github.com/mattn/go-isatty v0.0.19 github.com/miracl/conflate v1.2.1 github.com/mitchellh/go-homedir v1.1.0 github.com/otiai10/copy v1.7.0 github.com/spf13/cobra v1.5.0 github.com/spf13/viper v1.12.1-0.20220712161005-5247643f0235 github.com/stretchr/testify v1.8.0 - golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e + golang.org/x/crypto v0.10.0 gopkg.in/yaml.v2 v2.4.0 gopkg.in/yaml.v3 v3.0.1 ) diff --git a/go.sum b/go.sum index 09e3261c..8d849ed8 100644 --- a/go.sum +++ b/go.sum @@ -1,4 +1,6 @@ bazil.org/fuse v0.0.0-20160811212531-371fbbdaa898/go.mod h1:Xbm+BRKSBEpa4q4hTSxohYNQpsxXPbPry4JJWOB3LB8= +blockwatch.cc/tzgo v1.17.1 h1:00xwa5MS8DAO6ddtTRAw/VdfEdGZHgUadjtOeFDLgjY= +blockwatch.cc/tzgo v1.17.1/go.mod h1:tTgPzOH1pMhQod2sh2/jjOLabdCQegb8FZG23+fv1XE= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= @@ -293,6 +295,9 @@ github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/decred/dcrd/crypto/blake256 v1.0.1/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 h1:8UrgZ3GkP4i/CLijOJx79Yu+etlyjdBU4sfcs2WYQMs= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0= github.com/decred/dcrd/lru v1.0.0/go.mod h1:mxKOwFd7lFjN2GZYsiz/ecgqR6kkYAl+0pz0tEMk218= github.com/denverdino/aliyungo v0.0.0-20190125010748-a747050bb1ba/go.mod h1:dV8lFg6daOBZbT6/BDGIz6Y3WFGn8juu6G+CQ6LHtl0= github.com/dgrijalva/jwt-go v0.0.0-20170104182250-a601269ab70c/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= @@ -321,6 +326,10 @@ github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZ github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +github.com/echa/bson v0.0.0-20220430141917-c0fbdf7f8b79 h1:J+/tX7s5mN1aoeQi2ySzix7+zyEhnymkudOxn7VMze4= +github.com/echa/bson v0.0.0-20220430141917-c0fbdf7f8b79/go.mod h1:Ih8Pfj34Z/kOmaLua+KtFWFK3AviGsH5siipj6Gmoa8= +github.com/echa/log v1.2.4 h1:+3+WEqutIBUbASYnuk9zz6HKlm6o8WsFxlOMbA3BcAA= +github.com/echa/log v1.2.4/go.mod h1:KYs5YtFCgL4yHBBqhPmTBhz5ETI1A8q+qbiDPPF1MiM= github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= github.com/emicklei/go-restful v2.9.5+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= @@ -339,8 +348,10 @@ github.com/envoyproxy/protoc-gen-validate v0.6.2/go.mod h1:2t7qjJNvHPx8IjnBOzl9E github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= -github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w= github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= +github.com/fatih/color v1.14.1/go.mod h1:2oHN61fhTpgcxD3TSWCgKDiH1+x4OiDVVGH8WlgGZGg= +github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs= +github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw= github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k= github.com/frankban/quicktest v1.14.3 h1:FJKSZTDHjyhriyC81FLQ0LY93eSai0ZyR/ZIkd3ZUKE= @@ -611,16 +622,20 @@ github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVc github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= -github.com/mattn/go-colorable v0.1.12 h1:jF+Du6AlPIjs2BiUiQlKOX0rt3SujHxPnksPKZbaA40= github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= +github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= +github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84= github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= -github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= +github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-shellwords v1.0.3/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vqg+NOMyg4B2o= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= @@ -827,7 +842,6 @@ github.com/spf13/cobra v0.0.2-0.20171109065643-2da4a54c5cee/go.mod h1:1l0Ry5zgKv github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE= github.com/spf13/cobra v1.3.0/go.mod h1:BrRVncBjOJa/eUcVVm9CE+oC6as8k+VYr4NY7WCi9V4= -github.com/spf13/cobra v1.4.0 h1:y+wJpx64xcgO1V+RcnwW0LEHxTKRi2ZDPSBjWnrg88Q= github.com/spf13/cobra v1.4.0/go.mod h1:Wo4iy3BUC+X2Fybo0PDqwJIv3dNRiZLHQymsfxlB84g= github.com/spf13/cobra v1.5.0 h1:X+jTBEBqF0bHN+9cSMgmfuvv2VHJ9ezmFNf9Y/XstYU= github.com/spf13/cobra v1.5.0/go.mod h1:dWXEIy2H428czQCjInthrTRUg7yKbok+2Qi/yBIJoUM= @@ -908,6 +922,7 @@ github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/yvasiyarov/go-metrics v0.0.0-20140926110328-57bccd1ccd43/go.mod h1:aX5oPXxHm3bOH+xeAttToC8pqch2ScQN/JoXYupl6xs= github.com/yvasiyarov/gorelic v0.0.0-20141212073537-a9bba5b9ab50/go.mod h1:NUSPSUX/bi6SeDMUh6brw0nXpxHnc96TguQh0+r/ssA= github.com/yvasiyarov/newrelic_platform_go v0.0.0-20140908184405-b21fdbd4370f/go.mod h1:GlGEuHIJweS1mbCqG+7vt2nvWLzLLnRHbXz5JKd/Qbg= @@ -962,11 +977,13 @@ golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220518034528-6f7dac969898/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e h1:T8NU3HyQ8ClP4SEE+KbFlg6n0NhuTsN4MyznaarGsZM= golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.10.0 h1:LKqV2xt9+kDzSTfOhx4FrkEBcMrAgHSYgzywV9zcGmM= +golang.org/x/crypto v0.10.0/go.mod h1:o4eNf7Ede1fv+hwOwZsTHl9EsPFO6q6ZvYR8vYfY45I= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -1004,6 +1021,8 @@ golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.5.0/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20180719180050-a680a1efc54d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1069,8 +1088,11 @@ golang.org/x/net v0.0.0-20220325170049-de3da57026de/go.mod h1:CfG3xpIq0wQ8r1q4Su golang.org/x/net v0.0.0-20220412020605-290c469a71a5/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220520000938-2e3eb7b945c2/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.0.0-20220531201128-c960675eff93 h1:MYimHLfoXEpOhqd/zgoA/uoXzHB86AEky4LAx5ij9xA= golang.org/x/net v0.0.0-20220531201128-c960675eff93/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M= +golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -1102,8 +1124,10 @@ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20220513210516-0976fa681c29 h1:w8s32wxx3sY+OjLlv9qltkLU5yvJzxjjgiHWLjdIcw4= golang.org/x/sync v0.0.0-20220513210516-0976fa681c29/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= +golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1217,13 +1241,23 @@ golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220328115105-d36c6a25d886/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220502124256-b6088ccd6cba/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a h1:dGzPydgVsqGcTRVwiLJ1jVbufYwmzD3LfVPLKsKg+0k= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.9.0 h1:KS/R3tvhPqvJvwcKfnBHJwwthS11LRhmM5D59eEXa0s= +golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.0.0-20220411215600-e5f449aeb171/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.0.0-20220526004731-065cf7ba2467 h1:CBpWXWQpIRjzmkkA+M7q9Fqnwd2mZr3AFqexg8YTfoM= golang.org/x/term v0.0.0-20220526004731-065cf7ba2467/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= +golang.org/x/term v0.9.0 h1:GRRCnKYhdQrD8kfRAdQ6Zcw1P0OcELxGLKJvtjVMZ28= +golang.org/x/term v0.9.0/go.mod h1:M6DEAAIenWoTxdKrOltXcmDY3rSplQUkrvaDU5FcQyo= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1232,8 +1266,11 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.10.0 h1:UpjohKhiEgNc0CSauXmwYftY1+LlaC75SJwh0SgCX58= +golang.org/x/text v0.10.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -1302,6 +1339,8 @@ golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.8/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -1493,6 +1532,7 @@ google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQ google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= +gopkg.in/bson.v2 v2.0.0-20171018101713-d8c8987b8862/go.mod h1:VN8wuk/3Ksp8lVZ82HHf/MI1FHOBDt5bPK9VZ8DvymM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20141024133853-64131543e789/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -1508,6 +1548,7 @@ gopkg.in/ini.v1 v1.66.2/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/ini.v1 v1.66.4/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/ini.v1 v1.66.6 h1:LATuAqN/shcYAOkv3wl2L4rkaKqkcgTBQjOyYDvcPKI= gopkg.in/ini.v1 v1.66.6/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/mgo.v2 v2.0.0-20190816093944-a6b53ec6cb22/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA= gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= gopkg.in/square/go-jose.v2 v2.2.2/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= diff --git a/internal/blockchain/ethereum/accounts.go b/internal/blockchain/ethereum/accounts.go index a2b367ad..0fec787c 100644 --- a/internal/blockchain/ethereum/accounts.go +++ b/internal/blockchain/ethereum/accounts.go @@ -19,7 +19,6 @@ package ethereum import ( "context" "fmt" - "io/ioutil" "os" "path/filepath" @@ -45,7 +44,7 @@ func CreateWalletFile(outputDirectory, prefix, password string) (*secp256k1.KeyP } else { filename = filepath.Join(outputDirectory, keyPair.Address.String()[2:]) } - err = ioutil.WriteFile(filename, wallet.JSON(), 0755) + err = os.WriteFile(filename, wallet.JSON(), 0755) if err != nil { return nil, "", err } diff --git a/internal/blockchain/ethereum/besu/besu_provider.go b/internal/blockchain/ethereum/besu/besu_provider.go index 77b1ae81..d4670dac 100644 --- a/internal/blockchain/ethereum/besu/besu_provider.go +++ b/internal/blockchain/ethereum/besu/besu_provider.go @@ -19,7 +19,6 @@ package besu import ( "context" "fmt" - "io/ioutil" "os" "path" "path/filepath" @@ -80,7 +79,7 @@ func (p *BesuProvider) WriteConfig(options *types.InitOptions) error { // Generate node key nodeAddress, nodeKey := ethereum.GenerateAddressAndPrivateKey() // Write the node key to disk - if err := ioutil.WriteFile(filepath.Join(initDir, "blockchain", "nodeKey"), []byte(nodeKey), 0755); err != nil { + if err := os.WriteFile(filepath.Join(initDir, "blockchain", "nodeKey"), []byte(nodeKey), 0755); err != nil { return err } // Drop the 0x on the front of the address here because that's what is expected in the genesis.json diff --git a/internal/blockchain/ethereum/besu/genesis.go b/internal/blockchain/ethereum/besu/genesis.go index 479b03c4..9990cf89 100644 --- a/internal/blockchain/ethereum/besu/genesis.go +++ b/internal/blockchain/ethereum/besu/genesis.go @@ -19,7 +19,7 @@ package besu import ( "encoding/json" "fmt" - "io/ioutil" + "os" "path/filepath" "strings" ) @@ -64,7 +64,7 @@ type Alloc struct { func (g *Genesis) WriteGenesisJson(filename string) error { genesisJsonBytes, _ := json.MarshalIndent(g, "", " ") - if err := ioutil.WriteFile(filepath.Join(filename), genesisJsonBytes, 0755); err != nil { + if err := os.WriteFile(filepath.Join(filename), genesisJsonBytes, 0755); err != nil { return err } return nil diff --git a/internal/blockchain/ethereum/connector/ethconnect/config.go b/internal/blockchain/ethereum/connector/ethconnect/config.go index 678760da..1276c82c 100644 --- a/internal/blockchain/ethereum/connector/ethconnect/config.go +++ b/internal/blockchain/ethereum/connector/ethconnect/config.go @@ -18,7 +18,7 @@ package ethconnect import ( "fmt" - "io/ioutil" + "os" "path/filepath" "github.com/hyperledger/firefly-cli/internal/blockchain/ethereum/connector" @@ -59,7 +59,7 @@ type HTTP struct { func (e *Config) WriteConfig(filename string, extraConnectorConfigPath string) error { configYamlBytes, _ := yaml.Marshal(e) - if err := ioutil.WriteFile(filepath.Join(filename), configYamlBytes, 0755); err != nil { + if err := os.WriteFile(filepath.Join(filename), configYamlBytes, 0755); err != nil { return err } if extraConnectorConfigPath != "" { @@ -71,7 +71,7 @@ func (e *Config) WriteConfig(filename string, extraConnectorConfigPath string) e if err != nil { return err } - if err := ioutil.WriteFile(filename, bytes, 0755); err != nil { + if err := os.WriteFile(filename, bytes, 0755); err != nil { return err } } diff --git a/internal/blockchain/ethereum/connector/evmconnect/config.go b/internal/blockchain/ethereum/connector/evmconnect/config.go index 67ac7020..48ed4887 100644 --- a/internal/blockchain/ethereum/connector/evmconnect/config.go +++ b/internal/blockchain/ethereum/connector/evmconnect/config.go @@ -18,7 +18,7 @@ package evmconnect import ( "fmt" - "io/ioutil" + "os" "path/filepath" "github.com/hyperledger/firefly-cli/internal/blockchain/ethereum/connector" @@ -76,7 +76,7 @@ type GasOracleConfig struct { func (e *Config) WriteConfig(filename string, extraEvmconnectConfigPath string) error { configYamlBytes, _ := yaml.Marshal(e) - if err := ioutil.WriteFile(filepath.Join(filename), configYamlBytes, 0755); err != nil { + if err := os.WriteFile(filepath.Join(filename), configYamlBytes, 0755); err != nil { return err } if extraEvmconnectConfigPath != "" { @@ -88,7 +88,7 @@ func (e *Config) WriteConfig(filename string, extraEvmconnectConfigPath string) if err != nil { return err } - if err := ioutil.WriteFile(filename, bytes, 0755); err != nil { + if err := os.WriteFile(filename, bytes, 0755); err != nil { return err } } diff --git a/internal/blockchain/ethereum/contracts.go b/internal/blockchain/ethereum/contracts.go index 5395185e..48291d57 100644 --- a/internal/blockchain/ethereum/contracts.go +++ b/internal/blockchain/ethereum/contracts.go @@ -19,7 +19,7 @@ package ethereum import ( "context" "encoding/json" - "io/ioutil" + "os" "github.com/hyperledger/firefly-cli/internal/blockchain/ethereum/ethtypes" "github.com/hyperledger/firefly-cli/internal/docker" @@ -32,7 +32,7 @@ type truffleCompiledContract struct { } func ReadTruffleCompiledContract(filePath string) (*ethtypes.CompiledContracts, error) { - d, _ := ioutil.ReadFile(filePath) + d, _ := os.ReadFile(filePath) var truffleCompiledContract *truffleCompiledContract err := json.Unmarshal(d, &truffleCompiledContract) if err != nil { @@ -51,7 +51,7 @@ func ReadTruffleCompiledContract(filePath string) (*ethtypes.CompiledContracts, } func ReadSolcCompiledContract(filePath string) (*ethtypes.CompiledContracts, error) { - d, _ := ioutil.ReadFile(filePath) + d, _ := os.ReadFile(filePath) var contracts *ethtypes.CompiledContracts err := json.Unmarshal(d, &contracts) if err != nil { diff --git a/internal/blockchain/ethereum/ethsigner/accounts.go b/internal/blockchain/ethereum/ethsigner/accounts.go index 72a2844e..120280b6 100644 --- a/internal/blockchain/ethereum/ethsigner/accounts.go +++ b/internal/blockchain/ethereum/ethsigner/accounts.go @@ -19,7 +19,7 @@ package ethsigner import ( "context" "fmt" - "io/ioutil" + "os" "path/filepath" "github.com/hyperledger/firefly-cli/internal/docker" @@ -38,7 +38,7 @@ key-file = "/data/keystore/%s" password-file = "/data/password" `, keyFile) filename := filepath.Join(outputDirectory, fmt.Sprintf("%s.toml", keyFile)) - return filename, ioutil.WriteFile(filename, []byte(toml), 0755) + return filename, os.WriteFile(filename, []byte(toml), 0755) } func (p *EthSignerProvider) copyTomlFileToVolume(ctx context.Context, tomlFilePath, volumeName string) error { diff --git a/internal/blockchain/ethereum/ethsigner/config.go b/internal/blockchain/ethereum/ethsigner/config.go index 94bca2cb..9a8de2d4 100644 --- a/internal/blockchain/ethereum/ethsigner/config.go +++ b/internal/blockchain/ethereum/ethsigner/config.go @@ -17,7 +17,7 @@ package ethsigner import ( - "io/ioutil" + "os" "path/filepath" "gopkg.in/yaml.v2" @@ -65,7 +65,7 @@ type Config struct { func (e *Config) WriteConfig(filename string) error { configYamlBytes, _ := yaml.Marshal(e) - return ioutil.WriteFile(filepath.Join(filename), configYamlBytes, 0755) + return os.WriteFile(filepath.Join(filename), configYamlBytes, 0755) } func GenerateSignerConfig(chainID int64, rpcURL string) *Config { diff --git a/internal/blockchain/ethereum/ethsigner/ethsigner.go b/internal/blockchain/ethereum/ethsigner/ethsigner.go index 50bd9562..114f4c97 100644 --- a/internal/blockchain/ethereum/ethsigner/ethsigner.go +++ b/internal/blockchain/ethereum/ethsigner/ethsigner.go @@ -20,7 +20,6 @@ import ( "context" "encoding/hex" "fmt" - "io/ioutil" "net/url" "os" "path" @@ -58,7 +57,7 @@ func (p *EthSignerProvider) WriteConfig(options *types.InitOptions, rpcURL strin if err := os.MkdirAll(blockchainDirectory, 0755); err != nil { return err } - if err := ioutil.WriteFile(filepath.Join(initDir, "blockchain", "password"), []byte(keyPassword), 0755); err != nil { + if err := os.WriteFile(filepath.Join(initDir, "blockchain", "password"), []byte(keyPassword), 0755); err != nil { return err } diff --git a/internal/blockchain/ethereum/geth/client.go b/internal/blockchain/ethereum/geth/client.go index 44cdffc8..7919ddec 100644 --- a/internal/blockchain/ethereum/geth/client.go +++ b/internal/blockchain/ethereum/geth/client.go @@ -20,7 +20,7 @@ import ( "bytes" "encoding/json" "fmt" - "io/ioutil" + "io" "net/http" ) @@ -74,7 +74,7 @@ func (g *GethClient) UnlockAccount(address string, password string) error { return err } defer resp.Body.Close() - responseBody, err := ioutil.ReadAll(resp.Body) + responseBody, err := io.ReadAll(resp.Body) if err != nil { return err } diff --git a/internal/blockchain/ethereum/geth/genesis.go b/internal/blockchain/ethereum/geth/genesis.go index decdd25f..c3413a6b 100644 --- a/internal/blockchain/ethereum/geth/genesis.go +++ b/internal/blockchain/ethereum/geth/genesis.go @@ -19,7 +19,7 @@ package geth import ( "encoding/json" "fmt" - "io/ioutil" + "os" "path/filepath" "strings" ) @@ -108,7 +108,7 @@ func CreateGenesis(addresses []string, blockPeriod int, chainID int64) *Genesis func (g *Genesis) WriteGenesisJson(filename string) error { genesisJsonBytes, _ := json.MarshalIndent(g, "", " ") - if err := ioutil.WriteFile(filepath.Join(filename), genesisJsonBytes, 0755); err != nil { + if err := os.WriteFile(filepath.Join(filename), genesisJsonBytes, 0755); err != nil { return err } return nil diff --git a/internal/blockchain/fabric/cryptogen_config.go b/internal/blockchain/fabric/cryptogen_config.go index 39d827e7..90ae77b3 100644 --- a/internal/blockchain/fabric/cryptogen_config.go +++ b/internal/blockchain/fabric/cryptogen_config.go @@ -17,7 +17,7 @@ package fabric import ( - "io/ioutil" + "os" "gopkg.in/yaml.v3" ) @@ -94,5 +94,5 @@ func WriteCryptogenConfig(memberCount int, path string) error { } cryptogenConfigBytes, _ := yaml.Marshal(cryptogenConfig) - return ioutil.WriteFile(path, cryptogenConfigBytes, 0755) + return os.WriteFile(path, cryptogenConfigBytes, 0755) } diff --git a/internal/blockchain/fabric/fabconnect/client.go b/internal/blockchain/fabric/fabconnect/client.go index 9bf8b947..d939e86f 100644 --- a/internal/blockchain/fabric/fabconnect/client.go +++ b/internal/blockchain/fabric/fabconnect/client.go @@ -20,7 +20,7 @@ import ( "bytes" "encoding/json" "fmt" - "io/ioutil" + "io" "net/http" "net/url" "path" @@ -73,7 +73,7 @@ func CreateIdentity(fabconnectUrl string, signer string) (*CreateIdentityRespons return nil, err } defer resp.Body.Close() - responseBody, err := ioutil.ReadAll(resp.Body) + responseBody, err := io.ReadAll(resp.Body) if err != nil { return nil, err } @@ -113,7 +113,7 @@ func EnrollIdentity(fabconnectUrl, signer, secret string) (*EnrollIdentityRespon return nil, err } defer resp.Body.Close() - responseBody, err := ioutil.ReadAll(resp.Body) + responseBody, err := io.ReadAll(resp.Body) if err != nil { return nil, err } diff --git a/internal/blockchain/fabric/fabconnect/fabconnect_config.go b/internal/blockchain/fabric/fabconnect/fabconnect_config.go index 548a9b65..1fed94c6 100644 --- a/internal/blockchain/fabric/fabconnect/fabconnect_config.go +++ b/internal/blockchain/fabric/fabconnect/fabconnect_config.go @@ -17,7 +17,7 @@ package fabconnect import ( - "io/ioutil" + "os" "gopkg.in/yaml.v3" ) @@ -86,5 +86,5 @@ func WriteFabconnectConfig(filePath string) error { } fabconnectConfigBytes, _ := yaml.Marshal(fabconnectConfig) - return ioutil.WriteFile(filePath, fabconnectConfigBytes, 0755) + return os.WriteFile(filePath, fabconnectConfigBytes, 0755) } diff --git a/internal/blockchain/fabric/fabric_provider.go b/internal/blockchain/fabric/fabric_provider.go index 97fb51d6..01fb168d 100644 --- a/internal/blockchain/fabric/fabric_provider.go +++ b/internal/blockchain/fabric/fabric_provider.go @@ -22,7 +22,6 @@ import ( "encoding/json" "errors" "fmt" - "io/ioutil" "os" "path" "path/filepath" @@ -321,7 +320,7 @@ func (p *FabricProvider) getFabconnectServiceDefinitions(members []*types.Organi func (p *FabricProvider) writeConfigtxYaml() error { if !p.stack.RemoteFabricNetwork { filePath := path.Join(p.stack.InitDir, "blockchain", "configtx.yaml") - return ioutil.WriteFile(filePath, []byte(configtxYaml), 0755) + return os.WriteFile(filePath, []byte(configtxYaml), 0755) } return nil } diff --git a/internal/blockchain/fabric/network_config.go b/internal/blockchain/fabric/network_config.go index 7620a240..6b7dafce 100644 --- a/internal/blockchain/fabric/network_config.go +++ b/internal/blockchain/fabric/network_config.go @@ -17,7 +17,7 @@ package fabric import ( - "io/ioutil" + "os" "gopkg.in/yaml.v3" ) @@ -200,5 +200,5 @@ func WriteNetworkConfig(outputPath string) error { Version: "1.1.0%", } networkConfigBytes, _ := yaml.Marshal(networkConfig) - return ioutil.WriteFile(outputPath, networkConfigBytes, 0755) + return os.WriteFile(outputPath, networkConfigBytes, 0755) } diff --git a/internal/blockchain/tezos/connector/connector_interface.go b/internal/blockchain/tezos/connector/connector_interface.go new file mode 100644 index 00000000..95b18675 --- /dev/null +++ b/internal/blockchain/tezos/connector/connector_interface.go @@ -0,0 +1,33 @@ +// Copyright © 2022 Kaleido, Inc. +// +// SPDX-License-Identifier: Apache-2.0 +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package connector + +import ( + "github.com/hyperledger/firefly-cli/internal/docker" + "github.com/hyperledger/firefly-cli/pkg/types" +) + +type Connector interface { + GetServiceDefinitions(s *types.Stack, dependentServices map[string]string) []*docker.ServiceDefinition + GenerateConfig(stack *types.Stack, member *types.Organization) Config + Name() string + Port() int +} + +type Config interface { + WriteConfig(filename string, extraConnectorConfigPath string) error +} diff --git a/internal/blockchain/tezos/connector/tezosconnect/client.go b/internal/blockchain/tezos/connector/tezosconnect/client.go new file mode 100644 index 00000000..7ecca5ff --- /dev/null +++ b/internal/blockchain/tezos/connector/tezosconnect/client.go @@ -0,0 +1,39 @@ +// Copyright © 2023 Kaleido, Inc. +// +// SPDX-License-Identifier: Apache-2.0 +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package tezosconnect + +import ( + "context" +) + +type Tezosconnect struct { + ctx context.Context +} + +func NewTezosconnect(ctx context.Context) *Tezosconnect { + return &Tezosconnect{ + ctx: ctx, + } +} + +func (t *Tezosconnect) Name() string { + return "tezosconnect" +} + +func (t *Tezosconnect) Port() int { + return 5008 +} diff --git a/internal/blockchain/tezos/connector/tezosconnect/config.go b/internal/blockchain/tezos/connector/tezosconnect/config.go new file mode 100644 index 00000000..4794ef98 --- /dev/null +++ b/internal/blockchain/tezos/connector/tezosconnect/config.go @@ -0,0 +1,138 @@ +// Copyright © 2023 Kaleido, Inc. +// +// SPDX-License-Identifier: Apache-2.0 +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package tezosconnect + +import ( + "fmt" + "os" + "path/filepath" + + "github.com/hyperledger/firefly-cli/internal/blockchain/tezos/connector" + "github.com/hyperledger/firefly-cli/pkg/types" + "github.com/miracl/conflate" + "gopkg.in/yaml.v2" +) + +type Config struct { + Log *types.LogConfig `yaml:"log,omitempty"` + Connector *ConnectorConfig `yaml:"connector,omitempty"` + Metrics *types.MetricsServerConfig `yaml:"metrics,omitempty"` + Persistence *PersistenceConfig `yaml:"persistence,omitempty"` + FFCore *FFCoreConfig `yaml:"ffcore,omitempty"` + Confirmations *ConfirmationsConfig `yaml:"confirmations,omitempty"` + API *APIConfig `yaml:"api,omitempty"` +} + +type APIConfig struct { + Port int `yaml:"port,omitempty"` + Address string `yaml:"address,omitempty"` + PublicURL string `yaml:"publicURL,omitempty"` +} + +type ConnectorConfig struct { + URL string `yaml:"url,omitempty"` +} + +type PersistenceConfig struct { + LevelDB *LevelDBConfig `yaml:"leveldb,omitempty"` +} + +type LevelDBConfig struct { + Path string `yaml:"path,omitempty"` +} + +type FFCoreConfig struct { + URL string `yaml:"url,omitempty"` + Namespaces []string `yaml:"namespaces,omitempty"` +} + +type ConfirmationsConfig struct { + Required *int `yaml:"required,omitempty"` +} + +func (c *Config) WriteConfig(filename string, extraTezosconnectConfigPath string) error { + configYamlBytes, _ := yaml.Marshal(c) + if err := os.WriteFile(filepath.Join(filename), configYamlBytes, 0755); err != nil { + return err + } + if extraTezosconnectConfigPath != "" { + c, err := conflate.FromFiles(filename, extraTezosconnectConfigPath) + if err != nil { + return err + } + bytes, err := c.MarshalYAML() + if err != nil { + return err + } + if err := os.WriteFile(filename, bytes, 0755); err != nil { + return err + } + } + return nil +} + +func (t *Tezosconnect) GenerateConfig(stack *types.Stack, org *types.Organization) connector.Config { + confirmations := new(int) + *confirmations = 0 + var metrics *types.MetricsServerConfig + + if stack.PrometheusEnabled { + metrics = &types.MetricsServerConfig{ + HttpServerConfig: types.HttpServerConfig{ + Port: org.ExposedConnectorMetricsPort, + Address: "0.0.0.0", + PublicURL: fmt.Sprintf("http://127.0.0.1:%d", org.ExposedConnectorMetricsPort), + }, + Enabled: true, + Path: "/metrics", + } + } else { + metrics = nil + } + + return &Config{ + Log: &types.LogConfig{ + Level: "debug", + }, + API: &APIConfig{ + Port: t.Port(), + Address: "0.0.0.0", + PublicURL: fmt.Sprintf("http://127.0.0.1:%v", org.ExposedConnectorPort), + }, + Persistence: &PersistenceConfig{ + LevelDB: &LevelDBConfig{ + Path: "/tezosconnect/leveldb", + }, + }, + FFCore: &FFCoreConfig{ + URL: getCoreURL(org), + Namespaces: []string{"default"}, + }, + Metrics: metrics, + Confirmations: &ConfirmationsConfig{ + Required: confirmations, + }, + } +} + +func getCoreURL(org *types.Organization) string { + host := fmt.Sprintf("firefly_core_%v", org.ID) + if org.External { + host = "host.docker.internal" + } + return fmt.Sprintf("http://%s:%v", host, org.ExposedFireflyPort) +} diff --git a/internal/blockchain/tezos/connector/tezosconnect/docker.go b/internal/blockchain/tezos/connector/tezosconnect/docker.go new file mode 100644 index 00000000..95d5286b --- /dev/null +++ b/internal/blockchain/tezos/connector/tezosconnect/docker.go @@ -0,0 +1,54 @@ +// Copyright © 2023 Kaleido, Inc. +// +// SPDX-License-Identifier: Apache-2.0 +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package tezosconnect + +import ( + "fmt" + + "github.com/hyperledger/firefly-cli/internal/docker" + "github.com/hyperledger/firefly-cli/pkg/types" +) + +func (t *Tezosconnect) GetServiceDefinitions(s *types.Stack, dependentServices map[string]string) []*docker.ServiceDefinition { + dependsOn := make(map[string]map[string]string) + for dep, state := range dependentServices { + dependsOn[dep] = map[string]string{"condition": state} + } + serviceDefinitions := make([]*docker.ServiceDefinition, len(s.Members)) + for i, member := range s.Members { + serviceDefinitions[i] = &docker.ServiceDefinition{ + ServiceName: "tezosconnect_" + member.ID, + Service: &docker.Service{ + Image: s.VersionManifest.Tezosconnect.GetDockerImageString(), + ContainerName: fmt.Sprintf("%s_tezosconnect_%v", s.Name, i), + Command: "-f /tezosconnect/config/config.yaml", + DependsOn: dependsOn, + Ports: []string{fmt.Sprintf("%d:%v", member.ExposedConnectorPort, t.Port())}, + Volumes: []string{ + fmt.Sprintf("tezosconnect_config_%s:/tezosconnect/config", member.ID), + fmt.Sprintf("tezosconnect_leveldb_%s:/tezosconnect/leveldb", member.ID), + }, + Logging: docker.StandardLogOptions, + }, + VolumeNames: []string{ + fmt.Sprintf("tezosconnect_config_%s", member.ID), + fmt.Sprintf("tezosconnect_leveldb_%s", member.ID), + }, + } + } + return serviceDefinitions +} diff --git a/internal/blockchain/tezos/remoterpc/remoterpc_provider.go b/internal/blockchain/tezos/remoterpc/remoterpc_provider.go new file mode 100644 index 00000000..d7f62597 --- /dev/null +++ b/internal/blockchain/tezos/remoterpc/remoterpc_provider.go @@ -0,0 +1,165 @@ +// Copyright © 2023 Kaleido, Inc. +// +// SPDX-License-Identifier: Apache-2.0 +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package remoterpc + +import ( + "context" + "errors" + "fmt" + "path/filepath" + + "github.com/hyperledger/firefly-cli/internal/blockchain/tezos" + "github.com/hyperledger/firefly-cli/internal/blockchain/tezos/connector" + "github.com/hyperledger/firefly-cli/internal/blockchain/tezos/connector/tezosconnect" + + "github.com/hyperledger/firefly-cli/internal/constants" + "github.com/hyperledger/firefly-cli/internal/docker" + "github.com/hyperledger/firefly-cli/pkg/types" +) + +type RemoteRPCProvider struct { + ctx context.Context + stack *types.Stack + connector connector.Connector +} + +func NewRemoteRPCProvider(ctx context.Context, stack *types.Stack) *RemoteRPCProvider { + return &RemoteRPCProvider{ + ctx: ctx, + stack: stack, + connector: tezosconnect.NewTezosconnect(ctx), + } +} + +func (p *RemoteRPCProvider) WriteConfig(options *types.InitOptions) error { + initDir := filepath.Join(constants.StacksDir, p.stack.Name, "init") + for i, member := range p.stack.Members { + // Generate the connector config for each member + connectorConfigPath := filepath.Join(initDir, "config", fmt.Sprintf("%s_%v.yaml", p.connector.Name(), i)) + if err := p.connector.GenerateConfig(p.stack, member).WriteConfig(connectorConfigPath, options.ExtraConnectorConfigPath); err != nil { + return err + } + } + + return nil +} + +func (p *RemoteRPCProvider) FirstTimeSetup() error { + for i := range p.stack.Members { + // Copy connector config to each member's volume + connectorConfigPath := filepath.Join(p.stack.StackDir, "runtime", "config", fmt.Sprintf("%s_%v.yaml", p.connector.Name(), i)) + connectorConfigVolumeName := fmt.Sprintf("%s_%s_config_%v", p.stack.Name, p.connector.Name(), i) + docker.CopyFileToVolume(p.ctx, connectorConfigVolumeName, connectorConfigPath, "config.yaml") + } + + return nil +} + +func (p *RemoteRPCProvider) PreStart() error { + return nil +} + +func (p *RemoteRPCProvider) PostStart(fistTimeSetup bool) error { + return nil +} + +func (p *RemoteRPCProvider) DeployFireFlyContract() (*types.ContractDeploymentResult, error) { + return nil, fmt.Errorf("you must pre-deploy your FireFly contract when using a remote RPC endpoint") +} + +func (p *RemoteRPCProvider) GetDockerServiceDefinitions() []*docker.ServiceDefinition { + defs := p.connector.GetServiceDefinitions(p.stack, map[string]string{}) + return defs +} + +func (p *RemoteRPCProvider) GetBlockchainPluginConfig(stack *types.Stack, m *types.Organization) (blockchainConfig *types.BlockchainConfig) { + var connectorURL string + if m.External { + connectorURL = p.GetConnectorExternalURL(m) + } else { + connectorURL = p.GetConnectorURL(m) + } + + blockchainConfig = &types.BlockchainConfig{ + Type: "tezos", + Tezos: &types.TezosConfig{ + Tezosconnect: &types.TezosconnectConfig{ + URL: connectorURL, + Topic: m.ID, + }, + }, + } + return +} + +func (p *RemoteRPCProvider) GetOrgConfig(stack *types.Stack, m *types.Organization) (orgConfig *types.OrgConfig) { + account := m.Account.(*tezos.Account) + orgConfig = &types.OrgConfig{ + Name: m.OrgName, + Key: account.Address, + } + return +} + +func (p *RemoteRPCProvider) Reset() error { + return nil +} + +func (p *RemoteRPCProvider) GetContracts(filename string, extraArgs []string) ([]string, error) { + // TODO: to implement + return nil, errors.New("not implemented") +} + +func (p *RemoteRPCProvider) DeployContract(filename, contractName, instanceName string, member *types.Organization, extraArgs []string) (*types.ContractDeploymentResult, error) { + // TODO: to implement + return nil, errors.New("not implemented") +} + +func (p *RemoteRPCProvider) CreateAccount(args []string) (interface{}, error) { + // Currently, accounts (private/public keys) created by FireFly are not involved in the tx signing process. + // Accounts should be created in any key management system supported by the signatory service https://signatory.io/ + // And then account address (derivative of the public key) must be provided during each transaction sending via FireFly + address, pk, err := tezos.GenerateAddressAndPrivateKey() + if err != nil { + return nil, err + } + + return &tezos.Account{ + Address: address, + PrivateKey: pk, + }, nil +} + +func (p *RemoteRPCProvider) GetConnectorName() string { + return p.connector.Name() +} + +func (p *RemoteRPCProvider) GetConnectorURL(org *types.Organization) string { + return fmt.Sprintf("http://%s_%s:%v", p.connector.Name(), org.ID, p.connector.Port()) +} + +func (p *RemoteRPCProvider) GetConnectorExternalURL(org *types.Organization) string { + return fmt.Sprintf("http://127.0.0.1:%v", org.ExposedConnectorPort) +} + +func (p *RemoteRPCProvider) ParseAccount(account interface{}) interface{} { + accountMap := account.(map[string]interface{}) + return &tezos.Account{ + Address: accountMap["address"].(string), + PrivateKey: accountMap["privateKey"].(string), + } +} diff --git a/internal/blockchain/tezos/tezos.go b/internal/blockchain/tezos/tezos.go new file mode 100644 index 00000000..697ae626 --- /dev/null +++ b/internal/blockchain/tezos/tezos.go @@ -0,0 +1,33 @@ +// Copyright © 2023 Kaleido, Inc. +// +// SPDX-License-Identifier: Apache-2.0 +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package tezos + +import tz "blockwatch.cc/tzgo/tezos" + +type Account struct { + Address string `json:"address"` + PrivateKey string `json:"privateKey"` +} + +func GenerateAddressAndPrivateKey() (address string, privateKey string, err error) { + prk, err := tz.GenerateKey(tz.KeyTypeEd25519) + if err != nil { + return "", "", err + } + + return prk.Address().String(), prk.String(), nil +} diff --git a/internal/core/config.go b/internal/core/config.go index d62b2dae..77c49055 100644 --- a/internal/core/config.go +++ b/internal/core/config.go @@ -18,7 +18,7 @@ package core import ( "fmt" - "io/ioutil" + "os" "path" "github.com/hyperledger/firefly-cli/pkg/types" @@ -177,7 +177,7 @@ func getDataExchangeURL(member *types.Organization) string { } func ReadFireflyConfig(filePath string) (*types.FireflyConfig, error) { - if bytes, err := ioutil.ReadFile(filePath); err != nil { + if bytes, err := os.ReadFile(filePath); err != nil { return nil, err } else { var config *types.FireflyConfig @@ -190,7 +190,7 @@ func WriteFireflyConfig(config *types.FireflyConfig, filePath, extraCoreConfigPa if bytes, err := yaml.Marshal(config); err != nil { return err } else { - if err := ioutil.WriteFile(filePath, bytes, 0755); err != nil { + if err := os.WriteFile(filePath, bytes, 0755); err != nil { return err } } @@ -203,7 +203,7 @@ func WriteFireflyConfig(config *types.FireflyConfig, filePath, extraCoreConfigPa if err != nil { return err } - if err := ioutil.WriteFile(filePath, bytes, 0755); err != nil { + if err := os.WriteFile(filePath, bytes, 0755); err != nil { return err } } diff --git a/internal/core/http.go b/internal/core/http.go index b7b2e156..b9699277 100644 --- a/internal/core/http.go +++ b/internal/core/http.go @@ -22,7 +22,6 @@ import ( "encoding/json" "fmt" "io" - "io/ioutil" "net/http" "time" @@ -89,7 +88,7 @@ func request(method, url string, body, result interface{}) (err error) { if resp.StatusCode < 200 || resp.StatusCode >= 300 { var responseBytes []byte if resp.StatusCode != 204 { - responseBytes, _ = ioutil.ReadAll(resp.Body) + responseBytes, _ = io.ReadAll(resp.Body) } return fmt.Errorf("%s [%d] %s", url, resp.StatusCode, responseBytes) } diff --git a/internal/core/manifest.go b/internal/core/manifest.go index 0a96fc44..fe555be8 100644 --- a/internal/core/manifest.go +++ b/internal/core/manifest.go @@ -19,7 +19,7 @@ package core import ( "encoding/json" "fmt" - "io/ioutil" + "os" "github.com/hyperledger/firefly-cli/internal/constants" "github.com/hyperledger/firefly-cli/internal/docker" @@ -103,7 +103,7 @@ func getSHA(imageName, imageTag string) (string, error) { } func ReadManifestFile(p string) (*types.VersionManifest, error) { - d, err := ioutil.ReadFile(p) + d, err := os.ReadFile(p) if err != nil { return nil, err } diff --git a/internal/stacks/stack_manager.go b/internal/stacks/stack_manager.go index 400f8db4..33dff0af 100644 --- a/internal/stacks/stack_manager.go +++ b/internal/stacks/stack_manager.go @@ -20,7 +20,6 @@ import ( "context" "encoding/json" "fmt" - "io/ioutil" "net" "os" "os/exec" @@ -35,8 +34,9 @@ import ( "github.com/hyperledger/firefly-cli/internal/blockchain" "github.com/hyperledger/firefly-cli/internal/blockchain/ethereum/besu" "github.com/hyperledger/firefly-cli/internal/blockchain/ethereum/geth" - "github.com/hyperledger/firefly-cli/internal/blockchain/ethereum/remoterpc" + ethremoterpc "github.com/hyperledger/firefly-cli/internal/blockchain/ethereum/remoterpc" "github.com/hyperledger/firefly-cli/internal/blockchain/fabric" + tezosremoterpc "github.com/hyperledger/firefly-cli/internal/blockchain/tezos/remoterpc" "github.com/hyperledger/firefly-cli/internal/constants" "github.com/hyperledger/firefly-cli/internal/core" "github.com/hyperledger/firefly-cli/internal/docker" @@ -350,7 +350,7 @@ func (s *StackManager) loadStackStateJSON() error { return err } - b, err := ioutil.ReadFile(stackStatePath) + b, err := os.ReadFile(stackStatePath) if err != nil { return err } @@ -374,7 +374,7 @@ func (s *StackManager) writeStackStateJSON(directory string) error { if err != nil { return err } - return ioutil.WriteFile(filepath.Join(directory, "stackState.json"), stackStateBytes, 0755) + return os.WriteFile(filepath.Join(directory, "stackState.json"), stackStateBytes, 0755) } func (s *StackManager) ensureInitDirectories() error { @@ -401,7 +401,7 @@ func (s *StackManager) writeDockerCompose(compose *docker.DockerComposeConfig) e return err } bytes = append(bytes, yamlBytes...) - return ioutil.WriteFile(filepath.Join(s.Stack.StackDir, "docker-compose.yml"), bytes, 0755) + return os.WriteFile(filepath.Join(s.Stack.StackDir, "docker-compose.yml"), bytes, 0755) } func (s *StackManager) writeDockerComposeOverride(compose *docker.DockerComposeConfig) error { @@ -412,7 +412,7 @@ func (s *StackManager) writeDockerComposeOverride(compose *docker.DockerComposeC return err } bytes = append(bytes, yamlBytes...) - return ioutil.WriteFile(filepath.Join(s.Stack.StackDir, "docker-compose.override.yml"), bytes, 0755) + return os.WriteFile(filepath.Join(s.Stack.StackDir, "docker-compose.override.yml"), bytes, 0755) } func (s *StackManager) writeStackConfig() error { @@ -420,7 +420,7 @@ func (s *StackManager) writeStackConfig() error { if err != nil { return err } - return ioutil.WriteFile(filepath.Join(s.Stack.StackDir, "stack.json"), stackConfigBytes, 0755) + return os.WriteFile(filepath.Join(s.Stack.StackDir, "stack.json"), stackConfigBytes, 0755) } func (s *StackManager) writeConfig(options *types.InitOptions) error { @@ -472,7 +472,7 @@ func (s *StackManager) writeConfig(options *types.InitOptions) error { if err != nil { return err } - if err := ioutil.WriteFile(path.Join(s.Stack.InitDir, "config", "prometheus.yml"), configBytes, 0755); err != nil { + if err := os.WriteFile(path.Join(s.Stack.InitDir, "config", "prometheus.yml"), configBytes, 0755); err != nil { return err } } @@ -498,7 +498,7 @@ func (s *StackManager) writeDataExchangeCerts() error { if err != nil { return err } - if err := ioutil.WriteFile(path.Join(memberDXDir, "config.json"), configBytes, 0755); err != nil { + if err := os.WriteFile(path.Join(memberDXDir, "config.json"), configBytes, 0755); err != nil { return err } } @@ -1050,7 +1050,7 @@ func (s *StackManager) UpgradeStack(version string) error { } func replaceVersions(oldManifest, newManifest *types.VersionManifest, filename string) error { - b, err := ioutil.ReadFile(filename) + b, err := os.ReadFile(filename) if err != nil { return err } @@ -1068,6 +1068,10 @@ func replaceVersions(oldManifest, newManifest *types.VersionManifest, filename s new = newManifest.Evmconnect.GetDockerImageString() s = strings.Replace(s, old, new, -1) + old = oldManifest.Tezosconnect.GetDockerImageString() + new = newManifest.Tezosconnect.GetDockerImageString() + s = strings.Replace(s, old, new, -1) + old = oldManifest.Fabconnect.GetDockerImageString() new = newManifest.Fabconnect.GetDockerImageString() s = strings.Replace(s, old, new, -1) @@ -1088,9 +1092,42 @@ func replaceVersions(oldManifest, newManifest *types.VersionManifest, filename s new = newManifest.Signer.GetDockerImageString() s = strings.Replace(s, old, new, -1) - return ioutil.WriteFile(filename, []byte(s), 0755) + return os.WriteFile(filename, []byte(s), 0755) +} + +// initTabwriter takes the stackManger, the format of the Header row and a variadic arguement +// of strings (Headers) that is expected to comply with the Header format. It returns a Writer with sane defaults +// to write the body row. +func initTabwriter(s *StackManager, formatHeader string, headers ...interface{}) *tabwriter.Writer { + w := new(tabwriter.Writer) + w.Init(os.Stdout, 8, 8, 8, ' ', 0) + s.once.Do(func() { + fmt.Fprintf(w, formatHeader, headers...) + }) + return w } +// PrintStacksInfo prints to os.Stdout information about the stack. +func (s *StackManager) PrintStacksInfo() error { + formatHeader := "%-15s %-22s %-10s %-20s %-25s\n" + formatBody := " %-18s %-18s %-7s %-14s %-20s\n" + + w := initTabwriter(s, formatHeader, "STACK-NAME", "BLOCKCHAIN-PROVIDER", "MEMBERS", "STATUS", "DOCKER COMPOSE DIR") + + status, err := isRunning(s) + if err != nil { + return err + } + + if status { + fmt.Fprintf(w, formatBody, s.Stack.Name, s.Stack.BlockchainProvider, fmt.Sprint(len(s.Stack.Members)), "running", filepath.Join(s.Stack.StackDir, "docker-compose.yml")) + } else { + fmt.Fprintf(w, formatBody, s.Stack.Name, s.Stack.BlockchainProvider, fmt.Sprint(len(s.Stack.Members)), "not_running", filepath.Join(s.Stack.StackDir, "docker-compose.yml")) + } + fmt.Fprintln(w) + w.Flush() + return nil +} func (s *StackManager) PrintStackInfo() error { fmt.Print("\n") if err := s.runDockerComposeCommand("images"); err != nil { @@ -1106,31 +1143,40 @@ func (s *StackManager) PrintStackInfo() error { // IsRunning prints to the stdout, the stack name and it status as "running" or "not_running". func (s *StackManager) IsRunning() error { - output, err := docker.RunDockerComposeCommandReturnsStdout(s.Stack.StackDir, "ps") + formatHeader := " %-15s %-20s\n" + formatBody := " %-13s %-20s" + + w := initTabwriter(s, formatHeader, "STACK-NAME", "STATUS") + + status, err := isRunning(s) if err != nil { return err } - formatHeader := "\n %s\t%s\t " - formatBody := "\n %s\t%s\t" - - w := new(tabwriter.Writer) - w.Init(os.Stdout, 8, 8, 8, '\t', 0) - - s.once.Do(func() { - fmt.Fprintf(w, formatHeader, "STACK", "STATUS") - }) - - if strings.Contains(string(output), s.Stack.Name) { // if the output contains the stack name, it means the container is running. + if status { fmt.Fprintf(w, formatBody, s.Stack.Name, "running") } else { fmt.Fprintf(w, formatBody, s.Stack.Name, "not_running") } fmt.Fprintln(w) w.Flush() + return nil } +// isRunning returns true if a stack on the local machine is currently running, otherwise false. +func isRunning(s *StackManager) (bool, error) { + output, err := docker.RunDockerComposeCommandReturnsStdout(s.Stack.StackDir, "ps") + if err != nil { + return false, err + } + if strings.Contains(string(output), s.Stack.Name) { // from running `docker compose ps`, if the output contains the stack name, it means the container is running. + return true, nil + } + + return false, nil +} + func (s *StackManager) disableFireflyCoreContainers() error { compose := s.buildDockerCompose() for _, member := range s.Stack.Members { @@ -1162,7 +1208,7 @@ func (s *StackManager) patchFireFlyCoreConfigs(workingDir string, org *types.Org if err != nil { return err } - if err = ioutil.WriteFile(configFile, configData, 0755); err != nil { + if err = os.WriteFile(configFile, configData, 0755); err != nil { return err } } @@ -1250,10 +1296,13 @@ func (s *StackManager) getBlockchainProvider() blockchain.IBlockchainProvider { return besu.NewBesuProvider(s.ctx, s.Stack) case types.BlockchainNodeProviderRemoteRPC: s.Stack.DisableTokenFactories = true - return remoterpc.NewRemoteRPCProvider(s.ctx, s.Stack) + return ethremoterpc.NewRemoteRPCProvider(s.ctx, s.Stack) default: return nil } + case types.BlockchainProviderTezos: + s.Stack.DisableTokenFactories = true + return tezosremoterpc.NewRemoteRPCProvider(s.ctx, s.Stack) case types.BlockchainProviderFabric: s.Stack.DisableTokenFactories = true return fabric.NewFabricProvider(s.ctx, s.Stack) diff --git a/pkg/types/firefly_config.go b/pkg/types/firefly_config.go index 63968032..f3d16a0a 100644 --- a/pkg/types/firefly_config.go +++ b/pkg/types/firefly_config.go @@ -72,6 +72,12 @@ type EthconnectConfig struct { Auth *BasicAuth `yaml:"auth,omitempty"` } +type TezosconnectConfig struct { + URL string `yaml:"url,omitempty"` + Topic string `yaml:"topic,omitempty"` + Auth *BasicAuth `yaml:"auth,omitempty"` +} + type FabconnectConfig struct { URL string `yaml:"url,omitempty"` Channel string `yaml:"channel,omitempty"` @@ -84,6 +90,10 @@ type EthereumConfig struct { Ethconnect *EthconnectConfig `yaml:"ethconnect,omitempty"` } +type TezosConfig struct { + Tezosconnect *TezosconnectConfig `yaml:"tezosconnect,omitempty"` +} + type FabricConfig struct { Fabconnect *FabconnectConfig `yaml:"fabconnect,omitempty"` } @@ -92,6 +102,7 @@ type BlockchainConfig struct { Name string `yaml:"name,omitempty"` Type string `yaml:"type,omitempty"` Ethereum *EthereumConfig `yaml:"ethereum,omitempty"` + Tezos *TezosConfig `yaml:"tezos,omitempty"` Fabric *FabricConfig `yaml:"fabric,omitempty"` } diff --git a/pkg/types/manifest.go b/pkg/types/manifest.go index 5e1de355..039b1188 100644 --- a/pkg/types/manifest.go +++ b/pkg/types/manifest.go @@ -26,6 +26,7 @@ type VersionManifest struct { FireFly *ManifestEntry `json:"firefly,omitempty"` Ethconnect *ManifestEntry `json:"ethconnect"` Evmconnect *ManifestEntry `json:"evmconnect"` + Tezosconnect *ManifestEntry `json:"tezosconnect"` Fabconnect *ManifestEntry `json:"fabconnect"` DataExchange *ManifestEntry `json:"dataexchange-https"` TokensERC1155 *ManifestEntry `json:"tokens-erc1155"` @@ -41,6 +42,7 @@ func (m *VersionManifest) Entries() []*ManifestEntry { m.FireFly, m.Ethconnect, m.Evmconnect, + m.Tezosconnect, m.Fabconnect, m.DataExchange, m.TokensERC1155, diff --git a/pkg/types/options.go b/pkg/types/options.go index ca593e42..38a9f218 100644 --- a/pkg/types/options.go +++ b/pkg/types/options.go @@ -76,6 +76,7 @@ const BlockchainProvider = "blockchain_provider" var ( BlockchainProviderEthereum = fftypes.FFEnumValue(BlockchainProvider, "ethereum") + BlockchainProviderTezos = fftypes.FFEnumValue(BlockchainProvider, "tezos") BlockchainProviderFabric = fftypes.FFEnumValue(BlockchainProvider, "fabric") BlockchainProviderCorda = fftypes.FFEnumValue(BlockchainProvider, "corda") ) @@ -83,9 +84,10 @@ var ( const BlockchainConnector = "blockchain_connector" var ( - BlockchainConnectorEthconnect = fftypes.FFEnumValue(BlockchainConnector, "ethconnect") - BlockchainConnectorEvmconnect = fftypes.FFEnumValue(BlockchainConnector, "evmconnect") - BlockchainConnectorFabconnect = fftypes.FFEnumValue(BlockchainConnector, "fabric") + BlockchainConnectorEthconnect = fftypes.FFEnumValue(BlockchainConnector, "ethconnect") + BlockchainConnectorEvmconnect = fftypes.FFEnumValue(BlockchainConnector, "evmconnect") + BlockchainConnectorTezosconnect = fftypes.FFEnumValue(BlockchainConnector, "tezosconnect") + BlockchainConnectorFabconnect = fftypes.FFEnumValue(BlockchainConnector, "fabric") ) const BlockchainNodeProvider = "blockchain_node_provider"