From 75d292bcf673e1b10ac883f8767d092d2f45fd9a Mon Sep 17 00:00:00 2001 From: Martin Holst Swende Date: Tue, 12 Feb 2019 14:00:02 +0100 Subject: clef: external signing fixes + signing data (#19003) * signer/clef: make use of json-rpc notification * signer: tidy up output of OnApprovedTx * accounts/external, signer: implement remote signing of text, make accounts_sign take hexdata * clef: added basic testscript * signer, external, api: add clique signing test to debug rpc, fix clique signing in clef * signer: fix clique interoperability between geth and clef * clef: rename networkid switch to chainid * clef: enable chainid flag * clef, signer: minor changes from review * clef: more tests for signer --- cmd/clef/intapi_changelog.md | 9 +++++- cmd/clef/main.go | 14 +++++++-- cmd/clef/tests/testsigner.js | 73 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 93 insertions(+), 3 deletions(-) create mode 100644 cmd/clef/tests/testsigner.js (limited to 'cmd') diff --git a/cmd/clef/intapi_changelog.md b/cmd/clef/intapi_changelog.md index 6388af730..205aa1a27 100644 --- a/cmd/clef/intapi_changelog.md +++ b/cmd/clef/intapi_changelog.md @@ -1,8 +1,15 @@ ### Changelog for internal API (ui-api) +### 3.2.0 + +* Make `ShowError`, `OnApprovedTx`, `OnSignerStartup` be json-rpc [notifications](https://www.jsonrpc.org/specification#notification): + +> A Notification is a Request object without an "id" member. A Request object that is a Notification signifies the Client's lack of interest in the corresponding Response object, and as such no Response object needs to be returned to the client. The Server MUST NOT reply to a Notification, including those that are within a batch request. +> +> Notifications are not confirmable by definition, since they do not have a Response object to be returned. As such, the Client would not be aware of any errors (like e.g. "Invalid params","Internal error" ### 3.1.0 -* Add `ContentType string` to `SignDataRequest` to accommodate the latest EIP-191 and EIP-712 implementations. +* Add `ContentType` `string` to `SignDataRequest` to accommodate the latest EIP-191 and EIP-712 implementations. ### 3.0.0 diff --git a/cmd/clef/main.go b/cmd/clef/main.go index 38821102d..279b28d75 100644 --- a/cmd/clef/main.go +++ b/cmd/clef/main.go @@ -44,6 +44,7 @@ import ( "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/node" + "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/rlp" "github.com/ethereum/go-ethereum/rpc" "github.com/ethereum/go-ethereum/signer/core" @@ -83,6 +84,11 @@ var ( Value: DefaultConfigDir(), Usage: "Directory for Clef configuration", } + chainIdFlag = cli.Int64Flag{ + Name: "chainid", + Value: params.MainnetChainConfig.ChainID.Int64(), + Usage: "Chain id to use for signing (1=mainnet, 3=ropsten, 4=rinkeby, 5=Goerli)", + } rpcPortFlag = cli.IntFlag{ Name: "rpcport", Usage: "HTTP-RPC server listening port", @@ -178,7 +184,7 @@ func init() { logLevelFlag, keystoreFlag, configdirFlag, - utils.NetworkIdFlag, + chainIdFlag, utils.LightKDFFlag, utils.NoUSBFlag, utils.RPCListenAddrFlag, @@ -402,9 +408,13 @@ func signer(c *cli.Context) error { } } } + log.Info("Starting signer", "chainid", c.GlobalInt64(chainIdFlag.Name), + "keystore", c.GlobalString(keystoreFlag.Name), + "light-kdf", c.GlobalBool(utils.LightKDFFlag.Name), + "advanced", c.GlobalBool(advancedMode.Name)) apiImpl := core.NewSignerAPI( - c.GlobalInt64(utils.NetworkIdFlag.Name), + c.GlobalInt64(chainIdFlag.Name), c.GlobalString(keystoreFlag.Name), c.GlobalBool(utils.NoUSBFlag.Name), ui, db, diff --git a/cmd/clef/tests/testsigner.js b/cmd/clef/tests/testsigner.js new file mode 100644 index 000000000..86b2c4539 --- /dev/null +++ b/cmd/clef/tests/testsigner.js @@ -0,0 +1,73 @@ +// This file is a test-utility for testing clef-functionality +// +// Start clef with +// +// build/bin/clef --4bytedb=./cmd/clef/4byte.json --rpc +// +// Start geth with +// +// build/bin/geth --nodiscover --maxpeers 0 --signer http://localhost:8550 console --preload=cmd/clef/tests/testsigner.js +// +// and in the console simply invoke +// +// > test() +// +// You can reload the file via `reload()` + +function reload(){ + loadScript("./cmd/clef/tests/testsigner.js"); +} + +function init(){ + if (typeof accts == 'undefined' || accts.length == 0){ + accts = eth.accounts + console.log("Got accounts ", accts); + } +} +init() +function testTx(){ + if( accts && accts.length > 0) { + var a = accts[0] + var txdata = eth.signTransaction({from: a, to: a, value: 1, nonce: 1, gas: 1, gasPrice: 1}) + var v = parseInt(txdata.tx.v) + console.log("V value: ", v) + if (v == 37 || v == 38){ + console.log("Mainnet 155-protected chainid was used") + } + if (v == 27 || v == 28){ + throw new Error("Mainnet chainid was used, but without replay protection!") + } + } +} +function testSignText(){ + if( accts && accts.length > 0){ + var a = accts[0] + var r = eth.sign(a, "0x68656c6c6f20776f726c64"); //hello world + console.log("signing response", r) + } +} +function testClique(){ + if( accts && accts.length > 0){ + var a = accts[0] + var r = debug.testSignCliqueBlock(a, 0); // Sign genesis + console.log("signing response", r) + if( a != r){ + throw new Error("Requested signing by "+a+ " but got sealer "+r) + } + } +} + +function test(){ + var tests = [ + testTx, + testSignText, + testClique, + ] + for( i in tests){ + try{ + tests[i]() + }catch(err){ + console.log(err) + } + } + } -- cgit v1.2.3