Web3.js: Expose a function that will enable encoding of a solidity function call

Created on 29 May 2015  Â·  11Comments  Â·  Source: ChainSafe/web3.js

Many apps, like the multisig wallet and the democracy DAO, allows the users to ask the contract to execute a custom solidity call to another contract. This is a very powerful feature that allows, for example the user to have a second authentication for any transaction in the wallet contract; or allows the DAO to own and maintain names in the registrar, or the DAO to own custom coins.

This is usually done with the solidity .call feature that will have this parameters:

someAddress.call.value(_amount)(_data);

Where someAddress is an address to another contract, _amount is amount of ether in wei and _data is a custom abi encode of function that the user wants to call. The issue is that there is no user exposed function that will help build that _data field.

This is already half baked into web3.js in the Solidity Functions Prototype:

options.data = '0x' + this.signature() + coder.encodeParams(this._inputTypes, args);

I propose that we expose a function in web3 that would have the following parameters:

web3.encodeSolidityFunctionCall('myFunctionName',
     [{
       name: '_parameter1',
       type: 'address',
       value: '0x2345678..'
    },{
       name: '_parameter2',
       type: 'uint',
       value: '901'
    }])
    ...

This would return an ABI encoded string that could be passed as data on to any contracts methods, which use this data in calls to other contracts.

enhancement

Most helpful comment

All 11 comments

+1

Should be fairly easy to implement as every piece is already there.

I think that this problem should be solved differently. You can 'include' interface of the contract that you want to call in your solidity contract. Example:

// included solidity interface 
contract IncludedContract {
  function someMethod(bytes32 name) {}
}

// contract
contract MyContract {
  function MyContract(address a, bytes32 name) {
    IncludedContract(a).someMethod(name)
  }
}

Yes but this only works for specific contracts. Some contracts like the DAO and multisig wallet are built to be able to handle any transaction to any contract including those that have not been written yet.

Sent from my iPhone

On May 30, 2015, at 03:13, Marek Kotewicz [email protected] wrote:

I think that this problem should be solved differently. You can 'include' interface of the contract that you want to call in your solidity contract. Example:

// included solidity interface
contract IncludedContract {
function someMethod(bytes32 name) {}
}

// contract
contract MyContract {
function MyContract(address a, bytes32 name) {
IncludedContract(a).someMethod(name)
}
}
—
Reply to this email directly or view it on GitHub.

Thats actually a very valid use case. The same is valid for gavins wallet contract, which could be used to sign other contracts or execute contract functions, so the above proposal makes fully sense e.g.:

var callData = web3.soldity.encodeFunctionCall('myFunctionName',
     [{
       name: '_parameter1',
       type: 'address',
       value: '0x2345678..'
    },{
       name: '_parameter2',
       type: 'uint',
       value: '901'
    }]);


mycontractInstance.myMethod(address, value, callData, {from: ..., gas: 123456});

+1. Would love this support.

I don't think it is a good idea to mix types and values. My proposal would be:

web3.eth.function({
name: 'myFunctionName',
inputs: [{name: '_parameter1, type: 'uint256'}, {name: '_parameter2', type: 'uint16'}]
}).encode('0x123', 234)

I.e. take the part of the ABI that belongs to the specific function, call web3.eth.function on it and then call encode with the respective parameters. Note that the function part of the ABI contains some other keys which are not needed here but can be supplied if wanted.

I do not know if this is implemented already.

I've implemented this functionality by modifying index.js file in web3-js npm and added the following line -

Web3.SolidityCoder = require('./lib/solidity/coder');

I'm able to use the encoder and decoder after web3 is injected as below -

web3.SolidityCoder.encodeParams([types array], [values array]) web3.SolidityCoder.decodeParams([types array], encodedData)

Let me know if this would be a recommended approach to add the encoder and decoder to web3. I understand this would be very beneficial for the community, but not sure if my approach is acceptable. Any reviews on this would be appreciated.

Thanks,
Sridhar

Hasn't this been resolved with the addition of getData()? https://github.com/ethereum/wiki/wiki/JavaScript-API#contract-methods

@sridhar87

I somehow missed that method available on contract. Thanks for your response and for pointing out the new method is available to encode parameters. I think we can close this issue in that case.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

praveengupta0895 picture praveengupta0895  Â·  3Comments

baxy picture baxy  Â·  3Comments

nivida picture nivida  Â·  3Comments

zamoore picture zamoore  Â·  3Comments

sundbry picture sundbry  Â·  3Comments