diff --git a/cmd/signer/README.md b/cmd/signer/README.md
index dad2f2bc04..4def84e014 100644
--- a/cmd/signer/README.md
+++ b/cmd/signer/README.md
@@ -174,9 +174,9 @@ None
Signs a transactions and responds with the signed transaction in RLP encoded form.
#### Arguments
- 1. from [address]: account to send the transaction from
2. transaction object:
- - `to` [address]: receiver account
+ - `from` [address]: account to send the transaction from
+ - `to` [address]: receiver account. If omitted or `0x`, will cause contract creation.
- `gas` [number]: maximum amount of gas to burn
- `gasPrice` [number]: gas price
- `value` [number:optional]: amount of Wei to send with the transaction
@@ -196,8 +196,8 @@ None
"jsonrpc": "2.0",
"method": "account_signTransaction",
"params": [
- "0x1923f626bb8dc025849e00f99c25fe2b2f7fb0db",
{
+ "from": "0x1923f626bb8dc025849e00f99c25fe2b2f7fb0db",
"gas": "0x55555",
"gasPrice": "0x1234",
"input": "0xabcd",
@@ -209,11 +209,64 @@ None
}
{
- "id": 2,
"jsonrpc": "2.0",
- "result": "0xf86480821234830555559407a565b7ed7d7a678680a4c162885bedbb695fe0821234802ea028f9ebeff90732eae45692a11c4ca2ef7f631a0a25bf8763d093e770c4ec464aa01fae77b24617913e718b989be78bc1aabb2fed3f2d4e3b93bd36759f1b5b4904"
+ "id": 67,
+ "error": {
+ "code": -32000,
+ "message": "Request denied"
+ }
}
```
+#### Sample call with ABI-data
+
+
+```
+{
+ "jsonrpc": "2.0",
+ "method": "account_signTransaction",
+ "params": [
+ {
+ "from": "0x694267f14675d7e1b9494fd8d72fefe1755710fa",
+ "gas": "0x333",
+ "gasPrice": "0x1",
+ "nonce": "0x0",
+ "to": "0x07a565b7ed7d7a678680a4c162885bedbb695fe0",
+ "value": "0x0",
+ "data": "0x4401a6e40000000000000000000000000000000000000000000000000000000000000012"
+ },
+ "safeSend(address)"
+ ],
+ "id": 67
+}
+
+{
+ "jsonrpc": "2.0",
+ "id": 67,
+ "result": {
+ "raw": "0xf88380018203339407a565b7ed7d7a678680a4c162885bedbb695fe080a44401a6e4000000000000000000000000000000000000000000000000000000000000001226a0223a7c9bcf5531c99be5ea7082183816eb20cfe0bbc322e97cc5c7f71ab8b20ea02aadee6b34b45bb15bc42d9c09de4a6754e7000908da72d48cc7704971491663",
+ "tx": {
+ "nonce": "0x0",
+ "gasPrice": "0x1",
+ "gas": "0x333",
+ "to": "0x07a565b7ed7d7a678680a4c162885bedbb695fe0",
+ "value": "0x0",
+ "input": "0x4401a6e40000000000000000000000000000000000000000000000000000000000000012",
+ "v": "0x26",
+ "r": "0x223a7c9bcf5531c99be5ea7082183816eb20cfe0bbc322e97cc5c7f71ab8b20e",
+ "s": "0x2aadee6b34b45bb15bc42d9c09de4a6754e7000908da72d48cc7704971491663",
+ "hash": "0xeba2df809e7a612a0a0d444ccfa5c839624bdc00dd29e3340d46df3870f8a30e"
+ }
+ }
+}
+```
+
+Bash example:
+```bash
+#curl -H "Content-Type: application/json" -X POST --data '{"jsonrpc":"2.0","method":"account_signTransaction","params":[{"from":"0x694267f14675d7e1b9494fd8d72fefe1755710fa","gas":"0x333","gasPrice":"0x1","nonce":"0x0","to":"0x07a565b7ed7d7a678680a4c162885bedbb695fe0", "value":"0x0", "data":"0x4401a6e40000000000000000000000000000000000000000000000000000000000000012"},"safeSend(address)"],"id":67}' http://localhost:8550/
+
+{"jsonrpc":"2.0","id":67,"result":{"raw":"0xf88380018203339407a565b7ed7d7a678680a4c162885bedbb695fe080a44401a6e4000000000000000000000000000000000000000000000000000000000000001226a0223a7c9bcf5531c99be5ea7082183816eb20cfe0bbc322e97cc5c7f71ab8b20ea02aadee6b34b45bb15bc42d9c09de4a6754e7000908da72d48cc7704971491663","tx":{"nonce":"0x0","gasPrice":"0x1","gas":"0x333","to":"0x07a565b7ed7d7a678680a4c162885bedbb695fe0","value":"0x0","input":"0x4401a6e40000000000000000000000000000000000000000000000000000000000000012","v":"0x26","r":"0x223a7c9bcf5531c99be5ea7082183816eb20cfe0bbc322e97cc5c7f71ab8b20e","s":"0x2aadee6b34b45bb15bc42d9c09de4a6754e7000908da72d48cc7704971491663","hash":"0xeba2df809e7a612a0a0d444ccfa5c839624bdc00dd29e3340d46df3870f8a30e"}}}
+```
+
### account_sign
@@ -395,7 +448,8 @@ By starting the signer with the switch `--stdio-ui-test`, the signer will invoke
denials. This can be used during development to ensure that the API is (at least somewhat) correctly implemented.
See `pythonsigner`, which can be invoked via `python3 pythonsigner.py test` to perform the 'denial-handshake-test'.
-**work in progress**
+All methods in this API uses object-based parameters, so that there can be no mixups of parameters: each piece of data is accessed by key.
+
### ApproveTx
@@ -560,6 +614,15 @@ The UI should show the info to the user. Does not expect response.
```
+### OnApproved
+
+`OnApprovedTx` is called when a transaction has been approved and signed. The call contains the return value that will be sent to the external caller. The return value from this method is ignored - the reason for having this callback is to allow the ruleset to keep track of approved transactions.
+
+When implementing rate-limited rules, this callback should be used.
+
+TLDR; Use this method to keep track of signed transactions, instead of using the data in `ApproveTx`.
+
+
### Rules for UI apis
A UI should conform to the following rules.
diff --git a/cmd/signer/abihelper.go b/cmd/signer/core/abihelper.go
similarity index 96%
rename from cmd/signer/abihelper.go
rename to cmd/signer/core/abihelper.go
index 521ae7b45a..625d5cbdf9 100644
--- a/cmd/signer/abihelper.go
+++ b/cmd/signer/core/abihelper.go
@@ -14,7 +14,7 @@
// You should have received a copy of the GNU General Public License
// along with go-ethereum. If not, see .
-package signer
+package core
import (
// "bytes"
@@ -157,25 +157,25 @@ func MethodSelectorToAbi(selector string) ([]byte, error) {
}
-type abiDb struct {
+type AbiDb struct {
db map[string]string
}
// NewAbiDBFromFile loads signature database from file, and
// errors if the file is not valid json. Does no other validation of contents
-func NewAbiDBFromFile(path string) (*abiDb, error) {
+func NewAbiDBFromFile(path string) (*AbiDb, error) {
raw, err := ioutil.ReadFile(path)
if err != nil {
return nil, err
}
- db := new(abiDb)
+ db := new(AbiDb)
json.Unmarshal(raw, &db.db)
return db, nil
}
// LookupMethodSelector checks the given 4byte-sequence against the known ABI methods.
// OBS: This method does not validate the match, it's assumed the caller will do so
-func (db *abiDb) LookupMethodSelector(id []byte) (string, error) {
+func (db *AbiDb) LookupMethodSelector(id []byte) (string, error) {
if len(id) != 4 {
return "", fmt.Errorf("Expected 4-byte id, got %d", len(id))
}
@@ -185,6 +185,6 @@ func (db *abiDb) LookupMethodSelector(id []byte) (string, error) {
}
return "", fmt.Errorf("Signature %v not found", sig)
}
-func (db *abiDb) Size() int {
+func (db *AbiDb) Size() int {
return len(db.db)
}
diff --git a/cmd/signer/abihelper_test.go b/cmd/signer/core/abihelper_test.go
similarity index 99%
rename from cmd/signer/abihelper_test.go
rename to cmd/signer/core/abihelper_test.go
index 3117df09de..b3a662c71d 100644
--- a/cmd/signer/abihelper_test.go
+++ b/cmd/signer/core/abihelper_test.go
@@ -14,7 +14,7 @@
// You should have received a copy of the GNU General Public License
// along with go-ethereum. If not, see .
-package signer
+package core
import (
"fmt"
@@ -176,13 +176,13 @@ func TestCalldataDecoding(t *testing.T) {
func TestSelectorUnmarshalling(t *testing.T) {
var (
- db *abiDb
+ db *AbiDb
err error
abistring []byte
abistruct abi.ABI
)
- db, err = NewAbiDBFromFile("4byte.json")
+ db, err = NewAbiDBFromFile("../4byte.json")
if err != nil {
t.Fatal(err)
}
diff --git a/cmd/signer/api.go b/cmd/signer/core/api.go
similarity index 91%
rename from cmd/signer/api.go
rename to cmd/signer/core/api.go
index 03a182d849..8e9f4c2d3b 100644
--- a/cmd/signer/api.go
+++ b/cmd/signer/core/api.go
@@ -14,7 +14,7 @@
// You should have received a copy of the GNU General Public License
// along with go-ethereum. If not, see .
-package signer
+package core
import (
"context"
@@ -69,7 +69,7 @@ type SignerUI interface {
// ApproveImport prompt the user for confirmation to import Account json
ApproveImport(request *ImportRequest) (ImportResponse, error)
// ApproveListing prompt the user for confirmation to list accounts
- // the list of accounts to list can be modified by the ui
+ // the list of accounts to list can be modified by the UI
ApproveListing(request *ListRequest) (ListResponse, error)
// ApproveNewAccount prompt the user for confirmation to create new Account, and reveal to caller
ApproveNewAccount(request *NewAccountRequest) (NewAccountResponse, error)
@@ -86,8 +86,8 @@ type SignerUI interface {
type SignerAPI struct {
chainID *big.Int
am *accounts.Manager
- ui SignerUI
- abidb abiDb
+ UI SignerUI
+ abidb AbiDb
}
// Metadata about a request
@@ -201,7 +201,7 @@ func (ew errorWrapper) String() string {
// key that is generated when a new Account is created.
// noUSB disables USB support that is required to support hardware devices such as
// ledger and trezor.
-func NewSignerAPI(chainID int64, ksLocation string, noUSB bool, ui SignerUI, abidb *abiDb, lightKDF bool) *SignerAPI {
+func NewSignerAPI(chainID int64, ksLocation string, noUSB bool, ui SignerUI, abidb *AbiDb, lightKDF bool) *SignerAPI {
var (
backends []accounts.Backend
n, p = keystore.StandardScryptN, keystore.StandardScryptP
@@ -242,7 +242,7 @@ func (api *SignerAPI) List(ctx context.Context) (Accounts, error) {
accs = append(accs, acc)
}
}
- result, err := api.ui.ApproveListing(&ListRequest{Accounts: accs, Meta: MetadataFromContext(ctx)})
+ result, err := api.UI.ApproveListing(&ListRequest{Accounts: accs, Meta: MetadataFromContext(ctx)})
if err != nil {
return nil, err
}
@@ -261,7 +261,7 @@ func (api *SignerAPI) New(ctx context.Context) (accounts.Account, error) {
if len(be) == 0 {
return accounts.Account{}, errors.New("password based accounts not supported")
}
- resp, err := api.ui.ApproveNewAccount(&NewAccountRequest{MetadataFromContext(ctx)})
+ resp, err := api.UI.ApproveNewAccount(&NewAccountRequest{MetadataFromContext(ctx)})
if err != nil {
return accounts.Account{}, err
@@ -277,33 +277,25 @@ func (api *SignerAPI) New(ctx context.Context) (accounts.Account, error) {
// UI-modifications to requests
func logDiff(original *SignTxRequest, new *SignTxResponse) bool {
modified := false
-
if f0, f1 := original.Transaction.From, new.Transaction.From; !reflect.DeepEqual(f0, f1) {
log.Info("Sender-account changed by UI", "was", f0, "is", f1)
modified = true
}
-
if t0, t1 := original.Transaction.To, new.Transaction.To; !reflect.DeepEqual(t0, t1) {
log.Info("Recipient-account changed by UI", "was", t0, "is", t1)
modified = true
}
- if g0, g1 := (*big.Int)(original.Transaction.Gas), (*big.Int)(new.Transaction.Gas); g0 != g1 {
- if g0 == nil || g1 == nil || g0.Cmp(g1) != 0 {
- modified = true
- log.Info("Gas changed by UI", "was", g0, "is", g1)
- }
+ if g0, g1 := big.Int(original.Transaction.Gas), big.Int(new.Transaction.Gas); g0.Cmp(&g1) != 0 {
+ modified = true
+ log.Info("Gas changed by UI", "was", g0, "is", g1)
}
- if g0, g1 := (*big.Int)(original.Transaction.GasPrice), (*big.Int)(new.Transaction.GasPrice); g0 != g1 {
- if g0 == nil || g1 == nil || g0.Cmp(g1) != 0 {
- modified = true
- log.Info("GasPrice changed by UI", "was", g0, "is", g1)
- }
+ if g0, g1 := big.Int(original.Transaction.GasPrice), big.Int(new.Transaction.GasPrice); g0.Cmp(&g1) != 0 {
+ modified = true
+ log.Info("GasPrice changed by UI", "was", g0, "is", g1)
}
- if v0, v1 := (*big.Int)(original.Transaction.Value), (*big.Int)(new.Transaction.Value); v0 != v1 {
- if v0 == nil || v1 == nil || v0.Cmp(v1) != 0 {
- modified = true
- log.Info("Value changed by UI", "was", v0, "is", v1)
- }
+ if v0, v1 := big.Int(original.Transaction.Value), big.Int(new.Transaction.Value); v0.Cmp(&v1) != 0 {
+ modified = true
+ log.Info("Value changed by UI", "was", v0, "is", v1)
}
if d0, d1 := original.Transaction.Data, new.Transaction.Data; d0 != d1 {
d0s := ""
@@ -320,11 +312,8 @@ func logDiff(original *SignTxRequest, new *SignTxResponse) bool {
}
}
if n0, n1 := original.Transaction.Nonce, new.Transaction.Nonce; n0 != n1 {
-
- if n0 == nil || n1 == nil || (*n0) != (*n1) {
- modified = true
- log.Info("Nonce changed by UI", "was", n0, "is", n1)
- }
+ modified = true
+ log.Info("Nonce changed by UI", "was", n0, "is", n1)
}
return modified
}
@@ -386,12 +375,12 @@ func (api *SignerAPI) SignTransaction(ctx context.Context, args SendTxArgs, meth
*args.Input = nil
}
req := SignTxRequest{
- Transaction: args,
- Meta: MetadataFromContext(ctx),
- Callinfo:api.determineCallInfo(data, methodSelector),
+ Transaction: args,
+ Meta: MetadataFromContext(ctx),
+ Callinfo: api.determineCallInfo(data, methodSelector),
}
// Process approval
- result, err = api.ui.ApproveTx(&req)
+ result, err = api.UI.ApproveTx(&req)
if err != nil {
return nil, err
}
@@ -415,7 +404,7 @@ func (api *SignerAPI) SignTransaction(ctx context.Context, args SendTxArgs, meth
// The one to sign is the one that was returned from the UI
signedTx, err := wallet.SignTxWithPassphrase(acc, result.Password, unsignedTx, api.chainID)
if err != nil {
- api.ui.ShowError(err.Error())
+ api.UI.ShowError(err.Error())
return nil, err
}
@@ -423,7 +412,7 @@ func (api *SignerAPI) SignTransaction(ctx context.Context, args SendTxArgs, meth
response := ethapi.SignTransactionResult{rlpdata, signedTx}
// Finally, send the signed tx to the UI
- api.ui.OnApprovedTx(response)
+ api.UI.OnApprovedTx(response)
// ...and to the external caller
return &response, nil
@@ -443,7 +432,7 @@ func (api *SignerAPI) Sign(ctx context.Context, addr common.MixedcaseAddress, da
// We make the request prior to looking up if we actually have the account, to prevent
// account-enumeration via the API
req := &SignDataRequest{Address: addr, Rawdata: data, Message: msg, Hash: sighash, Meta: MetadataFromContext(ctx)}
- res, err := api.ui.ApproveSignData(req)
+ res, err := api.UI.ApproveSignData(req)
if err != nil {
return nil, err
@@ -460,7 +449,7 @@ func (api *SignerAPI) Sign(ctx context.Context, addr common.MixedcaseAddress, da
// Assemble sign the data with the wallet
signature, err := wallet.SignHashWithPassphrase(account, res.Password, sighash)
if err != nil {
- api.ui.ShowError(err.Error())
+ api.UI.ShowError(err.Error())
return nil, err
}
signature[64] += 27 // Transform V from 0/1 to 27/28 according to the yellow paper
@@ -509,7 +498,7 @@ func signHash(data []byte) ([]byte, string) {
// Export returns encrypted private key associated with the given address in web3 keystore format.
func (api *SignerAPI) Export(ctx context.Context, addr common.Address) (json.RawMessage, error) {
- res, err := api.ui.ApproveExport(&ExportRequest{Address: addr, Meta: MetadataFromContext(ctx)})
+ res, err := api.UI.ApproveExport(&ExportRequest{Address: addr, Meta: MetadataFromContext(ctx)})
if err != nil {
return nil, err
@@ -537,7 +526,7 @@ func (api *SignerAPI) Import(ctx context.Context, keyJSON json.RawMessage) (Acco
if len(be) == 0 {
return Account{}, errors.New("password based accounts not supported")
}
- res, err := api.ui.ApproveImport(&ImportRequest{Meta: MetadataFromContext(ctx)})
+ res, err := api.UI.ApproveImport(&ImportRequest{Meta: MetadataFromContext(ctx)})
if err != nil {
return Account{}, err
@@ -547,7 +536,7 @@ func (api *SignerAPI) Import(ctx context.Context, keyJSON json.RawMessage) (Acco
}
acc, err := be[0].(*keystore.KeyStore).Import(keyJSON, res.OldPassword, res.NewPassword)
if err != nil {
- api.ui.ShowError(err.Error())
+ api.UI.ShowError(err.Error())
return Account{}, err
}
return Account{Typ: "Account", URL: acc.URL, Address: acc.Address}, nil
diff --git a/cmd/signer/api_test.go b/cmd/signer/core/api_test.go
similarity index 95%
rename from cmd/signer/api_test.go
rename to cmd/signer/core/api_test.go
index 38f2c56aaf..2c8e35cc21 100644
--- a/cmd/signer/api_test.go
+++ b/cmd/signer/core/api_test.go
@@ -1,4 +1,4 @@
-package signer
+package core
import (
"bytes"
@@ -35,9 +35,9 @@ func (ui *HeadlessUI) ApproveTx(request *SignTxRequest) (SignTxResponse, error)
case "Y":
return SignTxResponse{request.Transaction, true, <-ui.controller}, nil
case "M": //Modify
- old := (*big.Int)(request.Transaction.Value)
- newVal := big.NewInt(0).Add(old, big.NewInt(1))
- request.Transaction.Value = (*hexutil.Big)(newVal)
+ old := big.Int(request.Transaction.Value)
+ newVal := big.NewInt(0).Add(&old, big.NewInt(1))
+ request.Transaction.Value = hexutil.Big(*newVal)
return SignTxResponse{request.Transaction, true, <-ui.controller}, nil
default:
return SignTxResponse{request.Transaction, false, ""}, nil
@@ -106,7 +106,7 @@ func setup(t *testing.T) (*SignerAPI, chan string) {
controller := make(chan string, 10)
- db, err := NewAbiDBFromFile(fmt.Sprintf("./4byte.json"))
+ db, err := NewAbiDBFromFile(fmt.Sprintf("../4byte.json"))
if err != nil {
utils.Fatalf(err.Error())
@@ -238,9 +238,9 @@ func TestSignData(t *testing.T) {
}
func mkTestTx(from common.MixedcaseAddress) SendTxArgs {
to := common.NewMixedcaseAddress(common.HexToAddress("0x1337"))
- gas := (*hexutil.Big)(big.NewInt(21000))
- gasPrice := (*hexutil.Big)(big.NewInt(2000000000))
- value := (*hexutil.Big)(big.NewInt(1e18))
+ gas := (hexutil.Big)(*big.NewInt(21000))
+ gasPrice := (hexutil.Big)(*big.NewInt(2000000000))
+ value := (hexutil.Big)(*big.NewInt(1e18))
nonce := (hexutil.Uint64)(0)
data := hexutil.Bytes(common.Hex2Bytes("01020304050607080a"))
tx := SendTxArgs{
@@ -250,7 +250,7 @@ func mkTestTx(from common.MixedcaseAddress) SendTxArgs {
GasPrice: gasPrice,
Value: value,
Data: &data,
- Nonce: &nonce}
+ Nonce: nonce}
return tx
}
diff --git a/cmd/signer/auditlog.go b/cmd/signer/core/auditlog.go
similarity index 99%
rename from cmd/signer/auditlog.go
rename to cmd/signer/core/auditlog.go
index 007faf45ef..c5cb0ffb40 100644
--- a/cmd/signer/auditlog.go
+++ b/cmd/signer/core/auditlog.go
@@ -14,7 +14,7 @@
// You should have received a copy of the GNU General Public License
// along with go-ethereum. If not, see .
-package signer
+package core
import (
"context"
diff --git a/cmd/signer/cliui.go b/cmd/signer/core/cliui.go
similarity index 99%
rename from cmd/signer/cliui.go
rename to cmd/signer/core/cliui.go
index 7222744f8f..de4ab466ca 100644
--- a/cmd/signer/cliui.go
+++ b/cmd/signer/core/cliui.go
@@ -13,7 +13,7 @@
//
// You should have received a copy of the GNU General Public License
// along with go-ethereum. If not, see .
-package signer
+package core
import (
"bufio"
@@ -181,7 +181,7 @@ func (ui *CommandlineUI) ApproveImport(request *ImportRequest) (ImportResponse,
}
// ApproveListing prompt the user for confirmation to list accounts
-// the list of accounts to list can be modified by the ui
+// the list of accounts to list can be modified by the UI
func (ui *CommandlineUI) ApproveListing(request *ListRequest) (ListResponse, error) {
ui.mu.Lock()
diff --git a/cmd/signer/stdioui.go b/cmd/signer/core/stdioui.go
similarity index 99%
rename from cmd/signer/stdioui.go
rename to cmd/signer/core/stdioui.go
index 9bc4ca60b2..a42ff845a5 100644
--- a/cmd/signer/stdioui.go
+++ b/cmd/signer/core/stdioui.go
@@ -15,7 +15,7 @@
// along with go-ethereum. If not, see .
//
-package signer
+package core
import (
"context"
diff --git a/cmd/signer/types.go b/cmd/signer/core/types.go
similarity index 84%
rename from cmd/signer/types.go
rename to cmd/signer/core/types.go
index b91af6625e..03c3a58ff3 100644
--- a/cmd/signer/types.go
+++ b/cmd/signer/core/types.go
@@ -14,7 +14,7 @@
// You should have received a copy of the GNU General Public License
// along with go-ethereum. If not, see .
-package signer
+package core
import (
"encoding/json"
@@ -66,10 +66,10 @@ type TransactionArg struct {
type SendTxArgs struct {
From common.MixedcaseAddress `json:"from"`
To *common.MixedcaseAddress `json:"to"`
- Gas *hexutil.Big `json:"gas"`
- GasPrice *hexutil.Big `json:"gasPrice"`
- Value *hexutil.Big `json:"value"`
- Nonce *hexutil.Uint64 `json:"nonce"`
+ Gas hexutil.Big `json:"gas"`
+ GasPrice hexutil.Big `json:"gasPrice"`
+ Value hexutil.Big `json:"value"`
+ Nonce hexutil.Uint64 `json:"nonce"`
// We accept "data" and "input" for backwards-compatibility reasons.
Data *hexutil.Bytes `json:"data"`
Input *hexutil.Bytes `json:"input"`
@@ -91,7 +91,7 @@ func (args *SendTxArgs) toTransaction() *types.Transaction {
input = *args.Input
}
if args.To == nil {
- return types.NewContractCreation(uint64(*args.Nonce), (*big.Int)(args.Value), (*big.Int)(args.Gas), (*big.Int)(args.GasPrice), input)
+ return types.NewContractCreation(uint64(args.Nonce), (*big.Int)(&args.Value), (*big.Int)(&args.Gas), (*big.Int)(&args.GasPrice), input)
}
- return types.NewTransaction(uint64(*args.Nonce), (*args.To).Address(), (*big.Int)(args.Value), (*big.Int)(args.Gas), (*big.Int)(args.GasPrice), input)
+ return types.NewTransaction(uint64(args.Nonce), args.To.Address(), (*big.Int)(&args.Value), (*big.Int)(&args.Gas), (*big.Int)(&args.GasPrice), input)
}
diff --git a/cmd/signer/main.go b/cmd/signer/main.go
index 398d1e2197..fa612f0258 100644
--- a/cmd/signer/main.go
+++ b/cmd/signer/main.go
@@ -16,7 +16,7 @@
// signer is a utility that can be used so sign transactions and
// arbitrary data.
-package signer
+package main
import (
"fmt"
@@ -33,6 +33,7 @@ import (
"github.com/ethereum/go-ethereum/node"
"github.com/ethereum/go-ethereum/rpc"
"gopkg.in/urfave/cli.v1"
+ "github.com/ethereum/go-ethereum/cmd/signer/core"
)
func main() {
@@ -90,7 +91,7 @@ func main() {
app.Action = func(c *cli.Context) error {
var (
- ui SignerUI
+ ui core.SignerUI
)
// Set up the logger to print everything
logOutput := os.Stdout
@@ -100,14 +101,14 @@ func main() {
log.Root().SetHandler(log.LvlFilterHandler(log.Lvl(c.Int("loglevel")), log.StreamHandler(logOutput, log.TerminalFormat(true))))
if c.Bool("stdio-ui") {
- ui = NewStdIOUI()
+ ui = core.NewStdIOUI()
} else {
- ui = NewCommandlineUI()
+ ui = core.NewCommandlineUI()
}
if c.Bool("stdio-ui") {
log.Info("Using stdin/stdout as UI-channel")
}
- db, err := NewAbiDBFromFile(c.String("4bytedb"))
+ db, err := core.NewAbiDBFromFile(c.String("4bytedb"))
if err != nil {
utils.Fatalf(err.Error())
@@ -115,12 +116,12 @@ func main() {
log.Info("Loaded 4byte db", "signatures", db.Size(), "file", c.String("4bytedb"))
var (
- api ExternalAPI
+ api core.ExternalAPI
listener net.Listener
server = rpc.NewServer()
)
- api_impl := NewSignerAPI(
+ api_impl := core.NewSignerAPI(
c.Int64(utils.NetworkIdFlag.Name),
c.String("keystore"),
c.Bool(utils.NoUSBFlag.Name),
@@ -131,7 +132,7 @@ func main() {
// Audit logging
if logfile := c.String("auditlog"); logfile != "" {
- api, err = NewAuditLogger(logfile, api_impl)
+ api, err = core.NewAuditLogger(logfile, api_impl)
if err != nil {
utils.Fatalf(err.Error())
}
@@ -170,7 +171,7 @@ func main() {
}
-func testExternalUI(api *SignerAPI) {
+func testExternalUI(api *core.SignerAPI) {
ctx := context.WithValue(context.Background(), "remote", "signer binary")
ctx = context.WithValue(ctx, "scheme", "in-proc")
@@ -178,17 +179,17 @@ func testExternalUI(api *SignerAPI) {
errs := make([]string, 0)
- api.ui.ShowInfo("Testing 'ShowInfo'")
- api.ui.ShowError("Testing 'ShowError'")
+ api.UI.ShowInfo("Testing 'ShowInfo'")
+ api.UI.ShowError("Testing 'ShowError'")
checkErr := func(method string, err error) {
- if err != nil && err != ErrRequestDenied {
+ if err != nil && err != core.ErrRequestDenied {
errs = append(errs, fmt.Sprintf("%v: %v", method, err.Error()))
}
}
var err error
- _, err = api.SignTransaction(ctx, SendTxArgs{From:common.MixedcaseAddress{}}, nil)
+ _, err = api.SignTransaction(ctx, core.SendTxArgs{From:common.MixedcaseAddress{}}, nil)
checkErr("SignTransaction", err)
_, err = api.Sign(ctx, common.MixedcaseAddress{}, common.Hex2Bytes("01020304"))
checkErr("Sign", err)
@@ -201,7 +202,7 @@ func testExternalUI(api *SignerAPI) {
_, err = api.Import(ctx, json.RawMessage{})
checkErr("Import", err)
- api.ui.ShowInfo("Tests completed")
+ api.UI.ShowInfo("Tests completed")
if len(errs) > 0 {
log.Error("Got errors")
diff --git a/cmd/signer/rules/rules.go b/cmd/signer/rules/rules.go
index 65cf467f60..b0b40045d1 100644
--- a/cmd/signer/rules/rules.go
+++ b/cmd/signer/rules/rules.go
@@ -19,7 +19,6 @@ package rules
import (
"encoding/json"
"fmt"
- "github.com/ethereum/go-ethereum/cmd/signer"
"github.com/ethereum/go-ethereum/cmd/signer/rules/deps"
"github.com/ethereum/go-ethereum/cmd/signer/storage"
"github.com/ethereum/go-ethereum/internal/ethapi"
@@ -27,6 +26,7 @@ import (
"github.com/robertkrimen/otto"
"os"
"strings"
+ "github.com/ethereum/go-ethereum/cmd/signer/core"
)
var (
@@ -48,7 +48,7 @@ func consoleOutput(call otto.FunctionCall) otto.Value {
// file for each defined UI-method
type rulesetUi struct {
vm *otto.Otto // The JS vm
- next signer.SignerUI // The next handler, for manual processing
+ next core.SignerUI // The next handler, for manual processing
storage storage.Storage
}
@@ -104,45 +104,45 @@ func (r *rulesetUi) checkApproval(jsfunc string, jsarg []byte, err error) error
return fmt.Errorf("rejected")
}
-func (r *rulesetUi) ApproveTx(request *signer.SignTxRequest) (signer.SignTxResponse, error) {
+func (r *rulesetUi) ApproveTx(request *core.SignTxRequest) (core.SignTxResponse, error) {
jsonreq, err := json.Marshal(request)
if err = r.checkApproval("ApproveTx", jsonreq, err); err == nil {
- return signer.SignTxResponse{Transaction: request.Transaction, Approved: true, Password: ""}, nil
+ return core.SignTxResponse{Transaction: request.Transaction, Approved: true, Password: ""}, nil
}
- return signer.SignTxResponse{Approved: false}, err
+ return core.SignTxResponse{Approved: false}, err
}
-func (r *rulesetUi) ApproveSignData(request *signer.SignDataRequest) (signer.SignDataResponse, error) {
+func (r *rulesetUi) ApproveSignData(request *core.SignDataRequest) (core.SignDataResponse, error) {
jsonreq, err := json.Marshal(request)
if err = r.checkApproval("ApproveTx", jsonreq, err); err == nil {
- return signer.SignDataResponse{Approved: true, Password: ""}, nil
+ return core.SignDataResponse{Approved: true, Password: ""}, nil
}
- return signer.SignDataResponse{Approved: false, Password: ""}, err
+ return core.SignDataResponse{Approved: false, Password: ""}, err
}
-func (r *rulesetUi) ApproveExport(request *signer.ExportRequest) (signer.ExportResponse, error) {
+func (r *rulesetUi) ApproveExport(request *core.ExportRequest) (core.ExportResponse, error) {
jsonreq, err := json.Marshal(request)
if err = r.checkApproval("ApproveTx", jsonreq, err); err == nil {
- return signer.ExportResponse{Approved: true}, nil
+ return core.ExportResponse{Approved: true}, nil
}
- return signer.ExportResponse{Approved: false}, err
+ return core.ExportResponse{Approved: false}, err
}
-func (r *rulesetUi) ApproveImport(request *signer.ImportRequest) (signer.ImportResponse, error) {
+func (r *rulesetUi) ApproveImport(request *core.ImportRequest) (core.ImportResponse, error) {
// This cannot be handled by rules, requires setting a password
// dispatch to next
return r.next.ApproveImport(request)
}
-func (r *rulesetUi) ApproveListing(request *signer.ListRequest) (signer.ListResponse, error) {
+func (r *rulesetUi) ApproveListing(request *core.ListRequest) (core.ListResponse, error) {
jsonreq, err := json.Marshal(request)
if err = r.checkApproval("ApproveListing", jsonreq, err); err == nil {
- return signer.ListResponse{Accounts: request.Accounts}, nil
+ return core.ListResponse{Accounts: request.Accounts}, nil
}
- return signer.ListResponse{}, err
+ return core.ListResponse{}, err
}
-func (r *rulesetUi) ApproveNewAccount(request *signer.NewAccountRequest) (signer.NewAccountResponse, error) {
+func (r *rulesetUi) ApproveNewAccount(request *core.NewAccountRequest) (core.NewAccountResponse, error) {
// This cannot be handled by rules, requires setting a password
// dispatch to next
return r.next.ApproveNewAccount(request)
diff --git a/cmd/signer/rules/rules_test.go b/cmd/signer/rules/rules_test.go
index c283d6d5d0..fe738da8c3 100644
--- a/cmd/signer/rules/rules_test.go
+++ b/cmd/signer/rules/rules_test.go
@@ -3,13 +3,13 @@ package rules
import (
"fmt"
"github.com/ethereum/go-ethereum/accounts"
- "github.com/ethereum/go-ethereum/cmd/signer"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/internal/ethapi"
"math/big"
"testing"
+ "github.com/ethereum/go-ethereum/cmd/signer/core"
)
const JS = `
@@ -66,11 +66,11 @@ func initRuleEngine(js string) (*rulesetUi, error) {
}
func TestListRequest(t *testing.T) {
- accs := make([]signer.Account, 5)
+ accs := make([]core.Account, 5)
for i, _ := range accs {
addr := fmt.Sprintf("000000000000000000000000000000000000000%x", i)
- acc := signer.Account{
+ acc := core.Account{
Address: common.BytesToAddress(common.Hex2Bytes(addr)),
URL: accounts.URL{Scheme: "test", Path: fmt.Sprintf("acc-%d", i)},
}
@@ -84,9 +84,9 @@ func TestListRequest(t *testing.T) {
t.Errorf("Couldn't create evaluator %v", err)
return
}
- resp, err := r.ApproveListing(&signer.ListRequest{
+ resp, err := r.ApproveListing(&core.ListRequest{
accs,
- signer.Metadata{
+ core.Metadata{
"remoteip", "localip", "inproc",
},
})
@@ -126,12 +126,12 @@ func TestSignTxRequest(t *testing.T) {
return
}
fmt.Printf("to %v", to.Address().String())
- resp, err := r.ApproveTx(&signer.SignTxRequest{
- Transaction: signer.SendTxArgs{
+ resp, err := r.ApproveTx(&core.SignTxRequest{
+ Transaction: core.SendTxArgs{
From: *from,
To: to},
Callinfo: "",
- Meta: signer.Metadata{"remoteip", "localip", "inproc"},
+ Meta: core.Metadata{"remoteip", "localip", "inproc"},
})
if err != nil {
t.Errorf("Unexpected error %v", err)
@@ -290,7 +290,7 @@ const ExampleTxWindow = `
`
-func dummyTx(value *hexutil.Big) *signer.SignTxRequest {
+func dummyTx(value hexutil.Big) *core.SignTxRequest {
to, _ := mixAddr("000000000000000000000000000000000000dead")
from, _ := mixAddr("000000000000000000000000000000000000dead")
@@ -298,17 +298,17 @@ func dummyTx(value *hexutil.Big) *signer.SignTxRequest {
gas := hexutil.Big(*big.NewInt(21000))
gasPrice := hexutil.Big(*big.NewInt(2000000))
- return &signer.SignTxRequest{
- Transaction: signer.SendTxArgs{
+ return &core.SignTxRequest{
+ Transaction: core.SendTxArgs{
From: *from,
To: to,
Value: value,
- Nonce: &n,
- GasPrice: &gas,
- Gas: &gasPrice,
+ Nonce: n,
+ GasPrice: gas,
+ Gas: gasPrice,
},
Callinfo: "Warning, all your base are bellong to us",
- Meta: signer.Metadata{"remoteip", "localip", "inproc"},
+ Meta: core.Metadata{"remoteip", "localip", "inproc"},
}
}
func dummySigned(value *big.Int) *types.Transaction {
@@ -335,7 +335,7 @@ func TestLimitWindow(t *testing.T) {
h := hexutil.Big(*v)
// The first three should succeed
for i := 0; i < 3; i++ {
- unsigned := dummyTx(&h)
+ unsigned := dummyTx(h)
resp, err := r.ApproveTx(unsigned)
if err != nil {
t.Errorf("Unexpected error %v", err)
@@ -352,7 +352,7 @@ func TestLimitWindow(t *testing.T) {
r.OnApprovedTx(response)
}
// Fourth should fail
- resp, err := r.ApproveTx(dummyTx(&h))
+ resp, err := r.ApproveTx(dummyTx(h))
if resp.Approved {
t.Errorf("Expected check to resolve to 'Reject'")
}