solidity metamask – Setting a price for a payable function (Ethereum Pet Shop)

metamasksolidity

I'm following the Ethereum Pet Shop tutorial online, and everything works fine. However, to "adopt" a pet, the MetaMask transaction on my site is only requiring me to pay for the gas. I've taken a look at the Solidity docs and I think I'm supposed to make my function "payable", which I've tried, but actually setting a required price in wei to execute the contract is unclear to me.

Here's my Adoption.sol file:

pragma solidity ^0.4.17;

contract Adoption {
    address[16] public adopters;
    // Adopting a pet
    function adopt(uint petId) public payable returns (uint) {
        require(petId >= 0 && petId <= 15);

        adopters[petId] = msg.sender;

        return petId;
    }
    // Retrieving the adopters
    function getAdopters() public view returns (address[16]) {
        return adopters;
    }

}

And my TestAdoption.sol file:

pragma solidity ^0.4.17;

import "truffle/Assert.sol";
import "truffle/DeployedAddresses.sol";
import "../contracts/Adoption.sol";

contract TestAdoption {
    Adoption adoption = Adoption(DeployedAddresses.Adoption());

    //Testing the adopt() function
    function testUserCanAdoptPet() public {
      uint returnedId = adoption.adopt(8);
      uint expected = 8;
      Assert.equal(returnedId, expected, "Adoption of pet ID 8 should be recorded.");
    }

    // Testing retrieval of a single pet's owner
    function testGetAdopterAddressByPetId() public {
        // Expected owner is this contract
        address expected = this;
        address adopter = adoption.adopters(8);
        Assert.equal(adopter, expected, "Owner of pet ID 8 should be recorded.");
    }

    // Testing retrieval of all pet owners
    function testGetAdopterAddressByPetIdInArray() public {
        // Expected owner is this contract
        address expected = this;

        // Store adopters in memory rather than contract's storage
        address[16] memory adopters = adoption.getAdopters();

        Assert.equal(adopters[8], expected, "Owner of pet ID 8 should be recorded.");
    }

}

Can anyone point me in the right direction?

Best Answer

The MetaMask transaction prompt is opened by your JavaScript code not your Solidity code. If you want it to include a default value you will have to add that value in your JavaScript, by adding it as a value parameter to your call to adopt().

To enforce payment as a requirement for adoption, you will also need to add some code to your Solidity adopt() function to check msg.value and throw an error if it's lower than however much it's supposed to be. You may also want to add a read-only constant function to tell the user how much they have to pay, then call that from your JavaScript code to fetch the value that you will then set as the default that will be displayed by MetaMask.

Related Topic