aboutsummaryrefslogblamecommitdiffstats
path: root/dev_console.go
blob: 91d911ec20d54ca104d97af5b8d41a62507f6ee6 (plain) (tree)
1
2
3
4
5
6
7
8
9


            



                      

                                         

                                        
                                        
                    

                 

 
                     


                                   

 
                                           

                                       
 
                                                        

 
                                                                          

                           
 









                                                       





                                                       


                                                      


                                                   


                                                        


                                                         





                                                     
         
 




                                                                                                                    

 








                                                               
                                                 

                                                             
 








                                                              
 


                             
 





                                                  
                                                            
 
                                     
                           
                                                           
                            
                                     
                               
                                                 


                                    
                                                                                         

                                                                 


                                                                    

                                                                 
                                                                                              





                                                                           



                                                                          

                                                                     


















                                                                                                            
                          
                                                                                                      
                                                     
 
                                                              








                                                                      




                                                                                                                 









                                                                                                      
                                                                                                       
                                                                
                                                




                                                             
 



                                                                  
 
                   

 
                           












                                                               
 
package main

import (
    "bufio"
    "encoding/hex"
    "errors"
    "fmt"
    "github.com/ethereum/eth-go"
    "github.com/ethereum/ethchain-go"
    "github.com/ethereum/ethdb-go"
    "github.com/ethereum/ethutil-go"
    "github.com/ethereum/ethwire-go"
    _ "math/big"
    "os"
    "strings"
)

type Console struct {
    db       *ethdb.MemDatabase
    trie     *ethutil.Trie
    ethereum *eth.Ethereum
}

func NewConsole(s *eth.Ethereum) *Console {
    db, _ := ethdb.NewMemDatabase()
    trie := ethutil.NewTrie(db, "")

    return &Console{db: db, trie: trie, ethereum: s}
}

func (i *Console) ValidateInput(action string, argumentLength int) error {
    err := false
    var expArgCount int

    switch {
    case action == "update" && argumentLength != 2:
        err = true
        expArgCount = 2
    case action == "get" && argumentLength != 1:
        err = true
        expArgCount = 1
    case action == "dag" && argumentLength != 2:
        err = true
        expArgCount = 2
    case action == "decode" && argumentLength != 1:
        err = true
        expArgCount = 1
    case action == "encode" && argumentLength != 1:
        err = true
        expArgCount = 1
    case action == "gettx" && argumentLength != 1:
        err = true
        expArgCount = 1
    case action == "tx" && argumentLength != 2:
        err = true
        expArgCount = 2
    case action == "getaddr" && argumentLength != 1:
        err = true
        expArgCount = 1
    case action == "contract" && argumentLength != 1:
        err = true
        expArgCount = 1
    case action == "say" && argumentLength != 1:
        err = true
        expArgCount = 1
    case action == "addp" && argumentLength != 1:
        err = true
        expArgCount = 1
    }

    if err {
        return errors.New(fmt.Sprintf("'%s' requires %d args, got %d", action, expArgCount, argumentLength))
    } else {
        return nil
    }
}

func (i *Console) PrintRoot() {
    root := ethutil.Conv(i.trie.RootT)
    if len(root.AsBytes()) != 0 {
        fmt.Println(hex.EncodeToString(root.AsBytes()))
    } else {
        fmt.Println(i.trie.RootT)
    }
}

