Exercises: small extensions to Greeter#

← Back to Week 4: Track exposure

Short and optional beyond the first one, same spirit as the AI track's exercises. There's no answer key to compare against; if it does what the task describes, you're done. Do these on a copy of ../project/contracts/Greeter.vy, or directly on it if you don't mind redeploying (redeploying costs nothing but a little testnet gas and a couple of minutes).

1. Count how many times the greeting has changed#

Add a state variable, change_count: public(uint256), and increment it inside set_greeting every time it's called (self.change_count += 1). Vyper's uint256 arithmetic reverts automatically on overflow, the same guarantee as everywhere else in this language, though realistically you'd need to call this function an astronomical number of times to ever hit it. Recompile (ape compile), redeploy (you'll get a brand-new address, since this is different bytecode than before), and confirm from a Python script that greeter.functions.change_count().call() returns 0 right after deploy, then 1 after your first set_greeting call.

2. Add a way to reset to the original greeting#

Store the constructor's initial value in a second state variable (for example, original_greeting: public(String[280]), set alongside self.greeting inside __init__) when the contract is deployed, and add a reset_greeting() function (@external, no @view, since it changes state) that sets self.greeting back to that stored original value. Call set_greeting a couple of times to change it, then call reset_greeting and confirm, from Python, that it's back to the original.

3. Notice what changed, and what didn't, in your Python script#

After doing either exercise above, look at how little of interact.py you actually had to touch to call your new function: the connection setup, the account loading, the transaction-building shape, all of it stayed the same. Only the function name being called changed. That's the ABI doing its job: once web3.py has an accurate ABI for whatever the contract currently looks like, calling any of its functions follows the exact same pattern, no matter what the function actually does underneath, and no matter which smart contract language produced that ABI in the first place.