Skip to content

Commit

Permalink
Merged in coinplugin/go-metadium (pull request #20)
Browse files Browse the repository at this point in the history
Master

Approved-by: Uh Sado <[email protected]>
  • Loading branch information
sadoci committed Apr 5, 2019
2 parents ebca4c9 + 5b05cb2 commit 95ee424
Show file tree
Hide file tree
Showing 14 changed files with 1,121 additions and 52 deletions.
12 changes: 7 additions & 5 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,11 @@ endif
metadium: gmet logrot
@[ -d build/conf ] || mkdir -p build/conf
@cp -p metadium/scripts/gmet.sh metadium/scripts/solc.sh build/bin/
@cp -p metadium/scripts/config.json.example \
metadium/scripts/genesis-template.json \
metadium/contracts/MetadiumGovernance.js build/conf/
@cp -p metadium/scripts/config.json.example \
metadium/scripts/genesis-template.json \
metadium/contracts/MetadiumGovernance.js \
metadium/scripts/deploy-governance.js \
build/conf/
@(cd build; tar cfz metadium.tar.gz bin conf)
@echo "Done building build/metadium.tar.gz"

Expand Down Expand Up @@ -210,7 +212,7 @@ ifeq ($(shell uname), Linux)
if [ ! $$? = 0 ]; then \
echo "Docker not found."; \
else \
docker run -e HOME=/tmp -it --rm \
docker run -e HOME=/tmp --rm \
-v /etc/passwd:/etc/passwd:ro \
-v /etc/group:/etc/group:ro \
-v ~/src:/home/$${USER}/src \
Expand All @@ -223,7 +225,7 @@ else
if [ ! $$? = 0 ]; then \
echo "Docker not found."; \
else \
docker run -e HOME=/tmp -it --rm -v $(shell pwd):/data \
docker run -e HOME=/tmp --rm -v $(shell pwd):/data \
-w /data metadium/bobthe:latest \
make USE_ROCKSDB=$(USE_ROCKSDB); \
fi
Expand Down
179 changes: 179 additions & 0 deletions accounts/usbwallet/offline.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
// Copyright 2019 The go-ethereum / go-metadium Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.

package usbwallet

import (
"errors"
"io"
"math/big"

"github.com/ethereum/go-ethereum/accounts"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/log"
"github.com/karalabe/hid"
)

// a simple wrapper for offline use, mainly for Close()
type offlineWallet struct {
driver driver
info hid.DeviceInfo
device *hid.Device
log log.Logger
}

// dummy Hub structures for offline wallet use
var (
offlineHubs []*Hub
)

func init() {
// nano ledger
offlineHubs = append(offlineHubs, &Hub{
scheme: LedgerScheme,
vendorID: 0x2c97,
productIDs: []uint16{0x0000, 0x0001},
usageID: 0xffa0,
endpointID: 0,
})
// trezor 1
offlineHubs = append(offlineHubs, &Hub{
scheme: TrezorScheme,
vendorID: 0x534c,
productIDs: []uint16{0x0001},
usageID: 0xff00,
endpointID: 0,
})
// trezor 2, this doesn't seem to work yet.
offlineHubs = append(offlineHubs, &Hub{
scheme: TrezorScheme,
vendorID: 0x1209,
productIDs: []uint16{0x53c0, 0x53c1},
usageID: 0xf1d0,
endpointID: -1,
})
}

func (w *offlineWallet) Status() (string, error) {
return w.driver.Status()
}

func (w *offlineWallet) Open(device io.ReadWriter, passphrase string) error {
return w.driver.Open(device, passphrase)
}

func (w *offlineWallet) Close() error {
if w.device == nil {
return nil
}
w.driver.Close()
w.device.Close()
w.device = nil
return nil
}

func (w *offlineWallet) Heartbeat() error {
return w.driver.Heartbeat()
}

func (w *offlineWallet) Derive(path accounts.DerivationPath) (common.Address, error) {
return w.driver.Derive(path)
}

func (w *offlineWallet) SignTx(path accounts.DerivationPath, tx *types.Transaction, chainID *big.Int) (common.Address, *types.Transaction, error) {
return w.driver.SignTx(path, tx, chainID)
}

// ListDevices returns the array of ledger or trezor device paths
// for mostly informational use
func ListDevices(scheme string) []string {
var devices []string

// triple loop!
for _, hub := range offlineHubs {
if len(scheme) > 0 && hub.scheme != scheme {
continue
}
for _, info := range hid.Enumerate(hub.vendorID, 0) {
for _, id := range hub.productIDs {
if info.ProductID == id && (info.UsagePage == hub.usageID || info.Interface == hub.endpointID) {
devices = append(devices, info.Path)
break
}
}
}
}
return devices
}

// OpenOffline opens usb wallet for offline use.
// If path is not specified, the first device is used.
// Note that Trezor 1 after firmware upgrade doesn't work any more.
func OpenOffline(scheme, path string) (interface{}, error) {
if scheme != LedgerScheme && scheme != TrezorScheme {
return nil, errors.New("Not Supported")
}
if path == "" {
paths := ListDevices(scheme)
if len(paths) == 0 {
return nil, errors.New("Not Found")
}
path = paths[0]
}

for _, hub := range offlineHubs {
if hub.scheme != scheme {
continue
}
for _, info := range hid.Enumerate(hub.vendorID, 0) {
if info.Path == path {
if scheme == TrezorScheme && info.Interface == -1 {
// Trezor 2. It's going to hang. Stop here.
return nil, errors.New("Trezor 2 doesn't work yet. You shouldn't have upgraded the firmware.")
}

logger := log.New("url", accounts.URL{Scheme: scheme, Path: path})
var drv driver
switch scheme {
case LedgerScheme:
drv = newLedgerDriver(logger)
case TrezorScheme:
drv = newTrezorDriver(logger)
}
device, err := info.Open()
if err != nil {
return nil, err
}
err = drv.Open(device, "")
if err != nil {
return nil, err
}
w := &offlineWallet{
driver: drv,
info: info,
device: device,
log: logger,
}
return w, nil
}
}
}

return nil, errors.New("Not Found")
}

// EOF
2 changes: 2 additions & 0 deletions console/console.go
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,8 @@ func (c *Console) init(preload []string) error {
}
c.prompter.SetWordCompleter(c.AutoCompleteInput)
}
// Metadium: set console prompter
jsre.PromptPassword = promptPassword
return nil
}

