diff --git a/core/quorum/api.go b/core/quorum/api.go index 868be5e0d..4d9a5d7fa 100644 --- a/core/quorum/api.go +++ b/core/quorum/api.go @@ -1,11 +1,15 @@ package quorum import ( + "bytes" "fmt" + "os/exec" + "strings" "time" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/private" "github.com/ethereum/go-ethereum/rpc" ) @@ -113,3 +117,85 @@ func (api PublicQuorumAPI) ResumeBlockMaker() error { } return nil } + +// GetPrivatePayload returns the contents of a private transaction +func (api PublicQuorumAPI) GetPrivatePayload(digestHex string) (string, error) { + return private.GetPayload(digestHex) +} + +type PorosityArgs struct { + Code string + Arguments string + Abi string + Hash string + List bool + Disassm bool + SingleStep bool + Cfg bool + CfgFull bool + Decompile bool + Debug bool + Silent bool +} + +type PorosityResult struct { + Vulnerable bool + Output string +} + +func addArg(b []string, k, v string) []string { + b = append(b, fmt.Sprintf("--%s=%s", k, v)) + return b +} + +func (api PublicQuorumAPI) RunPorosity(args PorosityArgs) (*PorosityResult, error) { + // TODO: Rewrite once Porosity is librarified + var ( + stderr, stdout bytes.Buffer + b []string + ) + b = addArg(b, "code", args.Code) + if args.Arguments != "" { + b = addArg(b, "arguments", args.Arguments) + } + if args.Abi != "" { + b = addArg(b, "abi", args.Abi) + } + if args.Hash != "" { + b = addArg(b, "hash", args.Hash) + } + if args.List { + b = addArg(b, "list", "") + } + if args.Disassm { + b = addArg(b, "disassm", "") + } + if args.SingleStep { + b = addArg(b, "single-step", "") + } + if args.Cfg { + b = addArg(b, "cfg", "") + } + if args.CfgFull { + b = addArg(b, "cfg-full", "") + } + if args.Decompile { + b = addArg(b, "decompile", "") + } + if args.Debug { + b = addArg(b, "debug", "") + } + cmd := exec.Command("porosity", b...) + cmd.Stderr = &stderr + cmd.Stdout = &stdout + if err := cmd.Run(); err != nil { + return nil, err + } + out := stdout.String() + pr := new(PorosityResult) + pr.Vulnerable = strings.Contains(out, "") + if !args.Silent { + pr.Output = out + } + return pr, nil +} diff --git a/internal/ethapi/api.go b/internal/ethapi/api.go index 445685c6f..d00737e41 100644 --- a/internal/ethapi/api.go +++ b/internal/ethapi/api.go @@ -578,28 +578,9 @@ func (s *PublicBlockChainAPI) GetUncleCountByBlockHash(ctx context.Context, bloc } // GetQuorumPayload returns the contents of a private transaction +// DEPRECATED in favor of quorum.GetPrivatePayload. func (s *PublicBlockChainAPI) GetQuorumPayload(digestHex string) (string, error) { - if private.P == nil { - return "", fmt.Errorf("PrivateTransactionManager is not enabled") - } - if len(digestHex) < 3 { - return "", fmt.Errorf("Invalid digest hex") - } - if digestHex[:2] == "0x" { - digestHex = digestHex[2:] - } - b, err := hex.DecodeString(digestHex) - if err != nil { - return "", err - } - if len(b) != 64 { - return "", fmt.Errorf("Expected a Quorum digest of length 64, but got %d", len(b)) - } - data, err := private.P.Receive(b) - if err != nil { - return "", err - } - return fmt.Sprintf("0x%x", data), nil + return private.GetPayload(digestHex) } // GetCode returns the code stored at the given address in the state for the given block number. diff --git a/internal/web3ext/web3ext.go b/internal/web3ext/web3ext.go index 4cd9f907a..37f172db8 100644 --- a/internal/web3ext/web3ext.go +++ b/internal/web3ext/web3ext.go @@ -721,6 +721,20 @@ web3._extend({ new web3._extend.Method({ name: 'resumeBlockMaker', call: 'quorum_resumeBlockMaker' + }), + new web3._extend.Method({ + name: 'getPrivatePayload', + params: 1, + call: 'quorum_getPrivatePayload' + }), + new web3._extend.Method({ + name: 'runPorosity', + params: 1, + call: 'quorum_runPorosity', + outputFormatter: function(pr) { + console.log(pr.Output); + return pr.Vulnerable; + } }) ], properties: diff --git a/private/private.go b/private/private.go index 2cf2175bf..1c3726190 100644 --- a/private/private.go +++ b/private/private.go @@ -1,6 +1,8 @@ package private import ( + "encoding/hex" + "fmt" "os" "github.com/ethereum/go-ethereum/private/constellation" @@ -20,3 +22,27 @@ func FromEnvironmentOrNil(name string) PrivateTransactionManager { } var P = FromEnvironmentOrNil("PRIVATE_CONFIG") + +func GetPayload(digestHex string) (string, error) { + if P == nil { + return "", fmt.Errorf("PrivateTransactionManager is not enabled") + } + if len(digestHex) < 3 { + return "", fmt.Errorf("Invalid digest hex") + } + if digestHex[:2] == "0x" { + digestHex = digestHex[2:] + } + b, err := hex.DecodeString(digestHex) + if err != nil { + return "", err + } + if len(b) != 64 { + return "", fmt.Errorf("Expected a Quorum digest of length 64, but got %d", len(b)) + } + data, err := P.Receive(b) + if err != nil { + return "", err + } + return fmt.Sprintf("0x%x", data), nil +}