2016-06-15 19:50:35 +00:00
|
|
|
package main
|
|
|
|
|
2016-07-27 11:47:41 +00:00
|
|
|
/*
|
|
|
|
#include <stddef.h>
|
|
|
|
#include <stdbool.h>
|
|
|
|
#include <jni.h>
|
|
|
|
extern bool GethServiceSignalEvent( const char *jsonEvent );
|
|
|
|
*/
|
|
|
|
import "C"
|
|
|
|
|
2016-06-15 19:50:35 +00:00
|
|
|
import (
|
2016-06-20 15:21:45 +00:00
|
|
|
"errors"
|
2016-06-15 19:50:35 +00:00
|
|
|
"fmt"
|
2016-06-22 18:56:27 +00:00
|
|
|
"io/ioutil"
|
|
|
|
"time"
|
2016-06-15 19:50:35 +00:00
|
|
|
|
2016-07-27 11:47:41 +00:00
|
|
|
"encoding/json"
|
2016-06-15 19:50:35 +00:00
|
|
|
"github.com/ethereum/go-ethereum/accounts"
|
2016-06-21 18:29:38 +00:00
|
|
|
"github.com/ethereum/go-ethereum/cmd/utils"
|
2016-06-22 18:56:27 +00:00
|
|
|
"github.com/ethereum/go-ethereum/common"
|
2016-06-21 14:34:38 +00:00
|
|
|
"github.com/ethereum/go-ethereum/crypto"
|
2016-07-27 11:47:41 +00:00
|
|
|
"github.com/ethereum/go-ethereum/les"
|
2016-07-04 16:00:29 +00:00
|
|
|
"github.com/ethereum/go-ethereum/p2p/discover"
|
2016-06-21 14:34:38 +00:00
|
|
|
errextra "github.com/pkg/errors"
|
2016-06-15 19:50:35 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
var (
|
2016-06-30 12:53:17 +00:00
|
|
|
scryptN = 4096
|
|
|
|
scryptP = 6
|
2016-06-15 19:50:35 +00:00
|
|
|
)
|
|
|
|
|
2016-06-21 14:07:24 +00:00
|
|
|
// createAccount creates an internal geth account
|
2016-07-01 13:23:39 +00:00
|
|
|
func createAccount(password string) (string, string, error) {
|
2016-06-15 19:50:35 +00:00
|
|
|
|
2016-06-29 11:32:04 +00:00
|
|
|
if currentNode != nil {
|
|
|
|
|
|
|
|
w := true
|
|
|
|
|
2016-07-04 12:28:49 +00:00
|
|
|
if accountManager != nil {
|
|
|
|
// generate the account
|
|
|
|
account, err := accountManager.NewAccount(password, w)
|
|
|
|
if err != nil {
|
|
|
|
return "", "", errextra.Wrap(err, "Account manager could not create the account")
|
|
|
|
}
|
|
|
|
address := fmt.Sprintf("%x", account.Address)
|
|
|
|
|
|
|
|
// recover the public key to return
|
|
|
|
keyContents, err := ioutil.ReadFile(account.File)
|
|
|
|
if err != nil {
|
|
|
|
return address, "", errextra.Wrap(err, "Could not load the key contents")
|
|
|
|
}
|
|
|
|
key, err := accounts.DecryptKey(keyContents, password)
|
|
|
|
if err != nil {
|
|
|
|
return address, "", errextra.Wrap(err, "Could not recover the key")
|
|
|
|
}
|
|
|
|
pubKey := common.ToHex(crypto.FromECDSAPub(&key.PrivateKey.PublicKey))
|
|
|
|
|
|
|
|
return address, pubKey, nil
|
2016-06-29 11:32:04 +00:00
|
|
|
}
|
2016-07-04 12:28:49 +00:00
|
|
|
return "", "", errors.New("Could not retrieve account manager")
|
2016-06-22 18:56:27 +00:00
|
|
|
|
2016-06-21 14:34:38 +00:00
|
|
|
}
|
|
|
|
|
2016-06-29 11:32:04 +00:00
|
|
|
return "", "", errors.New("No running node detected for account creation")
|
2016-06-15 19:50:35 +00:00
|
|
|
|
|
|
|
}
|
2016-06-20 15:21:45 +00:00
|
|
|
|
2016-06-21 18:29:38 +00:00
|
|
|
// unlockAccount unlocks an existing account for a certain duration and
|
|
|
|
// inject the account as a whisper identity if the account was created as
|
|
|
|
// a whisper enabled account
|
2016-06-22 18:56:27 +00:00
|
|
|
func unlockAccount(address, password string, seconds int) error {
|
2016-06-21 18:29:38 +00:00
|
|
|
|
|
|
|
if currentNode != nil {
|
|
|
|
|
2016-07-04 12:28:49 +00:00
|
|
|
if accountManager != nil {
|
|
|
|
account, err := utils.MakeAddress(accountManager, address)
|
|
|
|
if err != nil {
|
|
|
|
return errextra.Wrap(err, "Could not retrieve account from address")
|
|
|
|
}
|
|
|
|
|
|
|
|
err = accountManager.TimedUnlock(account, password, time.Duration(seconds)*time.Second)
|
|
|
|
if err != nil {
|
|
|
|
return errextra.Wrap(err, "Could not decrypt account")
|
|
|
|
}
|
|
|
|
return nil
|
2016-06-21 18:29:38 +00:00
|
|
|
}
|
2016-07-04 12:28:49 +00:00
|
|
|
return errors.New("Could not retrieve account manager")
|
2016-06-21 18:29:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return errors.New("No running node detected for account unlock")
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2016-06-21 14:07:24 +00:00
|
|
|
// createAndStartNode creates a node entity and starts the
|
|
|
|
// node running locally
|
2016-07-01 13:23:39 +00:00
|
|
|
func createAndStartNode(inputDir string) error {
|
2016-06-20 15:21:45 +00:00
|
|
|
|
2016-07-01 13:23:39 +00:00
|
|
|
currentNode = MakeNode(inputDir)
|
2016-06-20 15:21:45 +00:00
|
|
|
if currentNode != nil {
|
2016-06-29 11:32:04 +00:00
|
|
|
RunNode(currentNode)
|
2016-06-20 15:21:45 +00:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
return errors.New("Could not create the in-memory node object")
|
|
|
|
|
|
|
|
}
|
2016-07-04 16:00:29 +00:00
|
|
|
|
|
|
|
func doAddPeer(url string) (bool, error) {
|
|
|
|
server := currentNode.Server()
|
|
|
|
if server == nil {
|
|
|
|
return false, errors.New("node not started")
|
|
|
|
}
|
|
|
|
// Try to add the url as a static peer and return
|
|
|
|
node, err := discover.ParseNode(url)
|
|
|
|
if err != nil {
|
|
|
|
return false, fmt.Errorf("invalid enode: %v", err)
|
|
|
|
}
|
|
|
|
server.AddPeer(node)
|
|
|
|
return true, nil
|
2016-07-27 11:47:41 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func onSendTransactionRequest(queuedTx les.QueuedTx) {
|
|
|
|
event := GethEvent{
|
|
|
|
Type: "sendTransactionQueued",
|
|
|
|
Event: SendTransactionEvent{
|
|
|
|
Hash: queuedTx.Hash.Hex(),
|
|
|
|
Args: queuedTx.Args,
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
body, _ := json.Marshal(&event)
|
|
|
|
C.GethServiceSignalEvent(C.CString(string(body)))
|
|
|
|
}
|
|
|
|
|
2016-08-09 16:41:42 +00:00
|
|
|
func completeTransaction(hash string) (common.Hash, error) {
|
2016-07-27 11:47:41 +00:00
|
|
|
if currentNode != nil {
|
|
|
|
if lightEthereum != nil {
|
|
|
|
backend := lightEthereum.StatusBackend
|
2016-08-09 16:41:42 +00:00
|
|
|
|
2016-07-27 11:47:41 +00:00
|
|
|
return backend.CompleteQueuedTransaction(les.QueuedTxHash(hash))
|
|
|
|
}
|
2016-08-09 16:41:42 +00:00
|
|
|
|
|
|
|
return common.Hash{}, errors.New("can not retrieve LES service")
|
2016-07-27 11:47:41 +00:00
|
|
|
}
|
|
|
|
|
2016-08-09 16:41:42 +00:00
|
|
|
return common.Hash{}, errors.New("can not complete transaction: no running node detected")
|
2016-07-27 11:47:41 +00:00
|
|
|
}
|