如何获得与 Golang 中的 Solidity `abi.encodePacked` 相同的返回值

问题描述 投票:0回答:3

如何在 golang 中运行 abi.encodePacked?

在 Solidity 中,我使用

keccak256(abi.encodePacked(a, b))
来计算参数的签名。

这是我的合同。

pragma solidity ^0.4.24;

import "openzeppelin-solidity/contracts/ECRecovery.sol";


contract MyContract {
    using ECRecovery for bytes32;
    address permittedSinger;

    function doSomething(
    bytes32 id, uint256 amount, bytes sig
    ) {
        bytes32 hash = getHash(msg.sender, id, amount);
        address msgSigner = hash.recover(sig);
        require(msgSigner == permittedSinger);
    }

    function getMsgSigner(bytes32 proveHash, bytes sig) public pure returns (address) {
        return proveHash.recover(sig);
    }

    function getHash(
    address receiver, bytes32 id, uint256 amount
    ) pure returns (bytes32) {
        return keccak256(abi.encodePacked(receiver, id, amount));
    }
}
go ethereum solidity
3个回答
11
投票

终于我成功了。 :)

package main

import (
    "math/big"
    "github.com/ethereum/go-ethereum/common/hexutil"
    "github.com/ethereum/go-ethereum/accounts/abi"
    "log"
    "github.com/ethereum/go-ethereum/common"
    "github.com/ethereum/go-ethereum/crypto/sha3"
)

func main() {
    uint256Ty, _ := abi.NewType("uint256")
    bytes32Ty, _ := abi.NewType("bytes32")
    addressTy, _ := abi.NewType("address")

    arguments := abi.Arguments{
        {
            Type: addressTy,
        },
        {
            Type: bytes32Ty,
        },
        {
            Type: uint256Ty,
        },
    }

    bytes, _ := arguments.Pack(
        common.HexToAddress("0x0000000000000000000000000000000000000000"),
        [32]byte{'I','D','1'},
        big.NewInt(42),
    )

    var buf []byte
    hash := sha3.NewKeccak256()
    hash.Write(bytes)
    buf = hash.Sum(buf)

    log.Println(hexutil.Encode(buf))
    // output:
    // 0x1f214438d7c061ad56f98540db9a082d372df1ba9a3c96367f0103aa16c2fe9a
}

5
投票

正如在接受答案的评论中所说的那样,

Jakub N
返回为
Go's arguments.Pack
而不是
abi.encode
。在您的情况下,它可以工作,因为所有打包值都是 32 字节,但如果您还添加一些字符串,那么结果会有所不同。

以下是如何与

abi.encodePacked

对应的tightly打包编码兼容:


abi.encodePacked

它也更高效,因为我们不为此打包和分配额外的内存。哈希函数迭代现有值。


-1
投票

我在案例3中已经做了详细的解答。

https://ethereum.stackexchange.com/a/166536/144566

TLDR, 您可以在

https://go.dev/play/p/V3artUBQMUe

查看代码,我尝试以使用以太坊的人编码的方式构建它。您可以开始将它用作任何功能 对于 abi.encodePacked,您只需附加字节即可。

对于abi.encode,您可以执行OP已回答的操作,或者您需要执行我在go-playground链接中所做的操作,基本上创建一个与您需要编码的数据相匹配的参数对象,并将参数传递给参数。 Pack(...) 方法

© www.soinside.com 2019 - 2024. All rights reserved.