Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bug: can't deploy to JSON-RPC network, where equivalent deployment via Remix and Truffle works #694

Closed
bguiz opened this issue Jul 14, 2020 · 3 comments

Comments

@bguiz
Copy link

bguiz commented Jul 14, 2020

Expected behaviour

  • .getContractFactory() succeeds
  • .deploy() succeeds
  • .deployed() succeeds

Actual Behaviour

  • .getContractFactory() succeeds
  • .deploy() succeeds
  • .deployed() fails

The error thrown comes from within ethers.js: https://github.com/ethers-io/ethers.js/blob/88c7eae/packages/providers/src.ts/formatter.ts#L237-L244
... however, tracing up the stack trace, it appears to originate from the provider in some way.

Note that this smart contract deploys successfully on the same network, using both Remix (with web3 provider from MetaMask). It also deploys successfully using Truffle. Here's the Truffle network config and deployment script, for reference:

  networks: {
    regtest: {
      host: '127.0.0.1',
      port: 4444,
      network_id: 33,
      networkCheckTimeout: 1e3,
    },
  },
const Cars = artifacts.require("Cars");

module.exports = function(deployer) {
  deployer.deploy(Cars);
};

Details

Network configuration:

  networks: {
    regtest: {
      url: 'http://127.0.0.1:4444/',
      chainId: 33,
      timeout: 1e3,
    },
  },

Deployment script:

import { ethers } from '@nomiclabs/buidler';

async function main() {
  const carsFactory = await ethers.getContractFactory('Cars');
  console.log('carsFactory', carsFactory);
  const instance = await carsFactory.deploy();
  console.log('instance', instance);
  const result = await instance.deployed(); /// throws here
  console.log('result', result);
}

main()
  .then(() => {
    console.log('deployed');
  })
  .catch((ex) => {
    console.error(ex);
    process.exit(-1);
  });

Error:

Error: invalid hash (argument="value", value="0x01", code=INVALID_ARGUMENT, version=providers/5.0.4)
    at Logger.makeError (/home/bguiz/code/bguiz/buidler-trial/node_modules/@ethersproject/logger/lib/index.js:179:21)
    at Logger.throwError (/home/bguiz/code/bguiz/buidler-trial/node_modules/@ethersproject/logger/lib/index.js:188:20)
    at Logger.throwArgumentError (/home/bguiz/code/bguiz/buidler-trial/node_modules/@ethersproject/logger/lib/index.js:191:21)
    at Formatter.hash (/home/bguiz/code/bguiz/buidler-trial/node_modules/@ethersproject/providers/lib/formatter.js:196:27)
    at Object.root (/home/bguiz/code/bguiz/buidler-trial/node_modules/@ethersproject/providers/lib/formatter.js:361:20)
    at Function.Formatter.check (/home/bguiz/code/bguiz/buidler-trial/node_modules/@ethersproject/providers/lib/formatter.js:342:40)
    at Formatter.receipt (/home/bguiz/code/bguiz/buidler-trial/node_modules/@ethersproject/providers/lib/formatter.js:316:32)
    at EthersProviderWrapper.<anonymous> (/home/bguiz/code/bguiz/buidler-trial/node_modules/@ethersproject/providers/lib/base-provider.js:1214:70)
    at step (/home/bguiz/code/bguiz/buidler-trial/node_modules/@ethersproject/providers/lib/base-provider.js:46:23)
    at Object.next (/home/bguiz/code/bguiz/buidler-trial/node_modules/@ethersproject/providers/lib/base-provider.js:27:53) {
  reason: 'invalid hash',
  code: 'INVALID_ARGUMENT',
  argument: 'value',
  value: '0x01',
  checkKey: 'root',
  checkValue: '0x01'
}
npm ERR! code ELIFECYCLE
npm ERR! errno 255
npm ERR! buidler-trial@0.0.0 deploy-regtest: `buidler run --network regtest scripts/deploy.ts`
npm ERR! Exit status 255
npm ERR! 
npm ERR! Failed at the buidler-trial@0.0.0 deploy-regtest script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

Version

    "@nomiclabs/buidler": "1.3.8",
    "@nomiclabs/buidler-ethers": "2.0.0",
@bguiz
Copy link
Author

bguiz commented Jul 14, 2020