Expand Down
5 changes: 5 additions & 0 deletions console/prompter.go
Original file line number Diff line number Diff line change
Expand Up @@ -170,3 +170,8 @@ func (p *terminalPrompter) ClearHistory() {
func (p *terminalPrompter) SetWordCompleter(completer WordCompleter) {
p.State.SetWordCompleter(liner.WordCompleter(completer))
}

// Metadium. For offline wallet use
func promptPassword(prompt string) (string, error) {
return Stdin.PromptPassword(prompt)
}
12 changes: 12 additions & 0 deletions ethclient/ethclient.go
Original file line number Diff line number Diff line change
Expand Up @@ -506,6 +506,18 @@ func (ec *Client) SendTransaction(ctx context.Context, tx *types.Transaction) er
return ec.c.CallContext(ctx, nil, "eth_sendRawTransaction", common.ToHex(data))
}

// SendTransactions injects signed transactions into the pending pool for execution.
//
// If the transaction was a contract creation use the TransactionReceipt method to get the
// contract address after the transaction has been mined.
func (ec *Client) SendTransactions(ctx context.Context, txs types.Transactions) error {
data, err := rlp.EncodeToBytes(txs)
if err != nil {
return err
}
return ec.c.CallContext(ctx, nil, "eth_sendRawTransactions", common.ToHex(data))
}

func toCallArg(msg ethereum.CallMsg) interface{} {
arg := map[string]interface{}{
"from": msg.From,
Expand Down
20 changes: 20 additions & 0 deletions internal/ethapi/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -1337,6 +1337,26 @@ func (s *PublicTransactionPoolAPI) SendRawTransaction(ctx context.Context, encod
return submitTransaction(ctx, s.b, tx)
}

// SendRawTransactions will add the signed transactions to the transaction pool.
// The sender is responsible for signing the transactions and using the correct nonces.
func (s *PublicTransactionPoolAPI) SendRawTransactions(ctx context.Context, encodedTxs []hexutil.Bytes) ([]common.Hash, error) {
var hashes []common.Hash
for _, etx := range encodedTxs {
tx := new(types.Transaction)
if err := rlp.DecodeBytes(etx, tx); err != nil {
hashes = append(hashes, common.Hash{})
continue
}
hash, err := submitTransaction(ctx, s.b, tx)
if err == nil {
hashes = append(hashes, hash)
} else {
hashes = append(hashes, common.Hash{})
}
}
return hashes, nil
}

// Sign calculates an ECDSA signature for:
// keccack256("\x19Ethereum Signed Message:\n" + len(message) + message).
//
Expand Down
69 changes: 55 additions & 14 deletions internal/jsre/deps/bindata.go

Large diffs are not rendered by default.

8 changes: 8 additions & 0 deletions internal/jsre/deps/web3.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

36 changes: 35 additions & 1 deletion internal/jsre/jsre.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,13 @@ func New(assetPath string, output io.Writer) *JSRE {
go re.runEventLoop()
re.Set("loadScript", re.loadScript)
re.Set("inspect", re.prettyPrintJS)
re.Set("loadFile", re.loadFile)
re.Set("msleep", re.msleep)
re.Set("offlineWalletOpen", re.offlineWalletOpen)
re.Set("offlineWalletAddress", re.offlineWalletAddress)
re.Set("offlineWalletClose", re.offlineWalletClose)
re.Set("offlineWalletSignTx", re.offlineWalletSignTx)
re.Set("offlineWalletList", re.offlineWalletList)
return re
}

Expand Down Expand Up @@ -296,7 +303,6 @@ func (re *JSRE) loadScript(call otto.FunctionCall) otto.Value {
}
if _, err := compileAndRun(call.Otto, file, source); err != nil {
// TODO: throw exception
fmt.Println("err:", err)
return otto.FalseValue()
}
// TODO: return evaluation result
Expand Down Expand Up @@ -333,3 +339,31 @@ func compileAndRun(vm *otto.Otto, filename string, src interface{}) (otto.Value,
}
return vm.Run(script)
}

// loadFile loads a file content as string
func (re *JSRE) loadFile(call otto.FunctionCall) otto.Value {
file, err := call.Argument(0).ToString()
if err != nil {
return otto.UndefinedValue()
}
file = common.AbsolutePath(re.assetPath, file)
source, err := ioutil.ReadFile(file)
if err != nil {
return otto.UndefinedValue()
}
value, err := otto.ToValue(string(source))
if err != nil {
return otto.UndefinedValue()
}
return value
}

// msleep sleeps in ms resolution
func (re *JSRE) msleep(call otto.FunctionCall) otto.Value {
delay, err := call.Argument(0).ToInteger()
if err != nil {
return otto.FalseValue()
}
time.Sleep(time.Duration(delay) * time.Millisecond)
return otto.TrueValue()
}
Loading

0 comments on commit 95ee424

Please sign in to comment.