Quorum Ethereum Truffle) Error: Number can only sa

2019-06-12 12:55发布

问题:

I am actually learning smart contract programming on ethereum and I work with truffle. Right now I am making this tutorial here: https://truffleframework.com/tutorials/building-dapps-for-quorum-private-enterprise-blockchains

Where you learn how to create a dapp with quorum. But now I have a problem.

I did everything exactly as described, but when I do:

truffle migrate

I get this error here:

$ truffle migrate
    ⚠️  Important ⚠️
    If you're using an HDWalletProvider, it must be Web3 1.0 enabled or your migration will hang.


    Starting migrations...
    ======================
    > Network name:    'development'
    > Network id:      10
    > Block gas limit: 3758096384


    1_initial_migration.js
    ======================

       Deploying 'Migrations'
       ----------------------
       > transaction hash:    0x0a55cd010bb30247c3ae303e54be8dd13177b520af5967728cf77e07ca9efe76
    - Blocks: 0            Seconds: 0
       > Blocks: 0            Seconds: 0
       > contract address:    0x1932c48b2bF8102Ba33B4A6B545C32236e342f34
       > account:             0xed9d02e382b34818e88B88a309c7fe71E65f419d
       > balance:             1000000000
       > gas used:            245462
       > gas price:           0 gwei
       > value sent:          0 ETH
       > total cost:          0 ETH


    - Saving migration to chain.
    Error: Number can only safely store up to 53 bits
        at assert (C:\Users\dany.vandermeij\AppData\Roaming\npm\node_modules\truffle\build\webpack:\~\number-to-bn\~\bn.js\lib\bn.js:6:1)
        at BN.toNumber (C:\Users\dany.vandermeij\AppData\Roaming\npm\node_modules\truffle\build\webpack:\~\number-to-bn\~\bn.js\lib\bn.js:506:1)
        at Object.hexToNumber (C:\Users\dany.vandermeij\AppData\Roaming\npm\node_modules\truffle\build\webpack:\~\web3-utils\src\utils.js:234:1)
        at Method.outputBlockFormatter [as outputFormatter] (C:\Users\dany.vandermeij\AppData\Roaming\npm\node_modules\truffle\build\webpack:\~\web3-eth\~\web3-core-helpers\src\formatters.js:239:1)
        at Method.formatOutput (C:\Users\dany.vandermeij\AppData\Roaming\npm\node_modules\truffle\build\webpack:\~\web3-eth\~\web3-core-method\src\index.js:163:1)
        at sendTxCallback (C:\Users\dany.vandermeij\AppData\Roaming\npm\node_modules\truffle\build\webpack:\~\web3-eth\~\web3-core-method\src\index.js:473:1)
        at C:\Users\dany.vandermeij\AppData\Roaming\npm\node_modules\truffle\build\webpack:\~\web3-core-requestmanager\src\index.js:147:1
        at C:\Users\dany.vandermeij\AppData\Roaming\npm\node_modules\truffle\build\webpack:\packages\truffle-migrate\index.js:145:1
        at C:\Users\dany.vandermeij\AppData\Roaming\npm\node_modules\truffle\build\webpack:\packages\truffle-provider\wrapper.js:112:1
        at XMLHttpRequest.request.onreadystatechange (C:\Users\dany.vandermeij\AppData\Roaming\npm\node_modules\truffle\build\webpack:\~\web3-providers-http\src\index.js:96:1)
        at XMLHttpRequestEventTarget.dispatchEvent (C:\Users\dany.vandermeij\AppData\Roaming\npm\node_modules\truffle\build\webpack:\~\xhr2-cookies\dist\xml-http-request-event-target.js:34:1)
        at XMLHttpRequest._setReadyState (C:\Users\dany.vandermeij\AppData\Roaming\npm\node_modules\truffle\build\webpack:\~\xhr2-cookies\dist\xml-http-request.js:208:1)
        at XMLHttpRequest._onHttpResponseEnd (C:\Users\dany.vandermeij\AppData\Roaming\npm\node_modules\truffle\build\webpack:\~\xhr2-cookies\dist\xml-http-request.js:318:1)
        at IncomingMessage.<anonymous> (C:\Users\dany.vandermeij\AppData\Roaming\npm\node_modules\truffle\build\webpack:\~\xhr2-cookies\dist\xml-http-request.js:289:47)
        at emitNone (events.js:111:20)
        at IncomingMessage.emit (events.js:208:7)
        at endReadableNT (_stream_readable.js:1064:12)
        at _combinedTickCallback (internal/process/next_tick.js:138:11)
        at process._tickCallback (internal/process/next_tick.js:180:9)
    Truffle v5.0.1 (core: 5.0.1)
    Node v8.11.4

Now I don't know why...

Does anyone have the same problem and can help me out here?

This is my Smart Contract:

pragma solidity ^0.4.17;

contract SimpleStorage {
  uint public storedData;

  constructor(uint initVal) public {
    storedData = initVal;
  }

  function set(uint x) public {
    storedData = x;
  }

  function get() view public returns (uint retVal) {
    return storedData;
  }
}

