go-dvote/chain/chain.go
chain/chain.goRaw
1package chain
2
3import (
4 "context"
5 "fmt"
6 "log"
7 "math/big"
8 "time"
9
10 "github.com/ethereum/go-ethereum/cmd/utils"
11 "github.com/ethereum/go-ethereum/common"
12 "github.com/ethereum/go-ethereum/core/types"
13 "github.com/ethereum/go-ethereum/eth"
14 "github.com/ethereum/go-ethereum/eth/downloader"
15 "github.com/ethereum/go-ethereum/ethclient"
16 "github.com/ethereum/go-ethereum/node"
17 "github.com/ethereum/go-ethereum/p2p/enode"
18
19 // "github.com/ethereum/go-ethereum/accounts/abi"
20 hdwallet "github.com/miguelmota/go-ethereum-hdwallet"
21)
22
23type Node interface {
24 Init() error
25 Start()
26 LinkBatch([]byte) error
27}
28
29type EthNodeHandle struct {
30 n *node.Node
31 c *eth.Config
32}
33
34func Init() (Node, error) {
35 e := new(EthNodeHandle)
36 err := e.Init()
37 return e, err
38}
39
40func (e *EthNodeHandle) Init() error {
41
42 nodeConfig := node.DefaultConfig
43 nodeConfig.IPCPath = "~/.go-dvote-eth.ipc"
44
45 //might also make sense to use staticnodes instead of bootstrap
46 var urls = []string{
47 "enode://e97bbd1b66c91a3e042703ec1a9af9361e7c84d892632cfa995bad96f3fa630b7048c8194e2bbc8984a612db7f5f8ca29be5d807d8abe5db86d5505b62eaa382@51.15.114.224:30303",
48 "enode://480fbf14bab92f6203140403f5a1d4b4a8af143b4bc2c48d7f09fd3a294d08955611c362064ea01681663e42638440a888c326977e178a35295f5c1ca99dfb0f@51.15.71.154:30303",
49 "enode://d6165c23b1d4415f845922b6589fcf19c62e07555c867848a890978993230dad039c248975578216b69a9f7a8fbc2b58db4817bd693f464a6aa45af90964b1e2@51.15.102.251:30303",
50 "enode://3722cb9af22c61294fe6a0a7beb1db176ef456eb4cab1f6551cefb44e253450342de6459bcf576bd97797cf0df9e818db3d048532f3068351ed1bacaa6ec0d20@51.15.89.137:30303",
51 }
52 nodeConfig.P2P.BootstrapNodes = make([]*enode.Node, 0, len(urls))
53 for _, url := range urls {
54 if url != "" {
55 node, err := enode.ParseV4(url)
56 if err != nil {
57 return err
58 }
59 nodeConfig.P2P.BootstrapNodes = append(nodeConfig.P2P.BootstrapNodes, node)
60 }
61 }
62 n, err := node.New(&nodeConfig)
63 if err != nil {
64 return err
65 }
66
67 ethConfig := eth.DefaultConfig
68 ethConfig.NetworkId = 1714
69 ethConfig.SyncMode = downloader.LightSync
70
71 e.n = n
72 e.c = ðConfig
73 return nil
74}
75
76func (e *EthNodeHandle) Start() {
77 utils.RegisterEthService(e.n, e.c)
78 // start the stack and watch for SIG events
79 utils.StartNode(e.n)
80 //api := node.NewPublicAdminAPI(e.n)
81 //info, _ := api.NodeInfo()
82 //fmt.Println(info)
83 //client, _ := ethclient.Dial(e.n.IPCEndpoint())
84 //ctx, _ := context.WithCancel(context.TODO())
85 //sync, _ := client.SyncProgress(ctx)
86 //fmt.Println(sync)
87 // wait for explicit shutdown
88 //e.n.Wait()
89 //download chain?
90}
91
92func (e *EthNodeHandle) LinkBatch(data []byte) error {
93 contractAddr := "0x3e4FfefF898580eC8132A97A91543c8fdeF1210E"
94 var gasLimit uint64
95 gasLimit = 100000000000000000
96 return e.sendContractTx(contractAddr, gasLimit, data)
97}
98
99// might be worthwhile to create generic SendTx to call contracttx, deploytx, etc
100
101func (e *EthNodeHandle) sendContractTx(addr string, limit uint64, data []byte) error {
102 fmt.Println(e.n)
103 client, err := ethclient.Dial(e.n.IPCEndpoint())
104 fmt.Println("Got IPC Endpoint:" + e.n.IPCEndpoint())
105 deadline := time.Now().Add(1000 * time.Millisecond)
106 ctx, cancel := context.WithDeadline(context.TODO(), deadline)
107 defer cancel()
108 fmt.Println("context created")
109
110 mnemonic := "perfect kite link property simple eight welcome spring enforce universe barely cargo"
111 wallet, err := hdwallet.NewFromMnemonic(mnemonic)
112 if err != nil {
113 log.Fatal(err)
114 }
115
116 path := hdwallet.MustParseDerivationPath("m/44'/60'/0'/0/0")
117 account, err := wallet.Derive(path, true)
118 if err != nil {
119 log.Fatal(err)
120 }
121
122 fmt.Println("recovered acct")
123 key, err := wallet.PrivateKey(account)
124 sendaddr, err := wallet.Address(account)
125 nonce, _ := client.NonceAt(ctx, sendaddr, nil)
126 if err != nil {
127 fmt.Println("error")
128 return err
129 }
130 //create tx
131 fmt.Println("creating tx")
132 price, _ := client.SuggestGasPrice(ctx)
133 fmt.Println(price)
134 tx := types.NewTransaction(nonce, common.HexToAddress(addr), big.NewInt(0), limit, price, data)
135 signedTx, _ := types.SignTx(tx, types.HomesteadSigner{}, key)
136 //create ctx
137 err = client.SendTransaction(ctx, signedTx)
138 fmt.Println(err)
139 //fix return
140 return err
141}