func (i *Console) ParseInput(input string) bool {
    scanner := bufio.NewScanner(strings.NewReader(input))
    scanner.Split(bufio.ScanWords)

    count := 0
    var tokens []string
    for scanner.Scan() {
        count++
        tokens = append(tokens, scanner.Text())
    }
    if err := scanner.Err(); err != nil {
        fmt.Fprintln(os.Stderr, "reading input:", err)
    }

    if len(tokens) == 0 {
        return true
    }

    err := i.ValidateInput(tokens[0], count-1)
    if err != nil {
        fmt.Println(err)
    } else {
        switch tokens[0] {
        case "update":
            i.trie.UpdateT(tokens[1], tokens[2])

            i.PrintRoot()
        case "get":
            fmt.Println(i.trie.GetT(tokens[1]))
        case "root":
            i.PrintRoot()
        case "rawroot":
            fmt.Println(i.trie.RootT)
        case "print":
            i.db.Print()
        case "dag":
            fmt.Println(ethchain.DaggerVerify(ethutil.Big(tokens[1]), // hash
                ethutil.BigPow(2, 36),   // diff
                ethutil.Big(tokens[2]))) // nonce
        case "decode":
            d, _ := ethutil.Decode([]byte(tokens[1]), 0)
            fmt.Printf("%q\n", d)
        case "getaddr":
            encoded, _ := hex.DecodeString(tokens[1])
            d := i.ethereum.BlockManager.CurrentBlock.State().Get(string(encoded))
            if d != "" {
                decoder := ethutil.NewRlpDecoder([]byte(d))
                fmt.Println(decoder)
            } else {
                fmt.Println("getaddr: address unknown")
            }
        case "say":
            i.ethereum.Broadcast(ethwire.MsgTalkTy, tokens[1])
        case "addp":
            i.ethereum.ConnectToPeer(tokens[1])
        case "encode":
            fmt.Printf("%q\n", ethutil.Encode(tokens[1]))
            /*
                case "newblk":
                    block := ethchain.CreateBlock(
                        i.ethereum.BlockManager.BlockChain().LastBlock.State().Root,
                        i.ethereum.BlockManager.LastBlockHash,
                        "123",
                        big.NewInt(1),
                        big.NewInt(1),
                        "",
                        i.ethereum.TxPool.Flush(),
                    )
                    err := i.ethereum.BlockManager.ProcessBlock(block)
                    if err != nil {
                        fmt.Println(err)
                    } else {
                        i.ethereum.Broadcast(ethwire.MsgBlockTy, block.RlpData())
                    }
                    //fmt.Println(ethutil.NewRlpValue(block.RlpData()).Get(0))
            */
        case "tx":
            tx := ethchain.NewTransaction(tokens[1], ethutil.Big(tokens[2]), []string{""})
            fmt.Printf("%x\n", tx.Hash())

            i.ethereum.TxPool.QueueTransaction(tx)
        case "gettx":
            addr, _ := hex.DecodeString(tokens[1])
            data, _ := ethutil.Config.Db.Get(addr)
            if len(data) != 0 {
                decoder := ethutil.NewRlpDecoder(data)
                fmt.Println(decoder)
            } else {
                fmt.Println("gettx: tx not found")
            }
        case "contract":
            contract := ethchain.NewTransaction("", ethutil.Big(tokens[1]), []string{"PUSH", "1234"})
            fmt.Printf("%x\n", contract.Hash())

            i.ethereum.TxPool.QueueTransaction(contract)
        case "exit", "quit", "q":
            return false
        case "help":
            fmt.Printf("COMMANDS:\n" +
                "\033[1m= DB =\033[0m\n" +
                "update KEY VALUE - Updates/Creates a new value for the given key\n" +
                "get KEY - Retrieves the given key\n" +
                "root - Prints the hex encoded merkle root\n" +
                "rawroot - Prints the raw merkle root\n" +
                "\033[1m= Dagger =\033[0m\n" +
                "dag HASH NONCE - Verifies a nonce with the given hash with dagger\n" +
                "\033[1m= Encoding =\033[0m\n" +
                "decode STR\n" +
                "encode STR\n" +
                "\033[1m= Other =\033[0m\n" +
                "addp HOST:PORT\n" +
                "tx TO AMOUNT\n" +
                "contract AMOUNT\n")

        default:
            fmt.Println("Unknown command:", tokens[0])
        }
    }

    return true
}

func (i *Console) Start() {
    fmt.Printf("Eth Console. Type (help) for help\n")
    reader := bufio.NewReader(os.Stdin)
    for {
        fmt.Printf("eth >>> ")
        str, _, err := reader.ReadLine()
        if err != nil {
            fmt.Println("Error reading input", err)
        } else {
            if !i.ParseInput(string(str)) {
                return
            }
        }
    }
}