arnaucube
arnaucube/go-dvotePublic Self-hosted repository
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 = &ethConfig
 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}