Consensys / web3js-quorum

30 stars 21 forks source link

Unable to add privateFrom for named resident group for MPS enanbled quorum node v21.7.1 #36

Closed subhasisbanik closed 2 years ago

subhasisbanik commented 2 years ago

System information

Client type: GoQuorum

Client version: v21.7.1

OS & Version: Ubuntu 18.04

Expected behaviour

Client node running example from : https://github.com/ConsenSys/web3js-quorum/blob/master/7nodes-test/deployContractViaHttp.js to be able to interact with MPS enabled quorum node v21.7.1

Actual behaviour

The below error occurs when I am trying to connect to named (PS1) resident group as the privateFrom as evident in the example provided in this repository. error :>> Error: Returned error: The PrivateFrom address does not match the specified private state (private)

Backtrace

I have set up a MPS enable private quorum network of v21.7.1 with tessera v21.7.2 and am able to push transactions from and to my MPS enabled node with 2 keys passed onto tessera and connecting to geth with : geth attach https://10.16.2.6:22000?PSI=PS1

But I tried to push a new transaction with the example code present at https://github.com/ConsenSys/web3js-quorum/blob/master/7nodes-test/deployContractViaHttp.js as directed from: https://consensys.github.io/web3js-quorum/latest/index.html

where there is no mention of how to pass the Private State information nor is there any mention of how to connect to a multitenant quorum node where we can connect via RPC like:

geth attach https://10.16.2.6:22000?PSI=$PSI --rpcclitls.insecureskipverify --rpcclitoken "bearer $accessToken"

Please help me get this figured out.
subhasisbanik commented 2 years ago

Hi @achraf17 , could you please help me here?

MadelineMurray commented 2 years ago

Thanks for raising @subhasisbanik - we'll look at this in our next sprint.

subhasisbanik commented 2 years ago

@MadelineMurray Any timeline for this to get this completed?

subhasisbanik commented 2 years ago

@MadelineMurray @achraf17 any update on this?

subhasisbanik commented 2 years ago

Thanks for raising @subhasisbanik - we'll look at this in our next sprint.

Any update on this?

achraf17 commented 2 years ago

Hi @subhasisbanik, we have added a script for multi-tenancy which gets an oauth token from the server then requests PSI using that token.

You can start a network using this docker compose

Once you have the PSI you can create a new instance of web3 with the psi e.g

const web3 = new Web3Quorum(new Web3(provider), {
    privateUrl: "http://localhost:9081?PSI=PS1",
  },
  true
);
subhasisbanik commented 2 years ago

Hi @achraf17 , Thanks for providing the details. Steps I have followed:

  1. Set up the quorum network with : export QUORUM_CONSENSUS=raft docker-compose -f docker-compose-4nodes-mt.yml up -d

  2. Get access token from: https://github.com/ConsenSys/web3js-quorum/blob/master/7nodes-test/multi-tenant.js

  3. Try to deploy a sample smart contract with the below code:

const web3 = new Web3Quorum( new Web3(provider), { privateUrl: "http://localhost:9081?PSI=PS1", }, true ); // Example of calling PSI specific API const psi = await web3.eth.getPSI(); console.log(You are connected to ${psi}); console.log(await web3.eth.getAccounts());

    const accAddress = "ed9d02e382b34818e88b88a309c7fe71e65f419d";

    const signAcct = web3.eth.accounts.decrypt({
    "address": accAddress,
    "crypto": {
            "cipher": "aes-128-ctr",
            "ciphertext": "4e77046ba3f699e744acb4a89c36a3ea1158a1bd90a076d36675f4c883864377",
            "cipherparams": {
                    "iv": "a8932af2a3c0225ee8e872bc0e462c11"
            },
            "kdf": "scrypt",
            "kdfparams": {
                    "dklen": 32,
                    "n": 262144,
                    "p": 1,
                    "r": 8,
                    "salt": "8ca49552b3e92f79c51f2cd3d38dfc723412c212e702bd337a3724e8937aff0f"
            },
            "mac": "6d1354fef5aa0418389b1a5d1f5ee0050d7273292a1171c51fd02f9ecff55264"
    },
    "id": "a65d1ac3-db7e-445d-a1cc-b6c5eeaa05e0",
    "version": 3
     }, "");

    const abi = [
        {
            constant: true,
            inputs: [],
            name: "storedData",
            outputs: [{ name: "", type: "uint256" }],
            payable: false,
            type: "function",
        },
        {
            constant: false,
            inputs: [{ name: "x", type: "uint256" }],
            name: "set",
            outputs: [],
            payable: false,
            type: "function",
        },
        {
            constant: true,
            inputs: [],
            name: "get",
            outputs: [{ name: "retVal", type: "uint256" }],
            payable: false,
            type: "function",
        },
        {
            inputs: [{ name: "initVal", type: "uint256" }],
            payable: false,
            type: "constructor",
        },
    ];

    const bytecode ="0x6060604052341561000f57600080fd5b604051602080610149833981016040528080519060200190919050505b806000819055505b505b610104806100456000396000f30060606040526000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680632a1afcd914605157806360fe47b11460775780636d4ce63c146097575b600080fd5b3415605b57600080fd5b606160bd565b6040518082815260200191505060405180910390f35b3415608157600080fd5b6095600480803590602001909190505060c3565b005b341560a157600080fd5b60a760ce565b6040518082815260200191505060405180910390f35b60005481565b806000819055505b50565b6000805490505b905600a165627a7a72305820d5851baab720bba574474de3d09dbeaabc674a15f4dd93b974908476542c23f00029";

    const simpleContract = new web3.eth.Contract(abi);

    const bytecodeWithInitParam = simpleContract
        .deploy({ data: bytecode, arguments: [42] })
        .encodeABI();
    const txCount = await web3.eth.getTransactionCount(`0x${accAddress}`);

    const tx = await web3.priv.generateAndSendRawTransaction({
        gasPrice: 0,
        gasLimit: 4300000,
        value: 0,
        data: bytecodeWithInitParam,
        from: signAcct,
        isPrivate: true,
        privateFrom: "BULeR8JyUWhiuuCMU/HLA0Q5pzkYT+cHII3ZKBey3Bo=",
        privateFor: ["QfeDAys9MPDs2XHExtc84jKGHxZg/aj52DTh0vtA3Xc="],
        nonce: txCount,
        privacyFlag: 2,
        mandatoryFor: ["QfeDAys9MPDs2XHExtc84jKGHxZg/aj52DTh0vtA3Xc="],
    });
    console.log("Contract address: ", tx.contractAddress);

