go-ethereum keccak256 Multi-Value-Byte-Slice stimmt nicht mit solidity keccak256 überein

Ich habe einen Smart Contract mit folgender Funktion:

function testHash(
    address _sender, 
    uint8 _method, 
    uint256 _number, 
    uint256 _amount) 
    public 
    returns (bytes32) 
{
return keccak256(abi.encodePacked(_sender, _number, _method, _amount));    
}

Was, wenn die folgenden Werte gegeben sind, 0xa1d9e8788414eA9827f9639c4bd81bA8f3A29758, 0, 0, 0den folgenden Hash erzeugt0x65a0fc07391cb16f60c589836a72bdeaf2ab8bcb16c819126abba4408e069bcb

Ich habe den folgenden Golang-Code

func GenerateSignedPaymentMessage(ethAddress common.Address, paymentMethod uint8, paymentNumber, chargeAmountInWei *big.Int) []byte {
//keccak256(abi.encodePacked(msg.sender, _paymentNumber, _paymentMethod, _chargeAmountInWei))

addressBytes := ethAddress.Bytes()
// we need to cast to []byte in order to generate a keccak hash
methodBytes := make([]byte, 1)
methodBytes[0] = byte(paymentMethod)
numberBytes := paymentNumber.Bytes()
amountBytes := chargeAmountInWei.Bytes()
// generate the hash
hash := crypto.Keccak256(addressBytes, numberBytes, methodBytes, amountBytes)
return hash

}

Was, wenn ich so anrufe

address := common.HexToAddress("0xa1d9e8788414eA9827f9639c4bd81bA8f3A29758")
method := uint8(0)
number := big.NewInt(0)
amount := big.NewInt(0)
hash := GenerateSignedPaymentMessage(address, method, number, amount)
fmt.Println(hash.String())

was die folgende Ausgabe 0x7fc96d5f44e3e792633fcc981adf2bd0f644f0c167132eca5659b8a72d95bf07ergibt, die nicht mit dem vom Solidity-Code angegebenen Hash übereinstimmt. Ich bin mir nicht sicher, was ich hier tun soll, also wäre jeder Rat großartig!

BEARBEITEN:

Wie von smarx darauf hingewiesen, habe ich die folgende Funktion ausprobiert

func TestHash(t *testing.T) {
address := common.HexToAddress("0xa1d9e8788414eA9827f9639c4bd81bA8f3A29758")
bn := make([]byte, 32)
ba := make([]byte, 32)
bm := make([]byte, 32)
bn[31] = 0
ba[31] = 0
bm[31] = 0
hash := crypto.Keccak256Hash(address.Bytes(), bn, ba, bm)
fmt.Println(hash.String())
}

Was den folgenden Hash erzeugt0xfc60222910c18ebcfd5610479223663effa903325f3db1db39a4d5fa37ba33a2

Was macht .Bytes()? Meine Vermutung ist, dass es nicht 32 Bytes (die Größe eines uint256) zurückgibt, weil ich nicht sehe, wo Sie Informationen darüber bereitstellen, wie viele Bytes zurückgegeben werden sollen.
Wenn ich den Code von big.Int überfliege, würde ich sagen, dass dies definitiv das Problem ist. Sie erhalten wahrscheinlich nur ein einzelnes Byte für jeden zurück. Sie müssen herausfinden, wie Sie das Ergebnis links auffüllen, um es auf 32 Bytes zu bringen.
Ah okay das würde Sinn machen! Ich werde es versuchen und hoffentlich wird es behoben :D

Antworten (1)

Es war definitiv das, worauf smarx hingewiesen hat! Ich habe die Bibliothek https://github.com/miguelmota/go-solidity-sha3 verwendet, die funktioniert!

hash := payment.SoliditySHA3(
    payment.Address("0xa1d9e8788414eA9827f9639c4bd81bA8f3A29758"),
    payment.Uint8(big.NewInt(0)),
    payment.Uint256(big.NewInt(0)),
    payment.Uint256(big.NewInt(0)),
)
fmt.Println(hex.EncodeToString(hash))