Nethereum

C# 如何計算 Keccak256 以匹配 Solidity?

  • January 22, 2021

我有一個簡單的 Solidity 函式,如下所示:

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

使用以下庫中的庫測試 keccak256 雜湊:https ://github.com/modulexcite/CEX

但它們會產生不同的結果。

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

我可以知道是否有任何 C# 庫與 Solidity 相比可以獲得正確的 Keccak256 雜湊?

測試:

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 => x % 2 == 0)
                            .Select(x => 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("-", "").ToLower();

           return transactionHash;
       }
   }
}

我發現這個 C# lib 實現了 keccak256

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

引用自:https://ethereum.stackexchange.com/questions/60915