I was solving homework1.hs of week 3 of the third cohort and I think there is something wrong with the off-chain code of the solution given the validator. Namely the following, the off-chain part does not specify the end of the txInfoValidRange for the grab endpoint.

I think the current implementation sets this range to [currentTime, Inf]. For the grab of a beneficiary 2 that can grab after the deadline this poses no problem. This since the txInfoRange is contained in the range [deadline, Inf]. But if beneficiary 1 tries to grab before the endpoint the txInfoRange is not contained in the [0, Deadline] since 0 is in general not contained in txInfoRange. This makes that the current proposed solution of the validator can not construct transactions for beneficiary 1 before the deadline?

This can be solved in two ways,

  1. Change the off-chain code to make transactions such that the grab for beneficiary 1 will not fail. How can we set this valid range to before the deadline?
  2. Change the validator (I can not see how one could make this work if we permit the txInfoRange to be indefinite. This because it would also permit beneficiary 1 to collect the vesting funds after the deadline, what we want to avoid.)

I had a similar solution to the solution provided by the IOG acadamy (1) but both of course use the same off-chain code and thus don't work. For example if do the following enter image description here

Where wallet 1 is beneficiary 1 that can claim after the deadline of slot 10 (POSIXTime = 1596059101000) and wallet 2 with PaymentPubKey 98c77c40ccc536e0d433874dae97d4a0787b10b3bca0dc2e1bdc7be0a544f0ac is beneficiary 2 which can claim the funds before the deadline of slot 10. This emulation in the above screenshot works, wallet 1 can grab the funds. But if we set it up to test if wallet 2 can grab by the following simulation it fails with the following error at slot 6

Add slot 3
Contract instance for W872cb83: (ContractLog (RawJson "made a gift of 50000000 lovelace to 98c77c40ccc536e0d433874dae97d4a0787b10b3bca0dc2e1bdc7be0a544f0ac with deadline POSIXTime {getPOSIXTime = 1596059101000}"))
Add slot 4
Add slot 5
Add slot 6
Contract instance for W7ce812d: (ReceiveEndpointCall (EndpointDescription { getEndpointDescription: "grab" }) (RawJson "{\"contents\":[{\"getEndpointDescription\":\"grab\"},{\"unEndpointValue\":[]}],\"tag\":\"ExposeEndpointResp\"}"))
Contract instance for W7ce812d: (ContractLog (RawJson "found 0 gift(s) to grab"))
Add slot 7

Is my assessment of the off-chain code correct? How can we solve this?

  • Someone on the IOG discord channel mentioned that this problem arose due to the PubKeyHashes of the wallets being different in this cabal build. I'll do some testing and logging of the PubKeyHashes to check this out.
    – Fermat
    Feb 3, 2022 at 9:47

1 Answer 1


I found the answer myself. Turns out it has to do with the use of the wrong PubKeyHash in the endpoints. I followed the lecture where Lars used mockWalletPaymentPubKey $ knownWallet 1 to find the PubKey. I used that instead of the hash of this. To get the hash one has to observe the type signature of mockWalletPaymentPubKey $ knownWallet 1 :: PaymentPubKey, I saw in the haddock files that this is just some type wrapper around PubKey, to undo this wrapper simply use its constructor unPaymentPubKey :: PaymentPubKey -> PubKey . Now to hash this PubKey one can use pubKeyHash :: PubKey -> PubKeyHash . So in the end we can easily generate these wallets pubKeyHash's via the following

pubKeyHash $ unPaymentPubKey $ mockWalletPaymentPubKey $ knownWallet 1


pubKeyHash $ unPaymentPubKey $ mockWalletPaymentPubKey $ knownWallet 2

Hopes this helps anyone. In conclusion there is nothing wrong with the off-chain code, it was just weird that it validated for grabbing if the deadline past which put me on the wrong track. If anyone knows why this happened, please enlighten me :)

  • 2
    You can also use mockWalletPaymentPubKeyHash $ knownWallet 1, which yields the same result but is shorter
    – rkstgr
    Feb 3, 2022 at 11:27

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.