mirror of https://github.com/poanetwork/quorum.git
Merge branch '1812-permission-rpc-api' of https://github.com/vsmk98/quorum into 1812-permission-rpc-api
merge with Amal's api segregation changes
This commit is contained in:
commit
d49ed0318e
|
@ -361,8 +361,16 @@ func startNode(ctx *cli.Context, stack *node.Node) {
|
|||
}
|
||||
|
||||
func startQuorumPermissionService(ctx *cli.Context, stack *node.Node) {
|
||||
|
||||
var quorumApis []string
|
||||
if ctx.GlobalBool(utils.EnableNodePermissionFlag.Name) {
|
||||
//default quorum api list
|
||||
quorumApis = []string{"quorumNodeMgmt", "quorumAcctMgmt", "quorumKeyMgmt"}
|
||||
} else {
|
||||
quorumApis = []string{"quorumKeyMgmt"}
|
||||
}
|
||||
// start the permissions management service
|
||||
pc, err := permission.NewQuorumPermissionCtrl(stack, ctx.GlobalBool(utils.EnableNodePermissionFlag.Name),ctx.GlobalBool(utils.RaftModeFlag.Name))
|
||||
pc, err := permission.NewQuorumPermissionCtrl(stack, ctx.GlobalBool(utils.EnableNodePermissionFlag.Name), ctx.GlobalBool(utils.RaftModeFlag.Name))
|
||||
if err != nil {
|
||||
utils.Fatalf("Failed to start Quorum Permission contract service: %v", err)
|
||||
}
|
||||
|
@ -379,16 +387,20 @@ func startQuorumPermissionService(ctx *cli.Context, stack *node.Node) {
|
|||
log.Trace("Key management service started")
|
||||
}
|
||||
|
||||
v := stack.GetRPC("quorum")
|
||||
if v == nil {
|
||||
utils.Fatalf("Failed to start Quorum Permission API")
|
||||
for _, apiName := range quorumApis {
|
||||
v := stack.GetRPC(apiName)
|
||||
if v == nil {
|
||||
utils.Fatalf("Failed to start Quorum Permission API %s", apiName)
|
||||
}
|
||||
qapi := v.(*quorum.PermissionAPI)
|
||||
rpcClient, err := stack.Attach()
|
||||
if err != nil {
|
||||
utils.Fatalf("Failed to attach to self: %v", err)
|
||||
}
|
||||
stateReader := ethclient.NewClient(rpcClient)
|
||||
qapi.Init(stateReader, stack.GetNodeKey())
|
||||
log.Info("Permission API started.", "apiName", apiName)
|
||||
}
|
||||
qapi := v.(*quorum.PermissionAPI)
|
||||
rpcClient, err := stack.Attach()
|
||||
if err != nil {
|
||||
utils.Fatalf("Failed to attach to self: %v", err)
|
||||
}
|
||||
stateReader := ethclient.NewClient(rpcClient)
|
||||
qapi.Init(stateReader, stack.GetNodeKey())
|
||||
|
||||
log.Info("Permission API initialized")
|
||||
}
|
||||
|
|
|
@ -3,8 +3,8 @@ package permission
|
|||
import (
|
||||
"crypto/ecdsa"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"math/big"
|
||||
"os"
|
||||
|
@ -38,14 +38,14 @@ const (
|
|||
)
|
||||
|
||||
type PermissionCtrl struct {
|
||||
node *node.Node
|
||||
ethClnt *ethclient.Client
|
||||
eth *eth.Ethereum
|
||||
isRaft bool
|
||||
node *node.Node
|
||||
ethClnt *ethclient.Client
|
||||
eth *eth.Ethereum
|
||||
isRaft bool
|
||||
permissionedMode bool
|
||||
key *ecdsa.PrivateKey
|
||||
dataDir string
|
||||
pm *pbind.Permissions
|
||||
key *ecdsa.PrivateKey
|
||||
dataDir string
|
||||
pm *pbind.Permissions
|
||||
}
|
||||
|
||||
// Creates the controls structure for permissions
|
||||
|
@ -429,7 +429,7 @@ func (p *PermissionCtrl) populateInitPermission() error {
|
|||
utils.Fatalf("Joining a permissioned network in non-permissioned mode. Bring up get with --permissioned.")
|
||||
}
|
||||
|
||||
if !p.permissionedMode{
|
||||
if !p.permissionedMode {
|
||||
return errors.New("Node started in non-permissioned mode")
|
||||
}
|
||||
if tx != true {
|
||||
|
|
|
@ -73,7 +73,7 @@ type txArgs struct {
|
|||
}
|
||||
|
||||
type nodeStatus struct {
|
||||
Name string
|
||||
Name string
|
||||
Status string
|
||||
}
|
||||
|
||||
|
@ -82,6 +82,17 @@ type ExecStatus struct {
|
|||
Msg string
|
||||
}
|
||||
|
||||
var nodeApproveStatus = map[uint8]string{
|
||||
0: "Unknown",
|
||||
1: "PendingApproval",
|
||||
2: "Approved",
|
||||
3: "PendingDeactivation",
|
||||
4: "Deactivated",
|
||||
5: "PendingActivation",
|
||||
6: "PendingBlacklisting",
|
||||
7: "Blacklisted",
|
||||
}
|
||||
|
||||
// NewPermissionAPI creates a new PermissionAPI to access quorum services
|
||||
func NewPermissionAPI(tp *core.TxPool, am *accounts.Manager) *PermissionAPI {
|
||||
return &PermissionAPI{tp, nil, am, nil, nil, nil, nil}
|
||||
|
@ -89,28 +100,10 @@ func NewPermissionAPI(tp *core.TxPool, am *accounts.Manager) *PermissionAPI {
|
|||
|
||||
// helper function decodes the node status to string
|
||||
func decodeNodeStatus(nodeStatus uint8) string {
|
||||
var status string
|
||||
switch nodeStatus{
|
||||
case 0:
|
||||
status = "Unknown"
|
||||
case 1:
|
||||
status = "PendingApproval"
|
||||
case 2:
|
||||
status = "Approved"
|
||||
case 3:
|
||||
status = "PendingDeactivation"
|
||||
case 4:
|
||||
status = "Deactivated"
|
||||
case 5:
|
||||
status = "PendingActivation"
|
||||
case 6:
|
||||
status = "PendingBlacklisting"
|
||||
case 7:
|
||||
status = "Blacklisted"
|
||||
default:
|
||||
status = "Unknown"
|
||||
if status, ok := nodeApproveStatus[nodeStatus]; ok {
|
||||
return status
|
||||
}
|
||||
return status
|
||||
return "Unknown"
|
||||
}
|
||||
|
||||
//Init initializes PermissionAPI with eth client, permission contract and org key management control
|
||||
|
@ -130,7 +123,7 @@ func (p *PermissionAPI) Init(ethClnt *ethclient.Client, key *ecdsa.PrivateKey) e
|
|||
return nil
|
||||
}
|
||||
|
||||
// Returns the list of Nodes and status of each
|
||||
// Returns the list of Nodes and status of each
|
||||
func (s *PermissionAPI) PermissionNodeList() []nodeStatus {
|
||||
auth := bind.NewKeyedTransactor(s.key)
|
||||
ps := &pbind.PermissionsSession{
|
||||
|
@ -147,14 +140,14 @@ func (s *PermissionAPI) PermissionNodeList() []nodeStatus {
|
|||
}
|
||||
// get the total number of nodes on the contract
|
||||
nodeCnt, err := ps.GetNumberOfNodes()
|
||||
|
||||
nodeStatArr := make([]nodeStatus, nodeCnt.Uint64())
|
||||
nodeCntI := nodeCnt.Int64()
|
||||
nodeStatArr := make([]nodeStatus, nodeCntI)
|
||||
// loop for each index and get the node details from the contract
|
||||
if err == nil {
|
||||
i := int64(0)
|
||||
for nodeCnt.Cmp(big.NewInt(i)) > 0{
|
||||
for i < nodeCntI {
|
||||
nodeDtls, _ := ps.GetNodeDetails(big.NewInt(i))
|
||||
nodeStatArr[i].Name = "enode://"+ nodeDtls.EnodeId + "@" +nodeDtls.IpAddrPort
|
||||
nodeStatArr[i].Name = "enode://" + nodeDtls.EnodeId + "@" + nodeDtls.IpAddrPort
|
||||
nodeStatArr[i].Name += "?discport=" + nodeDtls.DiscPort
|
||||
if len(nodeDtls.RaftPort) > 0 {
|
||||
nodeStatArr[i].Name += "&raftport" + nodeDtls.RaftPort
|
||||
|
@ -253,7 +246,7 @@ func (s *PermissionAPI) executePermAction(action PermAction, args txArgs) ExecSt
|
|||
tx, err = ps.RemoveVoter(args.voter)
|
||||
|
||||
case ProposeNode:
|
||||
if !checkVoterExists(ps){
|
||||
if !checkVoterExists(ps) {
|
||||
return voterErr
|
||||
}
|
||||
node, err = discover.ParseNode(args.nodeId)
|
||||
|
@ -271,7 +264,7 @@ func (s *PermissionAPI) executePermAction(action PermAction, args txArgs) ExecSt
|
|||
tx, err = ps.ProposeNode(enodeID, ipAddrPort, discPort, raftPort)
|
||||
|
||||
case ApproveNode:
|
||||
if !checkIsVoter(ps, args.txa.From){
|
||||
if !checkIsVoter(ps, args.txa.From) {
|
||||
return voterErr
|
||||
}
|
||||
node, err = discover.ParseNode(args.nodeId)
|
||||
|
@ -283,7 +276,7 @@ func (s *PermissionAPI) executePermAction(action PermAction, args txArgs) ExecSt
|
|||
tx, err = ps.ApproveNode(enodeID)
|
||||
|
||||
case ProposeNodeDeactivation:
|
||||
if !checkVoterExists(ps){
|
||||
if !checkVoterExists(ps) {
|
||||
return voterErr
|
||||
}
|
||||
node, err = discover.ParseNode(args.nodeId)
|
||||
|
@ -295,7 +288,7 @@ func (s *PermissionAPI) executePermAction(action PermAction, args txArgs) ExecSt
|
|||
tx, err = ps.ProposeDeactivation(enodeID)
|
||||
|
||||
case ApproveNodeDeactivation:
|
||||
if !checkIsVoter(ps, args.txa.From){
|
||||
if !checkIsVoter(ps, args.txa.From) {
|
||||
return voterErr
|
||||
}
|
||||
node, err = discover.ParseNode(args.nodeId)
|
||||
|
@ -307,7 +300,7 @@ func (s *PermissionAPI) executePermAction(action PermAction, args txArgs) ExecSt
|
|||
tx, err = ps.DeactivateNode(enodeID)
|
||||
|
||||
case ProposeNodeActivation:
|
||||
if !checkVoterExists(ps){
|
||||
if !checkVoterExists(ps) {
|
||||
return voterErr
|
||||
}
|
||||
node, err = discover.ParseNode(args.nodeId)
|
||||
|
@ -319,7 +312,7 @@ func (s *PermissionAPI) executePermAction(action PermAction, args txArgs) ExecSt
|
|||
tx, err = ps.ProposeNodeActivation(enodeID)
|
||||
|
||||
case ApproveNodeActivation:
|
||||
if !checkIsVoter(ps, args.txa.From){
|
||||
if !checkIsVoter(ps, args.txa.From) {
|
||||
return voterErr
|
||||
}
|
||||
node, err = discover.ParseNode(args.nodeId)
|
||||
|
@ -331,7 +324,7 @@ func (s *PermissionAPI) executePermAction(action PermAction, args txArgs) ExecSt
|
|||
tx, err = ps.ActivateNode(enodeID)
|
||||
|
||||
case ProposeNodeBlacklisting:
|
||||
if !checkVoterExists(ps){
|
||||
if !checkVoterExists(ps) {
|
||||
return voterErr
|
||||
}
|
||||
node, err = discover.ParseNode(args.nodeId)
|
||||
|
@ -348,7 +341,7 @@ func (s *PermissionAPI) executePermAction(action PermAction, args txArgs) ExecSt
|
|||
|
||||
tx, err = ps.ProposeNodeBlacklisting(enodeID, ipAddrPort, discPort, raftPort)
|
||||
case ApproveNodeBlacklisting:
|
||||
if !checkIsVoter(ps, args.txa.From){
|
||||
if !checkIsVoter(ps, args.txa.From) {
|
||||
return voterErr
|
||||
}
|
||||
node, err = discover.ParseNode(args.nodeId)
|
||||
|
@ -427,6 +420,7 @@ func checkIsVoter(ps *pbind.PermissionsSession, acctId common.Address) bool {
|
|||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// newPermSession creates a new permission contract session
|
||||
func (s *PermissionAPI) newPermSession(w accounts.Wallet, txa ethapi.SendTxArgs) *pbind.PermissionsSession {
|
||||
frmAcct, transactOpts, gasLimit, gasPrice, nonce := s.getTxParams(txa, w)
|
||||
|
|
|
@ -23,6 +23,7 @@ type OrgStruct struct {
|
|||
OrgId string
|
||||
Keys []string
|
||||
}
|
||||
|
||||
var DefaultAccess = FullAccess
|
||||
|
||||
const acctMapLimit = 100
|
||||
|
|
|
@ -35,6 +35,7 @@ import (
|
|||
istanbulBackend "github.com/ethereum/go-ethereum/consensus/istanbul/backend"
|
||||
"github.com/ethereum/go-ethereum/core"
|
||||
"github.com/ethereum/go-ethereum/core/bloombits"
|
||||
"github.com/ethereum/go-ethereum/core/quorum"
|
||||
"github.com/ethereum/go-ethereum/core/rawdb"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/ethereum/go-ethereum/core/vm"
|
||||
|
@ -52,7 +53,6 @@ import (
|
|||
"github.com/ethereum/go-ethereum/params"
|
||||
"github.com/ethereum/go-ethereum/rlp"
|
||||
"github.com/ethereum/go-ethereum/rpc"
|
||||
"github.com/ethereum/go-ethereum/core/quorum"
|
||||
)
|
||||
|
||||
type LesServer interface {
|
||||
|
@ -275,14 +275,13 @@ func CreateConsensusEngine(ctx *node.ServiceContext, config *Config, chainConfig
|
|||
func (s *Ethereum) APIs() []rpc.API {
|
||||
apis := ethapi.GetAPIs(s.APIBackend)
|
||||
|
||||
|
||||
//TODO add perm service
|
||||
|
||||
// Append any APIs exposed explicitly by the consensus engine
|
||||
apis = append(apis, s.engine.APIs(s.BlockChain())...)
|
||||
|
||||
// Append all the local APIs and return
|
||||
return append(apis, []rpc.API{
|
||||
apis = append(apis, []rpc.API{
|
||||
{
|
||||
Namespace: "eth",
|
||||
Version: "1.0",
|
||||
|
@ -328,13 +327,51 @@ func (s *Ethereum) APIs() []rpc.API {
|
|||
Public: true,
|
||||
},
|
||||
{
|
||||
Namespace: "quorum",
|
||||
Namespace: "quorumNodeMgmt",
|
||||
Version: "1.0",
|
||||
Service: quorum.NewPermissionAPI(s.txPool, s.accountManager),
|
||||
Public: true,
|
||||
},
|
||||
{
|
||||
Namespace: "quorumAcctMgmt",
|
||||
Version: "1.0",
|
||||
Service: quorum.NewPermissionAPI(s.txPool, s.accountManager),
|
||||
Public: true,
|
||||
},
|
||||
{
|
||||
Namespace: "quorumKeyMgmt",
|
||||
Version: "1.0",
|
||||
Service: quorum.NewPermissionAPI(s.txPool, s.accountManager),
|
||||
Public: true,
|
||||
},
|
||||
|
||||
}...)
|
||||
|
||||
if s.config.EnableNodePermission {
|
||||
apis = append(apis, []rpc.API{
|
||||
{
|
||||
Namespace: "quorumNodeMgmt",
|
||||
Version: "1.0",
|
||||
Service: quorum.NewPermissionAPI(s.txPool, s.accountManager),
|
||||
Public: true,
|
||||
},
|
||||
{
|
||||
Namespace: "quorumAcctMgmt",
|
||||
Version: "1.0",
|
||||
Service: quorum.NewPermissionAPI(s.txPool, s.accountManager),
|
||||
Public: true,
|
||||
},
|
||||
}...)
|
||||
}
|
||||
apis = append(apis, []rpc.API{
|
||||
{
|
||||
Namespace: "quorumKeyMgmt",
|
||||
Version: "1.0",
|
||||
Service: quorum.NewPermissionAPI(s.txPool, s.accountManager),
|
||||
Public: true,
|
||||
},
|
||||
}...)
|
||||
|
||||
return apis
|
||||
}
|
||||
|
||||
func (s *Ethereum) ResetWithGenesisBlock(gb *types.Block) {
|
||||
|
|
|
@ -18,21 +18,23 @@
|
|||
package web3ext
|
||||
|
||||
var Modules = map[string]string{
|
||||
"admin": Admin_JS,
|
||||
"chequebook": Chequebook_JS,
|
||||
"clique": Clique_JS,
|
||||
"debug": Debug_JS,
|
||||
"eth": Eth_JS,
|
||||
"miner": Miner_JS,
|
||||
"net": Net_JS,
|
||||
"personal": Personal_JS,
|
||||
"rpc": RPC_JS,
|
||||
"shh": Shh_JS,
|
||||
"swarmfs": SWARMFS_JS,
|
||||
"txpool": TxPool_JS,
|
||||
"raft": Raft_JS,
|
||||
"istanbul": Istanbul_JS,
|
||||
"quorum": QUORUM_JS,
|
||||
"admin": Admin_JS,
|
||||
"chequebook": Chequebook_JS,
|
||||
"clique": Clique_JS,
|
||||
"debug": Debug_JS,
|
||||
"eth": Eth_JS,
|
||||
"miner": Miner_JS,
|
||||
"net": Net_JS,
|
||||
"personal": Personal_JS,
|
||||
"rpc": RPC_JS,
|
||||
"shh": Shh_JS,
|
||||
"swarmfs": SWARMFS_JS,
|
||||
"txpool": TxPool_JS,
|
||||
"raft": Raft_JS,
|
||||
"istanbul": Istanbul_JS,
|
||||
"quorumNodeMgmt": QUORUM_NODE_JS,
|
||||
"quorumAcctMgmt": QUORUM_ACCT_JS,
|
||||
"quorumKeyMgmt": QUORUM_KEY_JS,
|
||||
}
|
||||
|
||||
const Chequebook_JS = `
|
||||
|
@ -683,100 +685,124 @@ web3._extend({
|
|||
})
|
||||
`
|
||||
|
||||
const QUORUM_JS = `
|
||||
const QUORUM_NODE_JS = `
|
||||
web3._extend({
|
||||
property: 'quorum',
|
||||
property: 'quorumNodeMgmt',
|
||||
methods:
|
||||
[
|
||||
new web3._extend.Method({
|
||||
name: 'addVoter',
|
||||
call: 'quorum_addVoter',
|
||||
call: 'quorumNodeMgmt_addVoter',
|
||||
params: 2,
|
||||
inputFormatter: [web3._extend.formatters.inputAddressFormatter,web3._extend.formatters.inputTransactionFormatter]
|
||||
}),
|
||||
new web3._extend.Method({
|
||||
name: 'removeVoter',
|
||||
call: 'quorum_removeVoter',
|
||||
call: 'quorumNodeMgmt_removeVoter',
|
||||
params: 2,
|
||||
inputFormatter: [web3._extend.formatters.inputAddressFormatter,web3._extend.formatters.inputTransactionFormatter]
|
||||
}),
|
||||
new web3._extend.Method({
|
||||
name: 'proposeNode',
|
||||
call: 'quorum_proposeNode',
|
||||
call: 'quorumNodeMgmt_proposeNode',
|
||||
params: 2,
|
||||
inputFormatter: [null,web3._extend.formatters.inputTransactionFormatter]
|
||||
}),
|
||||
new web3._extend.Method({
|
||||
name: 'approveNode',
|
||||
call: 'quorum_approveNode',
|
||||
call: 'quorumNodeMgmt_approveNode',
|
||||
params: 2,
|
||||
inputFormatter: [null,web3._extend.formatters.inputTransactionFormatter]
|
||||
}),
|
||||
new web3._extend.Method({
|
||||
name: 'proposeNodeDeactivation',
|
||||
call: 'quorum_proposeNodeDeactivation',
|
||||
call: 'quorumNodeMgmt_proposeNodeDeactivation',
|
||||
params: 2,
|
||||
inputFormatter: [null,web3._extend.formatters.inputTransactionFormatter]
|
||||
}),
|
||||
new web3._extend.Method({
|
||||
name: 'approveNodeDeactivation',
|
||||
call: 'quorum_approveNodeDeactivation',
|
||||
call: 'quorumNodeMgmt_approveNodeDeactivation',
|
||||
params: 2,
|
||||
inputFormatter: [null,web3._extend.formatters.inputTransactionFormatter]
|
||||
}),
|
||||
new web3._extend.Method({
|
||||
name: 'proposeNodeActivation',
|
||||
call: 'quorum_proposeNodeActivation',
|
||||
call: 'quorumNodeMgmt_proposeNodeActivation',
|
||||
params: 2,
|
||||
inputFormatter: [null,web3._extend.formatters.inputTransactionFormatter]
|
||||
}),
|
||||
new web3._extend.Method({
|
||||
name: 'approveNodeActivation',
|
||||
call: 'quorum_approveNodeActivation',
|
||||
call: 'quorumNodeMgmt_approveNodeActivation',
|
||||
params: 2,
|
||||
inputFormatter: [null,web3._extend.formatters.inputTransactionFormatter]
|
||||
}),
|
||||
new web3._extend.Method({
|
||||
name: 'proposeNodeBlacklisting',
|
||||
call: 'quorum_proposeNodeBlacklisting',
|
||||
call: 'quorumNodeMgmt_proposeNodeBlacklisting',
|
||||
params: 2,
|
||||
inputFormatter: [null,web3._extend.formatters.inputTransactionFormatter]
|
||||
}),
|
||||
new web3._extend.Method({
|
||||
name: 'approveNodeBlacklisting',
|
||||
call: 'quorum_approveNodeBlacklisting',
|
||||
call: 'quorumNodeMgmt_approveNodeBlacklisting',
|
||||
params: 2,
|
||||
inputFormatter: [null,web3._extend.formatters.inputTransactionFormatter]
|
||||
}),
|
||||
new web3._extend.Method({
|
||||
name: 'setAccountAccess',
|
||||
call: 'quorum_setAccountAccess',
|
||||
params: 3,
|
||||
inputFormatter: [web3._extend.formatters.inputAddressFormatter,null,web3._extend.formatters.inputTransactionFormatter]
|
||||
}),
|
||||
new web3._extend.Method({
|
||||
name: 'addOrgKey',
|
||||
call: 'quorum_addOrgKey',
|
||||
params: 3,
|
||||
inputFormatter: [null,null,web3._extend.formatters.inputTransactionFormatter]
|
||||
}),
|
||||
new web3._extend.Method({
|
||||
name: 'removeOrgKey',
|
||||
call: 'quorum_removeOrgKey',
|
||||
params: 3,
|
||||
inputFormatter: [null,null,web3._extend.formatters.inputTransactionFormatter]
|
||||
}),
|
||||
],
|
||||
properties:
|
||||
[
|
||||
new web3._extend.Property({
|
||||
name: 'permissionNodeList',
|
||||
getter: 'quorum_permissionNodeList'
|
||||
getter: 'quorumNodeMgmt_permissionNodeList'
|
||||
}),
|
||||
]
|
||||
})
|
||||
`
|
||||
|
||||
const QUORUM_ACCT_JS = `
|
||||
web3._extend({
|
||||
property: 'quorumAcctMgmt',
|
||||
methods:
|
||||
[
|
||||
new web3._extend.Method({
|
||||
name: 'setAccountAccess',
|
||||
call: 'quorumAcctMgmt_setAccountAccess',
|
||||
params: 3,
|
||||
inputFormatter: [web3._extend.formatters.inputAddressFormatter,null,web3._extend.formatters.inputTransactionFormatter]
|
||||
}),
|
||||
],
|
||||
properties:
|
||||
[
|
||||
]
|
||||
})
|
||||
`
|
||||
|
||||
const QUORUM_KEY_JS = `
|
||||
web3._extend({
|
||||
property: 'quorumKeyMgmt',
|
||||
methods:
|
||||
[
|
||||
new web3._extend.Method({
|
||||
name: 'addOrgKey',
|
||||
call: 'quorumKeyMgmt_addOrgKey',
|
||||
params: 3,
|
||||
inputFormatter: [null,null,web3._extend.formatters.inputTransactionFormatter]
|
||||
}),
|
||||
new web3._extend.Method({
|
||||
name: 'removeOrgKey',
|
||||
call: 'quorumKeyMgmt_removeOrgKey',
|
||||
params: 3,
|
||||
inputFormatter: [null,null,web3._extend.formatters.inputTransactionFormatter]
|
||||
}),
|
||||
],
|
||||
properties:
|
||||
[
|
||||
]
|
||||
})
|
||||
`
|
||||
|
||||
const Istanbul_JS = `
|
||||
web3._extend({
|
||||
property: 'istanbul',
|
||||
|
|
Loading…
Reference in New Issue