question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Truffle tests fail on Solidity 0.4.23 but work on Remix

See original GitHub issue
  • [N] I’ve asked for help in the Truffle Gitter before filing this issue.

Issue

Methods that worked in Solidity version 0.4.20 do not work in 0.4.23, while they do work in Remix. Only thing that has been changed in a contract is constructor - rest stayed the same.

Steps to Reproduce

Run the ./testRootPerson.js test with both 0.4.20 and 0.4.23 compiler (changing pragma’s in contracts).

Expected Behavior

Calling get functions on contracts work, all tests should run.

Actual Results

Tests fail, due to get methods returning 0x values instead of actual values.

  • When running the attached testRootPerson.js test, certain tests return null values when run with Solidity 0.4.23 compiler.
  • When running tests with 0.4.20 compiler (npm install solc@0.4.20 in truffle node_modules) they succeed.
  • Copying the contracts into Remix, selecting the 0.4.23 compiler, and calling the methods on the contracts, they work.
  • Truffle compiler gives a different bytecode output than Remix does using compiler 0.4.23+commit.124ca40d.Emscripten.clang Code supplied at bottom of issue

0.4.20: afbeelding

0.4.23: afbeelding

Environment

  • Operating System: Windows 10 x64 - Ubuntu 16.04 on Virtual Machine
  • Ethereum client: Local 3 node Quorum network on VM
  • Truffle version (truffle version): Truffle v4.1.7 (core: 4.1.7) - Solidity v0.4.23 (solc-js)
  • node version (node --version): v8.9.4
  • npm version (npm --version): 5.6.0

Person.sol

pragma solidity ^0.4.23;

contract Person {

    bytes32 public name;
    struct ContactInformation {
        bytes32 street;
        uint number;
        bytes32 postalCode;
        bytes32 city;
        bytes32 country;
        bytes32 phoneNumber;
    }

    ContactInformation public contactInfo;

    constructor(
        bytes32 _name, bytes32 _street, uint _number, bytes32 _postalCode,
        bytes32 _city, bytes32 _country, bytes32 _phoneNumber) public {
        name = _name;
        contactInfo = ContactInformation(_street, _number, _postalCode, _city, _country, _phoneNumber);
    }

    function getStreet() public view returns (bytes32) {
        return contactInfo.street;
    }

    function getNumber() public view returns (uint) {
        return contactInfo.number;
    }

    function getPostalCode() public view returns (bytes32) {
        return contactInfo.postalCode;
    }

    function getCity() public view returns (bytes32) {
        return contactInfo.city;
    }

    function getCountry() public view returns (bytes32) {
        return contactInfo.country;
    }

    function getPhoneNumber() public view returns (bytes32) {
        return contactInfo.phoneNumber;
    }
}

Root.sol

pragma solidity ^0.4.23;

import "./Person.sol";

contract Root {
    
    Person[] public persons;
    mapping(address => bytes32) public personAddressToName;
    
    
    function addPerson(address _personAddress) public {
        require(_personAddress != address(0));
        Person person = Person(_personAddress);
        persons.push(person);
    }

    function getPersonByAddress(address _personAddress) public view
    returns(address personAddress, bytes32 personName, bytes32 street, uint number, bytes32 postalCode,
    bytes32 city, bytes32 country, bytes32 phoneNumber) {
        Person p = Person(_personAddress);
        require(p != Person(0x0));
        personName = p.name();
        street = p.getStreet();
        number = p.getNumber();
        postalCode = p.getPostalCode();
        city = p.getCity();
        country = p.getCountry();
        phoneNumber = p.getPhoneNumber();
        return (_personAddress, personName, street, number, postalCode, city, country, phoneNumber);
    }

    function getAllPersons() public view returns (Person[]) {
        return persons;
    }

    function getPersonAddressesAndNames() public view returns (Person[] addresses, bytes32[] memory names) {
        names = new bytes32[](persons.length);
        for (uint i = 0; i < persons.length; i++) {
            Person p = Person(persons[i]);
            names[i] = p.name();
        }
        return (persons, names);
    }

}

testRootPerson.js

const Root = artifacts.require('Root');
const Person = artifacts.require('Person');
const Web3 = require('web3');

const develop = '/*address*/';
const web3 = new Web3();
let rootInstance;
let personInstance;