And my truffle-config.js file:

module.exports = {
  networks: {
    development: {
      host: "127.0.0.1",
      port: 22000, // was 8545
      network_id: "*", // Match any network id
      gasPrice: 0,
      gas: 4500000
    },
    nodefour:  {
      host: "127.0.0.1",
      port: 22003,
      network_id: "*", // Match any network id
      gasPrice: 0,
      gas: 4500000
    },
    nodeseven:  {
      host: "127.0.0.1",
      port: 22006,
      network_id: "*", // Match any network id
      gasPrice: 0,
      gas: 4500000
    }
  },
  // Set default mocha options here, use special reporters etc.
  mocha: {
    // timeout: 100000
  },

  // Configure your compilers
  compilers: {
    solc: {
      version: "0.4.25",    // Fetch exact version from solc-bin (default: truffle's version)
    }
  }
}

And the migration file:

var SimpleStorage = artifacts.require("SimpleStorage");

module.exports = function(deployer) {
  // Pass 42 to the contract as the first constructor parameter
  deployer.deploy(SimpleStorage, 2, { privateFor: ["ROAZBWtSacxXQrOe3FGAqJDyJjFePR5ce4TSIzmJ0Bc="] })
};

回答1:

So the problem was that the Block Timestamp was in Nanoseconds.

@edgraaff wrote a Proxy who converts the Timestamp from Nanoseconds to Seconds. You can find the code here -> https://github.com/edgraaff/quorum-rpc-proxy

What I had to do is to clone the proxy and change the config.js file to:

module.exports = {
  rpcUrl: 'http://localhost:22000',
  port: 7545
};

And in the truffle-config.js file i had to change the port. Here's the code:

module.exports = {
  networks: {
    development: {
      host: "127.0.0.1",
      port: 7545, // was 8545
      network_id: "*", // Match any network id
      gasPrice: 0,
      gas: 4500000
    },
    nodefour:  {
      host: "127.0.0.1",
      port: 22003,
      network_id: "*", // Match any network id
      gasPrice: 0,
      gas: 4500000
    },
    nodeseven:  {
      host: "127.0.0.1",
      port: 22006,
      network_id: "*", // Match any network id
      gasPrice: 0,
      gas: 4500000
    }
  },
  // Set default mocha options here, use special reporters etc.
  mocha: {
    // timeout: 100000
  },

  // Configure your compilers
  compilers: {
    solc: {
      version: "0.4.25",    // Fetch exact version from solc-bin (default: truffle's version)
    }
  }
}

Thanks to @edgraaff



回答2:

The proxy is not enough, because web3.js can get block in subscribtion via ws

Also in quorum getting block by number is broken, it accept only hex, however web3.js assume hex as blockhash

Here is my solution

web3.extend({
  property: 'eth',
  methods: [new web3.extend.Method({
    name: 'getBlockByNumber',
    call: 'eth_getBlockByNumber',
    params: 2,
    inputFormatter: [web3.extend.formatters.inputBlockNumberFormatter, v => !!v],
    outputFormatter: web3.extend.formatters.outputBlockFormatter
  })]
});
web3.utils.hexToNumber = v => {
  if (!v) return v;
  try {
    return numberToBN(v).toNumber();
  } catch (e) {
    return numberToBN(v).toString();
  }
};

Just take care that timestamp is string now

Here is related issue in web3.js repo https://github.com/ethereum/web3.js/issues/1215



回答3:

You don't need to use any proxy if you downgrade your truffle version to 4.1.15. If you do that everything will work fine. Just don't downgrade to 4.1.14 because truffle init it's broken in that package!.



回答4:

How I have seen in several blogs: the best solution is downgrade the truffle version to truffle@4.1.5. The problem is related to quorum in truffle version 5.

I have made this downgrading and now everything works!



回答5:

Easy fix: Just add type: "quorum" in your truffle-config for the network which is supposed to run on quorum.



回答6:

@QuorumPrivateBlockChain hey mate.

So this is my truffle-config.js file:

module.exports = {
  networks: {
    development: {
      host: "127.0.0.1",
      port: 7545,
      network_id: "*",
      gasPrice: 0,
      gas: 4500000
    },
    nodefour:  {
      host: "127.0.0.1",
      port: 7546,
      network_id: "*",
      gasPrice: 0,
      gas: 4500000
    },
    nodeseven:  {
      host: "127.0.0.1",
      port: 7547,
      network_id: "*",
      gasPrice: 0,
      gas: 4500000
    }
  },
  compilers: {
    solc: {
      version: "0.4.25",   
    }
  }
}

And this is my config.js file from the proxy:

module.exports = [
  {
    rpcUrl: 'http://localhost:22000',
    port: 7545
  },
  {
    rpcUrl: 'http://localhost:22003',
    port: 7546
  },
  {
    rpcUrl: 'http://localhost:22006',
    port: 7547
  },
];

So what you do, you send the requests from your truffle to your proxy and the proxy then converts the timestamp and sends the request further to the node.

The proxy is a program by itself, you don't have to copy the config.js file form the proxy code. Look into the github how you can start the proxy.