Did a bit more digging, and got a bit closer to the error, appears to be happening while validating the transaction receipt.

https://github.com/ethers-io/ethers.js/blob/88c7eae/packages/providers/src.ts/formatter.ts#L382-L390 :

    receipt(value: any): TransactionReceipt {
        const result: TransactionReceipt = Formatter.check(this.formats.receipt, value);

        if (value.status != null) {
            result.byzantium = true;
        }

        return result;
    }

... which then goes on to throw here:
https://github.com/ethers-io/ethers.js/blob/88c7eae/packages/providers/src.ts/formatter.ts#L411-L424 :

... in particular at root: Formatter.allowNull(hash),

https://github.com/ethers-io/ethers.js/blob/88c7eae/packages/providers/src.ts/formatter.ts#L99-L114 :

        formats.receipt = {
            to: Formatter.allowNull(this.address, null),
            from: Formatter.allowNull(this.address, null),
            contractAddress: Formatter.allowNull(address, null),
            transactionIndex: number,
            root: Formatter.allowNull(hash),
            gasUsed: bigNumber,
            logsBloom: Formatter.allowNull(data),// @TODO: should this be data?
            blockHash: hash,
            transactionHash: hash,
            logs: Formatter.arrayOf(this.receiptLog.bind(this)),
            blockNumber: number,
            confirmations: Formatter.allowNull(number, null),
            cumulativeGasUsed: bigNumber,
            status: Formatter.allowNull(number)
        };

which fails validation when the hash does not have a length of 32.

Below is the actual transaction receipt contains root: '0x01', - which is just 1 byte - and this is what causes it to throw.

{
  transactionHash: '0x207443dca7009383371745242e4a9cd4bf83f2ff70ddf0c827d27c8f02c5b28c',
  transactionIndex: '0x0',
  blockHash: '0x64f3a04bb67aea8684e1aea3f7673a5d6422cc018f592903490d61f6e456c507',
  blockNumber: '0xb4c',
  cumulativeGasUsed: '0xd93c0',
  gasUsed: '0xd93c0',
  contractAddress: '0xda7ce79725418f4f6e13bf5f520c89cec5f6a974',
  logs: [],
  from: '0xcd2a3d9f938e13cd947ec05abc7fe734df8dd826',
  to: null,
  root: '0x01',
  status: '0x1',
  logsBloom: '0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000'
}

I should probably mention that this network I'm connecting to is not Ethereum, but does have EVM compatibility and JSON-RPC compatibility, and that I can deploy this contract using other Ethereum tools (Remix+MetaMask, and Truffle).

@bguiz
Copy link
Author

bguiz commented Jul 14, 2020

Further digging within the geth source yields that the definition of root in the JSON-RPC response maps to PostState - https://github.com/ethereum/go-ethereum/blob/ce9a289/core/types/receipt.go#L49-L52 :

// Receipt represents the results of a transaction.
type Receipt struct {
	// Consensus fields: These fields are defined by the Yellow Paper
	PostState         []byte `json:"root"`

So, unless I've misread something, it appears that the validation logic for transaction receipts appears to be too strict in this case.

bguiz added a commit to bguiz/ethers.js that referenced this issue Jul 14, 2020
- Currently formatter expects a transaction receipt's root property to be a hash, so 32 bytes
- However, that does not match definition used in geth,
  where this maps to the PostState fields within the Receipt struct,
  thus the current validation appears to be based on convention
- This is currently causing issue with transactions submitted to
  a non-Ethereum, but EVM and JSON-RPC compliant, network
- Refs:
  - https://github.com/ethereum/go-ethereum/blob/ce9a289/core/types/receipt.go#L49-L52
  - NomicFoundation/hardhat#694 (comment)
@fvictorio fvictorio removed their assignment Dec 27, 2022
@fvictorio
Copy link
Member

Hi, I'm checking old issues to see if they are still valid. My guess is that this one isn't and, if it is, it seems to be something related to ethers.js itself and not Hardhat?

So I'm going to tentatively close this. Please let us know if you disagree.

@fvictorio fvictorio closed this as not planned Won't fix, can't repro, duplicate, stale Dec 30, 2022
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Mar 31, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
Archived in project
Development

No branches or pull requests

2 participants