4

I have a simple Solidity function as below:

function testKeccak(uint8[] buffer) public pure returns (bytes32) {
    return keccak256(abi.encodePacked(buffer));
}

Testing the keccak256 hash using library from: https://github.com/modulexcite/CEX

But they yield different results.

var In = "54686973206973206A75737420612074657374"; // Assume this is a byte[], otherwise the code won't compile
Web3 w = new Web3("http://localhost:8545/");
Contract c = w.Eth.GetContract("My ABI", " My Contract Address");
var r = c.GetFunction("testKeccak").CallAsync<byte[]>(In).Result;

//Expected = 68D0D86DF8DCA7ABDAD4DA5986F7E33FA7637EE85775A64AE965E10E3841923E
//Received = FC3B317A9FB7A02E6FF7A1839EEA04A21C30D9CD15B3414FA7431F09DEEC9D9D

May I know if there is any C# library out there which can get the correct Keccak256 hash when compared to Solidity?

eth
  • 85,679
  • 53
  • 285
  • 406
s k
  • 886
  • 1
  • 10
  • 22
  • The problem is probably what is being passed to the C# library. https://ethereum.stackexchange.com/questions/2632/how-does-soliditys-sha3-keccak256-hash-uints is an example in JavaScript that might help – eth Oct 22 '18 at 05:06

3 Answers3

6

Tested:

using System;
using System.Linq;
using Org.BouncyCastle.Crypto.Digests;

namespace myNamespace { public static class TransactionTool { public static string GetTransactionHash(string rawTransaction) { var offset = rawTransaction.StartsWith("0x") ? 2 : 0;

        var txByte = Enumerable.Range(offset, rawTransaction.Length - offset)
                         .Where(x =&gt; x % 2 == 0)
                         .Select(x =&gt; Convert.ToByte(rawTransaction.Substring(x, 2), 16))
                         .ToArray();

        //Note: Not intended for intensive use so we create a new Digest.
        //if digest reuse, prevent concurrent access + call Reset before BlockUpdate
        var digest = new KeccakDigest(256);

        digest.BlockUpdate(txByte, 0, txByte.Length);
        var calculatedHash = new byte[digest.GetByteLength()];
        digest.DoFinal(calculatedHash, 0);

        var transactionHash = BitConverter.ToString(calculatedHash, 0, 32).Replace(&quot;-&quot;, &quot;&quot;).ToLower();

        return transactionHash;
    }
}

}

guillaume
  • 73
  • 1
  • 4
0

I found that this C# lib implement keccak256

https://github.com/multiformats/cs-multihash

Tony Dang
  • 2,151
  • 2
  • 9
  • 16
0

It is likely that there is a padding version mismatch. You can use https://www.nuget.org/packages/SHA3/1.0.0-rc to choose which padding version you'd like, the official SHA3 is now the default. Setting UseKeccakPadding to true enables original Keccak padding.

joe
  • 111
  • 2