Skip to content

Commit

Permalink
Update contract class to not mutate options object (#5394)
Browse files Browse the repository at this point in the history
* Update contract class to not mutate options object

* Add .send test for options mutation test

* Update CHANGELOG

* Remove errounous import
  • Loading branch information
spacesailor24 committed Aug 30, 2022
1 parent 0d38050 commit 0541faa
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 8 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Expand Up @@ -593,3 +593,4 @@ Released with 1.0.0-beta.37 code base.
### Fixed
- Browser builds support polyfills (#5031) (#5053) (#4659) (#4767)
- Start incrementing jsonrpc.id from random number (#5327)
- `web3-eth-contract`'s `call` and `send` methods no longer mutate `options` argument (#5394)
17 changes: 9 additions & 8 deletions packages/web3-eth-contract/src/index.js
Expand Up @@ -379,19 +379,20 @@ Contract.prototype._checkListener = function(type, event){
* @return {Object} the options with gaps filled by defaults
*/
Contract.prototype._getOrSetDefaultOptions = function getOrSetDefaultOptions(options) {
var gasPrice = options.gasPrice ? String(options.gasPrice): null;
var from = options.from ? utils.toChecksumAddress(formatters.inputAddressFormatter(options.from)) : null;
var _options = { ...options };
var gasPrice = _options.gasPrice ? String(_options.gasPrice): null;
var from = _options.from ? utils.toChecksumAddress(formatters.inputAddressFormatter(_options.from)) : null;

options.data = options.data || this.options.data;
_options.data = _options.data || this.options.data;

options.from = from || this.options.from;
options.gasPrice = gasPrice || this.options.gasPrice;
options.gas = options.gas || options.gasLimit || this.options.gas;
_options.from = from || this.options.from;
_options.gasPrice = gasPrice || this.options.gasPrice;
_options.gas = _options.gas || _options.gasLimit || this.options.gas;

// TODO replace with only gasLimit?
delete options.gasLimit;
delete _options.gasLimit;

return options;
return _options;
};


Expand Down
71 changes: 71 additions & 0 deletions test/contract.js
Expand Up @@ -3152,6 +3152,77 @@ var runTests = function(contractFactory) {
describe('typical usage', function() {
runTests(getEthContractInstance);

it('should not mutate options object - call', function (done) {
var provider = new FakeHttpProvider();

provider.injectResult('0x0000000000000000000000000000000000000000000000000000000000000032');

var eth = new Eth(provider);
var contract = new eth.Contract(abi, address);
var options = { from: address };
var expectedOptions = { ...options };

contract.methods.balance(address).call(options)
.then(function () {
assert.deepEqual(options, expectedOptions);
done();
});
});

it('should not mutate options object - send', function (done) {
var provider = new FakeHttpProvider();

provider.injectResult('0x1234000000000000000000000000000000000000000000000000000000056789');
provider.injectResult({
contractAddress: null,
cumulativeGasUsed: '0xa',
transactionIndex: '0x3',
transactionHash: '0x1234',
blockNumber: '0xa',
blockHash: '0x1234',
gasUsed: '0x0',
logs: [{
address: address,
topics: [
sha3('Unchanged(uint256,address,uint256)'),
'0x0000000000000000000000000000000000000000000000000000000000000002',
'0x000000000000000000000000'+ addressLowercase.replace('0x','')
],
blockNumber: '0xa',
transactionHash: '0x1234',
transactionIndex: '0x0',
blockHash: '0x1345',
logIndex: '0x4',
data: '0x0000000000000000000000000000000000000000000000000000000000000005'
},{
address: address,
topics: [
sha3('Changed(address,uint256,uint256,uint256)'),
'0x000000000000000000000000'+ addressLowercase.replace('0x',''),
'0x0000000000000000000000000000000000000000000000000000000000000001'
],
blockNumber: '0xa',
transactionHash: '0x1234',
transactionIndex: '0x0',
blockHash: '0x1345',
logIndex: '0x4',
data: '0x0000000000000000000000000000000000000000000000000000000000000001' +
'0000000000000000000000000000000000000000000000000000000000000008'
}]
});

var eth = new Eth(provider);
var contract = new eth.Contract(abi, address);
var options = { from: address, gasPrice: '21345678654321' };
var expectedOptions = { ...options };

contract.methods.mySend(address, 10).send(options)
.on('receipt', function () {
assert.deepEqual(options, expectedOptions);
done();
});
});

it('should update contract instance provider when assigned a provider to eth instance that contract instance came from', function () {
var provider1 = new FakeIpcProvider();
var provider2 = new FakeHttpProvider();
Expand Down

0 comments on commit 0541faa

Please sign in to comment.