0
function mint(bytes32 hash) external {
        require(!_hasMinted[msg.sender]);
        require(totalSupply() + premineRemaining < 500);
        require(hash == sha256(abi.encodePacked(msg.sender, "emperor")));
        /* mint logic */
}
4
  • Could you clarify what you mean by "the hash is missing" ?
    – hroussille
    Nov 2 '21 at 10:27
  • We need to know what abi.encodePacked(msg.sender, "emperor") does.
    – TimmyG43
    Nov 2 '21 at 19:28
  • "The smart contract code is the same for everybody, but the hash you need is different for each person. What you said makes it sound like you're missing the part that's different for everybody. 🙂" This is the clue but I am not a developer at all Nov 2 '21 at 20:31
  • Here is the full contract etherscan.io/address/… Nov 2 '21 at 20:33
1

This contract is basically a "challenge".

You need to provide a hash that matches :

sha256(abi.encodePacked(msg.sender, "emperor"))

abi.encodePacked will just transform your data to bytes and pack them :

with a msg.sender (address) equal to : 0x5B38Da6a701c568545dCfcB03FcB875f56beddC4 and the string "emperor".

This would produce an array of bytes (aka bytes1) containing the following :

[5b, 38, da, 6a, 70, 1c, 56, 85, 45, dc, fc, b0, 3f, cb, 87, 5f, 56, be, dd, c4, 65, 6d, 70, 65, 72, 6f, 72]

Where : [5b, 38, da, 6a, 70, 1c, 56, 85, 45, dc, fc, b0, 3f, cb, 87, 5f, 56, be, dd, c4] is the address. And : [65, 6d, 70, 65, 72, 6f, 72] is the string "emperor" in hexadecimal. You can check it here.

This bytes buffer is then fed to the sha256 function, producing a hash.


From solidity, it's as easy as calling the mint function with : sha256(abi.encodePacked(address(this), "emperor")) as an argument.

ex (For the example, the mint function is replaced by the challenge function):

pragma solidity >0.5.0 <0.9.0;


contract MyContract {
    
     function challenge(bytes32 hash) external view {
         require(hash == sha256(abi.encodePacked(msg.sender, "emperor")));   
     }
     
     function challenger() public view {
         this.challenge(sha256(abi.encodePacked(address(this), "emperor")));
     }
}

The function challenge matches your challenge contract conditions. I made it external because from your example you will have to issue an external call if you do it from solidity.

Calling the challenger function works, as hash == sha256(abi.encodePacked(msg.sender, "emperor")) is obviously true inside the challenge function.


From JavaScript using ethers for the encoding (and calling the example contract just above) :

const hash = ethers.utils.soliditySha256(["address", "string"] [accounts[0], "emperor"]);
await myContractInstace.challenge(hash, { from: accounts[0] });

EDIT : I am giving you another example that you can use both locally to test / understand and to interact with the mint function on the real contract.

// SPDX-License-Identifier: GPL-3.0

pragma solidity >=0.8.0 <0.9.0;

contract Book {
    function mint(bytes32 hash) external view {
        require(hash == sha256(abi.encodePacked(msg.sender, "emperor")), "Invalid hash");
    }
}

contract Example {
    
    // This variable will hold the address of your challenge contract
    address _bookContract;
    
    // For your example: pass the address 0xE31171381081ADd2684b9F9bA4e2B30cE9A7be0a
    // to the constructor when you are ready to interact with the real challenge contract.
    // Alternatively, you can set _bookContract directly.
    constructor(address bookContractAddress) {
        _bookContract = bookContractAddress;  
    }
    
    // This function will generate a hash matching what the mint function is
    // expecting.
    // Then it will issue a call to the contract address contained in the
    // _bookContract address. Targetting a function with the following encodeWithSignature
    // mint(bytes32) which mathes mint(bytes32 hash) from the Book contract.
    function callMint() public returns (bool){
        bytes32 hash = sha256(abi.encodePacked(address(this), "emperor"));
        (bool success, bytes memory result) = _bookContract.call(abi.encodeWithSignature('mint(bytes32)', hash));
        return success;
    }
    
}

Try to use it on Remix it's easy to use if you are not yet comfortable with all the available tools.

You can simply copy / paste this in Remix and to test locally :

  • Deploy the Book contract
  • Copy the deployed Book contract address
  • Deploy the Example contract giving the Book contract address as a parameter of the constructor.
  • Call the callMint function on the Example contract. (This will mint on the Book contract under the Example contract address)

If you are ready to interact with the real Book contract (the one from your challenge currently at address : 0xE31171381081ADd2684b9F9bA4e2B30cE9A7be0a) then just deploy the Example contract on the same network as your challenge and give the address 0xE31171381081ADd2684b9F9bA4e2B30cE9A7be0a as a constructor parameter.

Calling the callMint function will successfully mint on the real Book contract. Play around with it and try to understand what is happening, it's a challenge it's not necessarily meant to be easy for the challengers !

4
  • Hi, thanks a lot for this, I really appreciate your help. Yes, it was a challenge but even with your great explanation, I need a bit more guidance. As to how I can mint from this contract or which part and where do I need to run your code? I am so sorry but I am a complete beginner here. Nov 2 '21 at 22:59
  • How do you want to use it ? From Solidity or JavaScript ?
    – hroussille
    Nov 3 '21 at 7:50
  • Probably from solidity, I would have thought. Nov 3 '21 at 9:21
  • Thanks for all your help. I will play around with it. I know what to do in terms of "I need to insert the right "hash (bytes32)" into the "write contract" "mint" part in etherscan. However, I tried the combinations above and it gives me a 3ETH gas fee and according to the challenge if I get it right it should be around 0.3. I really appreciate your help and I definitely learned a lot from you. Thanks, A Nov 3 '21 at 12:04

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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