contract('Root + Person', () => {
  it('should correctly add Person to root contract', () =>
    // 1. Deploy new root contract
    Root.deployed()
      .then((deployedInstance) => {
        // 2.1 Check if contract has been deployed
        assert.notEqual(deployedInstance.contract.address, '0x0000000000000000000000000000000000000000', 'Root address should not be address(0) - incorrectly deployed');
        // 2.2 Save root instance
        rootInstance = deployedInstance.contract;
        // 3. Deploy new Person contract
        return Person.deployed();
      })
      .then((deployedInstance) => {
        // 4.1 Check if contract has been deployed
        assert.notEqual(deployedInstance.contract.address, '0x0000000000000000000000000000000000000000', 'Person address should not be address(0) - incorrectly deployed');
        // 4.2 Save Person instance
        personInstance = deployedInstance.contract;
        // 5. Call addPerson()-function on root contract - transaction function!
        return rootInstance.addPerson(personInstance.address, { from: develop });
      })
      // 6.1 Call getAllPerson()-function on root contract
      .then(() => rootInstance.getAllPersons.call({ from: develop }))
      .then((result) => {
        console.log('allPersons', result);
        // 6.2 Check if array length is 1 - only one Person has been added
        assert.equal(result.length, 1, 'Person should be added to array');
        // 6.3 Check if value in array is correct
        assert.equal(result[0], personInstance.address, 'Correct address should be added to the array');
        // 7. Call getPersonByAddress()
        return rootInstance.getPersonByAddress.call(result[0], { from: develop });
      })
      .then((result) => {
        console.log('getPersonByAddress', result);
        // 7.1 Check if values are correct
        assert.equal(result[0], personInstance.address, 'Person address should be correct');
        assert.equal(web3.utils.hexToUtf8(result[1]), 'John Doe', 'Person name should be correct');
        assert.equal(web3.utils.hexToUtf8(result[2]), 'Main Street', 'Person street should be correct');
        assert.equal(result[3], 1, 'Person street number should be correct');
        assert.equal(web3.utils.hexToUtf8(result[4]), '1234-56', 'Person postal code should be correct');
        assert.equal(web3.utils.hexToUtf8(result[5]), 'New York', 'Person city should be correct');
        assert.equal(web3.utils.hexToUtf8(result[6]), 'United States', 'Person country should be correct');
        assert.equal(web3.utils.hexToUtf8(result[7]), '+12-34-5678-90', 'Person phone number should be correct');
        return rootInstance.getPersonAddressesAndNames.call({ from: develop });
      })
      .then((result) => {
        console.log('getPersonAddressesAndNames', result);
        // 7. Check Person array, if filled and correct value
        assert.equal(result[0].length, 1, 'Person should be added to array');
        assert.equal(result[0][0], personInstance.address, 'Person address should be correct value');
        // 8. Check names array, if filled and correct value
        assert.equal(result[1].length, 1, 'Person should be added to array');
        assert.equal(web3.utils.hexToUtf8(result[1][0]), 'John Doe', 'Person name should be correct value');
      })
      .catch(error => console.log(error)));
});

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Comments:12 (6 by maintainers)

github_iconTop GitHub Comments

1reaction
arnoudbeverscommented, May 8, 2018

@cgewecke

Is it ok if we close this issue since it’s specific to an older Geth version?

Yes, this is fine. I will try to check with Quorum when support for newer versions is coming.

Just leaving a note here about geth dev since that wasn’t clear. You can run a geth test client locally with very little setup by…

Thank you! I will keep this in mind, will be really useful in my development.

Thanks for your help!

0reactions
cgeweckecommented, May 8, 2018

@arnoudbevers Just leaving a note here about geth dev since that wasn’t clear. You can run a geth test client locally with very little setup by:

$ docker pull ethereum/client-go:latest  #`latest` is a version. See hub.docker for more.

$ docker run -it -p 8545:8545 \
                 -p 30303:30303 \
                 ethereum/client-go:latest \
                 --rpc --rpcaddr "0.0.0.0" \ 
                 --dev --dev.period 2

It comes with a single funded unlocked account. It’s slower than ganache but can be quite helpful for debugging when you are getting different outcomes on different clients.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Function not working on Truffle, but works on Remix
I have a function, purchaseItem , this function sets the items[_id].sold = true. pragma solidity >=0.4.22 <0.9.0; contract TradeCoin { uint ...
Read more >
Truffle doesn't compile but remix does - Stack Overflow
It throws a parse error: expected primary expression when the call function is called. ethereum · solidity · smartcontracts · truffle · ganache....
Read more >
ConsenSys/truffle - Gitter
When I'm debugging a transaction with the debug command, is there a way to have it dump out the contract storage variables?
Read more >
Solidity Documentation - Read the Docs
Solidity is an object-oriented, high-level language for implementing smart contracts. Smart contracts are programs.
Read more >
Running out of gas error when trying to deploy my solidity ...
In truffle I turned on the optimizer with 200 runs which then allowed me to deploy your contract and library to ganache-cli. truffle-config.js....
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found