github.com/aeternity/aepp-sdk-go/v6@v6.0.0/cmd/chain.go (about) 1 // Copyright © 2018 NAME HERE <EMAIL ADDRESS> 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package cmd 16 17 import ( 18 "errors" 19 "fmt" 20 21 "github.com/aeternity/aepp-sdk-go/v6/binary" 22 "github.com/aeternity/aepp-sdk-go/v6/config" 23 "github.com/aeternity/aepp-sdk-go/v6/naet" 24 "github.com/spf13/cobra" 25 ) 26 27 // chainCmd represents the chain command 28 var chainCmd = &cobra.Command{ 29 Use: "chain", 30 Short: "Query the state of the chain", 31 Long: ``, 32 } 33 34 var topCmd = &cobra.Command{ 35 Use: "top", 36 Short: "Query the top block of the chain", 37 Long: ``, 38 RunE: func(cmd *cobra.Command, args []string) error { 39 node := newAeNode() 40 return topFunc(node, args) 41 }, 42 } 43 44 func topFunc(conn naet.GetTopBlocker, args []string) error { 45 v, err := conn.GetTopBlock() 46 if err != nil { 47 return err 48 } 49 PrintObject("block", v) 50 return nil 51 } 52 53 var statusCmd = &cobra.Command{ 54 Use: "status", 55 Short: "Get the status and status of the node running the chain", 56 Long: ``, 57 RunE: func(cmd *cobra.Command, args []string) error { 58 node := newAeNode() 59 return statusFunc(node, args) 60 }, 61 } 62 63 func statusFunc(conn naet.GetStatuser, args []string) (err error) { 64 v, err := conn.GetStatus() 65 if err != nil { 66 return err 67 } 68 PrintObject("node", v) 69 return nil 70 } 71 72 var limit, startFromHeight uint64 73 var playCmd = &cobra.Command{ 74 Use: "play", 75 Short: "Query the blocks of the chain one after the other", 76 Long: ``, 77 RunE: func(cmd *cobra.Command, args []string) error { 78 node := newAeNode() 79 return playFunc(node, args) 80 }, 81 } 82 83 type playFuncInterface interface { 84 naet.GetHeighter 85 getGenerationMicroBlockTransactioner 86 } 87 88 func playFunc(conn playFuncInterface, args []string) (err error) { 89 blockHeight, err := conn.GetHeight() 90 if err != nil { 91 return err 92 } 93 94 // deal with the height parameter 95 if startFromHeight > blockHeight { 96 err := fmt.Errorf("Height (%d) is greater that the top block (%d)", startFromHeight, blockHeight) 97 return err 98 } 99 100 if startFromHeight > 0 { 101 blockHeight = startFromHeight 102 } 103 // deal with the limit parameter 104 targetHeight := uint64(0) 105 if limit > 0 { 106 th := blockHeight - limit 107 if th > targetHeight { 108 targetHeight = th 109 } 110 } 111 // run the play 112 for ; blockHeight > targetHeight; blockHeight-- { 113 PrintGenerationByHeight(conn, blockHeight) 114 fmt.Println("") 115 } 116 117 return nil 118 } 119 120 var broadcastCmd = &cobra.Command{ 121 Use: "broadcast SIGNED_TRANSACTION", 122 Short: "Broadcast a transaction to the network", 123 Long: ``, 124 Args: cobra.ExactArgs(1), 125 RunE: func(cmd *cobra.Command, args []string) error { 126 node := newAeNode() 127 return broadcastFunc(node, args) 128 }, 129 } 130 131 func broadcastFunc(conn naet.PostTransactioner, args []string) (err error) { 132 // Load variables from arguments 133 txSignedBase64 := args[0] 134 135 if len(txSignedBase64) == 0 || txSignedBase64[0:3] != "tx_" { 136 err := errors.New("Error, missing or invalid recipient address") 137 return err 138 } 139 140 // Transform tx_ string back to an RLP bytearray to calculate its hash 141 txRLP, err := binary.Decode(txSignedBase64) 142 if err != nil { 143 return err 144 } 145 rlpTxHashRaw, err := binary.Blake2bHash(txRLP) 146 if err != nil { 147 return err 148 } 149 signedEncodedTxHash := binary.Encode(binary.PrefixTransactionHash, rlpTxHashRaw) 150 151 err = conn.PostTransaction(txSignedBase64, signedEncodedTxHash) 152 if err != nil { 153 errFinal := fmt.Errorf("Error while broadcasting transaction: %v", err) 154 return errFinal 155 } 156 157 return nil 158 } 159 160 var ttlCmd = &cobra.Command{ 161 Use: "ttl", 162 Short: "Get the absolute TTL for a Transaction", 163 Long: `Get the absolute TTL (node's height + recommended TTL offset) for a Transaction`, 164 Args: cobra.ExactArgs(0), 165 RunE: func(cmd *cobra.Command, args []string) error { 166 node := newAeNode() 167 return ttlFunc(node, args) 168 }, 169 } 170 171 func ttlFunc(conn naet.GetHeighter, args []string) (err error) { 172 height, err := conn.GetHeight() 173 if err != nil { 174 errFinal := fmt.Errorf("Error getting height from the node: %v", err) 175 return errFinal 176 } 177 ttl = height + config.Client.TTL 178 fmt.Println(ttl) 179 return nil 180 } 181 182 var networkIDCmd = &cobra.Command{ 183 Use: "networkid", 184 Short: "Get the node's network_id", 185 Long: ``, 186 Args: cobra.ExactArgs(0), 187 RunE: func(cmd *cobra.Command, args []string) error { 188 node := newAeNode() 189 return networkIDFunc(node, args) 190 }, 191 } 192 193 func networkIDFunc(conn naet.GetStatuser, args []string) (err error) { 194 resp, err := conn.GetStatus() 195 if err != nil { 196 errFinal := fmt.Errorf("Error getting status information from the node: %v", err) 197 return errFinal 198 } 199 fmt.Println(*resp.NetworkID) 200 return nil 201 } 202 203 func init() { 204 RootCmd.AddCommand(chainCmd) 205 chainCmd.AddCommand(topCmd) 206 chainCmd.AddCommand(statusCmd) 207 chainCmd.AddCommand(playCmd) 208 chainCmd.AddCommand(broadcastCmd) 209 chainCmd.AddCommand(ttlCmd) 210 chainCmd.AddCommand(networkIDCmd) 211 212 playCmd.Flags().Uint64Var(&limit, "limit", 0, "Print at max 'limit' generations") 213 playCmd.Flags().Uint64Var(&startFromHeight, "height", 0, "Start playing the chain at 'height'") 214 215 // Here you will define your flags and configuration settings. 216 217 // Cobra supports Persistent Flags which will work for this command 218 // and all subcommands, e.g.: 219 // chainCmd.PersistentFlags().String("foo", "", "A help for foo") 220 221 // Cobra supports local flags which will only run when this command 222 // is called directly, e.g.: 223 // chainCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle") 224 225 }