Here is an article on how to pass arguments to a contract file in Solidity, along with an example of what can go wrong when testing a contract.
Passing arguments to a contract file in Solidity
When writing smart contracts in Solidity, one of the common tasks is passing arguments from the application that deployed the contract. This can be done using function calls on the contract instance or by modifying the contract code itself.
In this article, we will discuss how to pass arguments to the contract file and troubleshoot when testing the contract returns 0.
Passing arguments in a deployed contract
First, let’s assume that the deployed contract is HelioToken
with an emitted event called TotalSupply
. To call this function from another contract, you need to create an instance of HelioToken. However, it looks like you are missing some code, so I will provide a basic example.
// 2_deploy_contract.js
const HelioToken = artifacts.require("HelioToken");
module.exports = function (deployer) {
const intialSupply = 1000000;
deployer.deploy(HelioToken, intialSupply);
// Now you can fire the TotalSupply event
HelioToken.totalSupply().then(totalSupply => {
console.log("Total Supply: %s", totalSupply);
});
};
Testing the Contract with Arguments Passed
Now that we have deployed our contract and passed an argument, let’s test it using the built-in Truffle testing framework. We will create two contracts: HelioToken
and ContractWithPassedArgument
.
// HelioToken.sol
pragma solidity ^0.6.0;
contract HelioToken {
mapping(address => uint256) public balances;
function totalSupply() external view returns (uint256) {
return balances[msg.sender];
}
function addBalance(uint256 amount, address who) public {
balances[who] += amount;
}
}
// ContractWithPassedArgument.sol
pragma solidity ^0.6.0;
ContractWithPassedArgument {
uint256 public passedAmount = 0;
mapping(address => uint256) public passedBalances;
function addBalance(uint256 amount, address who) public {
passedBalances[who] += amount;
}
function totalSupply() external view returns (uint256) {
return passedBalances[msg.sender];
}
}
Now let’s test our contracts.
// 1_deploy_contract.js
const HelioToken = artifacts.require("HelioToken"");
ContractWithPassedArgument calldata contractWithPassedArgument;
module.exports = function (deployer) {
const intialSupply = 1000000;
deployer.deploy(HelioToken, intialSupply);
// Now we can test our contract
contractWithPassedArgument.addBalance(intialSupply, msg.sender);
}
In the above example, after running 1_deploy_contract.js
, two contracts will be deployed: HelioToken
and ContractWithPassedArgument
. Then a specified amount will be added HelioToken to a ContractWithPassedArgument
instance.
Troubleshooting argument passing
Now that we have tested our contract, let’s troubleshoot why it returns 0 when tested. There are a few reasons:
- Missing implementation code: If the deployed contracts do not have the
totalSupply()
andaddBalance()
functions defined correctly, or if they are not accessible from another contract, passing arguments will not work.
- Incorrect event handling: Make sure you have raised the correct events on the HelioToken instance. In this example, we have passed an argument to
HelioToken.totalSupply()
, but in fact it is an external call.
To resolve these issues:
- Check the deployed contracts for any errors or inconsistencies.
- Check that you are calling the correct functions and passing arguments correctly.
- Make sure both contracts are accessible from another contract, as in our example.