But I am receiving the error below:

StatusCodeError: 500 - "HTTP 405 Method Not Allowed" at new StatusCodeError (/home/test/web3quorum-sample/web3js-codebase/web3js-quorum/node_modules/request-promise-core/lib/errors.js:32:15) at Request.plumbing.callback (/home/test/web3quorum-sample/web3js-codebase/web3js-quorum/node_modules/request-promise-core/lib/plumbing.js:104:33) at Request.RP$callback [as _callback] (/home/test/web3quorum-sample/web3js-codebase/web3js-quorum/node_modules/request-promise-core/lib/plumbing.js:46:31) at Request.self.callback (/home/test/web3quorum-sample/web3js-codebase/web3js-quorum/node_modules/request/request.js:185:22) at Request.emit (events.js:314:20) at Request. (/home/test/web3quorum-sample/web3js-codebase/web3js-quorum/node_modules/request/request.js:1154:10) at Request.emit (events.js:314:20) at IncomingMessage. (/home/test/web3quorum-sample/web3js-codebase/web3js-quorum/node_modules/request/request.js:1076:12) at Object.onceWrapper (events.js:420:28) at IncomingMessage.emit (events.js:326:22) at endReadableNT (_stream_readable.js:1241:12) at processTicksAndRejections (internal/process/task_queues.js:84:21) { statusCode: 500, error: 'HTTP 405 Method Not Allowed', options: { method: 'POST', uri: 'http://localhost:9081?PSI=PS1/storeraw', json: true, body: { payload: 'YGBgQFI0FWEAD1dgAID9W2BAUWAggGEBSYM5gQFgQFKAgFGQYCABkJGQUFBbgGAAgZBVUFtQW2EBBIBhAEVgADlgAPMAYGBgQFJgADV8AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACQBGP/////FoBjKhr82RRgUVeAY2D+R7EUYHdXgGNtTOY8FGCXV1tgAID9WzQVYFtXYACA/VtgYWC9VltgQFGAgoFSYCABkVBQYEBRgJEDkPNbNBVggVdgAID9W2CVYASAgDWQYCABkJGQUFBgw1ZbAFs0FWChV2AAgP1bYKdgzlZbYEBRgIKBUmAgAZFQUGBAUYCRA5DzW2AAVIFWW4BgAIGQVVBbUFZbYACAVJBQW5BWAKFlYnp6cjBYINWFG6q3ILuldEdN49Cdvqq8Z0oV9N2TuXSQhHZULCPwACkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKg==', from: 'BULeR8JyUWhiuuCMU/HLA0Q5pzkYT+cHII3ZKBey3Bo=' },

Please help

antonydenyer commented 2 years ago

Apologies, that code example wasn't right. privateUrl is the enclave URL and the provider URL must contain the PSI along with the header options.

Something like:

const provider = new Web3HttpProvider("http://localhost:22000?PSI=PS1", options);
const web3 = new Web3Quorum(new Web3(provider), {
    privateUrl: "http://localhost:9081",
  },
  true
);

Should do the trick.

subhasisbanik commented 2 years ago

Thanks @antonydenyer that worked.