Ethereum: Issue with tx.origin
and msg.sender
in Foundry testing
As part of my ongoing research on smart contracts, I have been working on a test case for an Ethernaut Level 4 (phone) contract using Foundry. However, an unexpected issue has arisen that requires troubleshooting.
Issue:
During testing, I noticed that the tx.origin and msg.sender fields in my contract were not working as expected. In particular, these fields seemed to return different values than I expected.
Topic:
After looking at the contract code and understanding how it works with the blockchain, I realized there are two main issues here:
tx.origin
: The tx.origin field contains the address of the account that initiated the transaction (i.e. the sender). However, when using the Foundry testing framework, this value is not always accurate.
msg.sender
: Themsg.sender
field contains the address of the account that called the contract function (i.e. the recipient). This value may be different fromtx.origin
, especially if the transaction was sent via a different account.
Solution:
To solve this problem, I made several changes to my test code:
- Use the
sender
attribute instead oforigin
: In the Foundry test framework,
sender
seems to be the correct attribute to use in conjunction with the event sender.
- Use
contractAddress
as a fallback: Iftx.origin
andmsg.sender
are still different, I can fallback to the contract address (“contractAddress”) as an alternative.
Here is an updated code snippet demonstrating these changes:
const { Ether } = require("Ether");
// Test case for phone contract
asynchronous function testTelephone() {
// Initialize contract and account
const phoneContract = new Ether.Contract(
"
PhoneContract ABI,
ethers.Wallet.fromPrivateKey(
"YOUR_PRIVATE_KEY", // Replace it with your private key
)
);
//Create an event object
Constants tx = {
Sender: ethers.Wallet.fromPrivateKey("YOUR_PRIVATE_KEY"),
Recipient: phoneContract.address, // The correct address for this contract
Value: ethers.utils.parseEther("1"), // Set the event value
gasPrice: 20n, // Set gas price (optional)
gasLimit: 2000, // Set maximum gas limit
data: "0x", // Sets the event data (empty in this case)
};
// Run the event
const result = wait for phoneContract.sendTransaction(tx);
console.log(result);
}
// Run the test function
testPhone();
Conclusion:
Applying these changes helped me resolve the issue with tx.origin and msg.sender in my phone contract test case. Now that the values are accurate, I can continue testing and analyzing.
If you have similar issues or have any questions about this solution, feel free to ask!