diff --git a/packages/contract/README.md b/packages/contract/README.md index 0fc08901fa6..a8e60962f7b 100644 --- a/packages/contract/README.md +++ b/packages/contract/README.md @@ -240,11 +240,11 @@ contract MyContract { } ``` -From Javascript's point of view, this contract has three functions: `setValue`, `getValue` and `value`. This is because `value` is public and automatically creates a getter function for it. +From JavaScript's point of view, this contract has three functions: `setValue`, `getValue` and `value`. This is because `value` is public and automatically creates a getter function for it. #### Making a transaction via a contract function -When we call `setValue()`, this creates a transaction. From Javascript: +When we call `setValue()`, this creates a transaction. From JavaScript: ```javascript const result = instance.setValue(5); @@ -310,6 +310,80 @@ const val = instance.getValue(); // since the contract returns that value. ``` +#### Overloaded functions + +Solidity supports a contract having multiple functions with the same name as long as the +function argument types differ. And so you may find yourself in the situation of having a +Truffle contract object with this property. +You can invoke these "overloaded" functions just like you would a normal contract function. Truffle contract instances +actually wrap web3's contract abstraction (`web3.eth.Contract`) and when you call an overloaded function, it +uses the same function resolution that web3 uses. However, we must give a warning that this overloaded function +resolution is often imprecise and can resolve to the wrong function when you call it. + +Consider the following contrived code sample: + +```solidity +contract MyContract { + uint256 public myUint; + string public myString; + string public myOtherString; + + function setValues(uint256 val, string str) { + myUint = val; + myString = str + } + + function setValues(string str, string otherStr) { + myString = str; + myOtherString = otherStr; + } + + function setValues(uint256 val, string str, string otherStr) { + myUint = val; + myString = str; + myOtherString = otherStr; + } +} +``` + +This Solidity contract contains three functions named `setValues`, each taking a different type of input. In your JavaScript you +might do something like the following: + +```javascript +await instance.setValue( + 666, + "this is not string cheese", + "this is string cheese" +); +``` + +As mentioned above, Truffle contract wraps web3 `Contract` objects and uses web3's overloaded function resolution. +To resolve these functions, web3's strategy is to look at the number of arguments that the function was invoked with and try +one that takes that many arguments. This works for some cases but is not ideal in that it +can invoke the incorrect function. Take, for example, the case where we do something like the following: + +```javascript +await instance.setValue("this is not string cheese", "this is string cheese"); +``` + +We know that in our contract there are two functions named `setValues` that take +two arguments. In the above case, we cannot be sure whether web3's resolution will resolve to the first or second +function. The more precise way to reference functions like this is to use +the `methods` property on the contract instance. The following is an example of how you +access these methods: + +```javascript +await instance.methods["setValue(string,string)"]( + "this is not string cheese", + "this is string cheese" +); +``` + +The `methods` property is an object whose keys are strings that correspond to the contract function's names +and signatures with no spaces. The values are the functions themselves. You can inspect the +`methods` property to see the key names in this object and match the function signature. +We recommend using this method of calling overloaded functions since it will unambiguously resolve to the correct function. + #### Processing transaction results When you make a transaction, you're given a `result` object that gives you a wealth of information about the transaction. You're given the transaction hash (`result.tx`), the decoded events (also known as logs; `result.logs`), and a transaction receipt (`result.receipt`). In the below example, you'll receive the `ValueSet()` event because you triggered the event using the `setValue()` function: