Hey @Samm,
Once again, apologies for the delay in giving you some answers on this.
It doesn’t have to be. Our example is based on a contractual relationship between a government and a bank. The idea is that the government needs to collect some kind of tax on each banking transaction that is a transfer. To keep things simple in our example, the government is collecting a fixed amount (1 wei) on each transfer. This amount will be automatically transferred from the Bank contract balance to the Government contract balance on each successfully executed transfer transaction. For record keeping purposes, the relevant data for each transfer is also sent from Bank to Government and stored in the government’s transaction log (an array).
Instead of being a tax, another way to interpret this payment could be as payment for some kind of record keeping service i.e. the Bank contract pays the Government contract for storing all of its transaction data.
However we interpret this payment from one contract to the other, it demonstrates (albeit in an overly simplistic way) how we can program automatic interactions between individual contracts for the purposes of both data and value transfer. Hopefully, this example shows the potential for these sorts of programmed interactions to be applied to many different use cases.
But returning to your original question… we could equally exclude the transfer of value from the addTransaction function, if we want it to provide a purely record keeping role at no extra charge (except of course the cost of gas consumption, which in any case is paid to the miners and not to the external contract).
If no value is transferred, then the addTransaction function should not be marked payable
, in both Government and the Government interface in Bank.
You should be deploying your Government contract before deploying Bank. If you redeploy Government at any stage, then it will have a different contract address, and so you also need to change the Government address assigned to your governmentInstance in this line of your code in Bank:
If you forgot to replace the previous address of your external contract for the new one, then this will have caused the transaction to revert when you called the transfer function, and will have given you the error message you got. The problem is that the error message you got was just a default one, and so that’s why it wasn’t helpful in pinpointing the error. Your error most probably wasn’t anything to do with the function not being marked payable, or the value exceeding the current balance.
This is easily done, and catches most of us out the first time we make that mistake
Adding an error message to your require() statements, is always a good idea, because if the revert is caused by one of them, the message you added will appear as part of the error message you get in the Remix console. If one of your own error messages doesn’t appear, you know that the transaction reverted because of something else.
Let me know if you think that was the cause of the problem or not. But I’m glad to see that you got it to work in the end