3

I'm trying to do something that in theory is very simple: I want to pass a string like "hello" to a function and then compute the sha3/keccak256 hash. I think the problem is that if the parameter is a bytes32 (as it is now), the hash function will produce a different output.

How can I get the same hashes with these two methods inside a smart contract? In practice, how to get a return true in the following code?

function someFunction(bytes32 _string) returns(bool){
    bool result = false;
    bytes32 hashparameter = sha3(_string);
    bytes32 hashstring = sha3("hello");
    if(hashstring == hashparameter) {
        result = true;
    }

    return result;

}

How can I truncate the passed bytes32 so that it consider only the first 5 bytes for the sha3?

Thanks for your time, I hope you have the solution. If I'll find something, I'll update the question.

4

try this snipet

function bytes32ToString(bytes32 x) constant returns (string) {
    bytes memory bytesString = new bytes(32);
    uint charCount = 0;
    for (uint j = 0; j < 32; j++) {
        byte char = byte(bytes32(uint(x) * 2 ** (8 * j)));
        if (char != 0) {
            bytesString[charCount] = char;
            charCount++;
        }
    }
    bytes memory bytesStringTrimmed = new bytes(charCount);
    for (j = 0; j < charCount; j++) {
        bytesStringTrimmed[j] = bytesString[j];
    }
    return string(bytesStringTrimmed);
}

 function someFunction(bytes32 _string) returns(bool){
    bool result = false;
    bytes32 hashparameter = sha3(bytes32ToString(_string));
    bytes32 hashstring = sha3("hello");
    if(hashstring == hashparameter) {
        result = true;
    }

    return result;

}

the first function converts bytes32 to string then passes the result to hashing function. I've tried it gives true for "hello".

  • thank you very much! It's exactly what I was trying to write but I wasn't able to figure out 5th line of your snippet :) – gatb27 Jan 9 '17 at 20:28
0

How can I truncate the passed bytes32 so that it consider only the first 5 bytes for the sha3?

To truncate bytes32 to the first 5 bytes, cast it to bytes5:

bytes5 b5 = bytes5(bytes32value);

In the question contract, use:

keccak256(bytes5(_string));


The question isn't passing a string to keccak256/sha3, it's passing in bytes32. One could use a function to convert the bytes32 to string but it may turn out to not be needed and just use unnecessary gas.

For example, here are 3 options that are much cheaper for making someFunction return true. Choose 1 and replace the matching line in the problem contract:

  • function someFunction(string _string) returns(bool){
    Make the input be a string :)

  • bytes32 hashparameter = keccak256(bytes5(_string)); Make the length match the length of hello.

  • bytes32 hashstring = keccak256("hello\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"); Pad the string to 32 bytes.

But this question sounds like an XY problem:

The XY problem is asking about your attempted solution rather than your actual problem.

That is, you are trying to solve problem X, and you think solution Y would work, but instead of asking about X when you run into trouble, you ask about Y.

For example, where does the hardcoded "hello" come from or get stored in the contract? Wouldn't it also be a bytes32? If it isn't, then padding it to 32 bytes would be much cheaper than converting each bytes32 input to a string.

  • Thank @eth for the answer. This function is just an example to explain I needed a conversion from bytes32 to string, without the knowledge about how long is the string saved in a bytes32. So the "hello" is just an example to the conversion. I can actually use the string type for the function parameters, but in a specific case I need a conversion and so the first answer by badr bellaj was the one I was looking for :) – gatb27 Jan 25 '17 at 15:12
  • 1
    @gatb27 Thanks, so your actual problem was "conversion from bytes32 to string" which is basically the linked answer :) – eth Jan 25 '17 at 21:59
0
// Copyright 2014 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.

package crypto

import (
    "crypto/ecdsa"
    "crypto/elliptic"
    "crypto/rand"
    "encoding/hex"
    "errors"
    "io"
    "io/ioutil"
    "math/big"
    "os"

    "github.com/ethereum/go-ethereum/common"
    "github.com/ethereum/go-ethereum/crypto/sha3"
    "github.com/ethereum/go-ethereum/rlp"
)

var (
    secp256k1_N, _  = new(big.Int).SetString("fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141", 16)
    secp256k1_halfN = new(big.Int).Div(secp256k1_N, big.NewInt(2))
)

// Keccak256 calculates and returns the Keccak256 hash of the input data.
func Keccak256(data ...[]byte) []byte {
    d := sha3.NewKeccak256()
    for _, b := range data {
        d.Write(b)
    }
    return d.Sum(nil)
}

// Keccak256Hash calculates and returns the Keccak256 hash of the input data,
// converting it to an internal Hash data structure.
func Keccak256Hash(data ...[]byte) (h common.Hash) {
    d := sha3.NewKeccak256()
    for _, b := range data {
        d.Write(b)
    }
    d.Sum(h[:0])
    return h
}

// Keccak512 calculates and returns the Keccak512 hash of the input data.
func Keccak512(data ...[]byte) []byte {
    d := sha3.NewKeccak512()
    for _, b := range data {
        d.Write(b)
    }
    return d.Sum(nil)
}
  • It would be good to also add some explanation about how the code solves the problem described in the question. – Ajoy Bhatia May 23 '17 at 17:14

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.