golang 计算。ERC2612签名问题

我用golang 代码实现了一个ERC2612签名的代码。签名验证不通过,哪位大佬给看看哪出了问题。


import (
    "crypto/ecdsa"
    "fmt"
    "github.com/ethereum/go-ethereum/accounts/abi"
    "log"
    "math/big"
    "strings"

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

func main() {

    // 用户私钥,用于签名
    privateKey, err := crypto.HexToECDSA("503f38a9c967ed597e47fe25643985f032b072db8075426a92110f82df48dfcb")
    if err != nil {
        log.Fatal(err)
    }

    publicKey := privateKey.Public()
    publicKeyECDSA, ok := publicKey.(*ecdsa.PublicKey)
    if !ok {
        log.Fatal("error casting public key to ECDSA")
    }

    // 构建EIP-712签名消息结构
    abiString0 := `
[
    {
        "inputs": [
            {
                "internalType": "bytes32",
                "name": "hash",
                "type": "bytes32"
            },
            {
                "internalType": "bytes32",
                "name": "hashedName",
                "type": "bytes32"
            },
            {
                "internalType": "bytes32",
                "name": "hashedVersion",
                "type": "bytes32"
            },
            {
                "internalType": "uint256",
                "name": "chainid",
                "type": "uint256"
            },
            {
                "internalType": "address",
                "name": "token",
                "type": "address"
            }
        ],
        "name": "buildDomainSeparator",
        "outputs": [
            {
                "internalType": "bytes32",
                "name": "ha",
                "type": "bytes32"
            }
        ],
        "stateMutability": "pure",
        "type": "function"
    }
]
`
    contractAbi0, _ := abi.JSON(strings.NewReader(abiString0))
    //erc20 合约
    token := common.HexToAddress("0xe2899bddFD890e320e643044c6b95B9B0b84157A")
    hashedName := "MyToken"
    chainId := big.NewInt(1)
    bytes0, err := contractAbi0.Pack("buildDomainSeparator",
        crypto.Keccak256Hash([]byte("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)")),
        crypto.Keccak256Hash([]byte(hashedName)),
        crypto.Keccak256Hash([]byte("1")),
        chainId,
        token,
    )
    bytes0 = bytes0[4:]
    hash0 := crypto.Keccak256Hash(bytes0)

    // 构建EIP-712签名消息结构
    abiString := `
[
    {
        "inputs": [
            {
                "internalType": "bytes32",
                "name": "permit",
                "type": "bytes32"
            },
            {
                "internalType": "address",
                "name": "owner",
                "type": "address"
            },
            {
                "internalType": "address",
                "name": "spender",
                "type": "address"
            },
            {
                "internalType": "uint256",
                "name": "value",
                "type": "uint256"
            },
            {
                "internalType": "uint256",
                "name": "nonce",
                "type": "uint256"
            },
            {
                "internalType": "uint256",
                "name": "deadline",
                "type": "uint256"
            }
        ],
        "name": "dd",
        "outputs": [
            {
                "internalType": "bytes32",
                "name": "ha",
                "type": "bytes32"
            }
        ],
        "stateMutability": "pure",
        "type": "function"
    }
]
`
    contractAbi, _ := abi.JSON(strings.NewReader(abiString))
    fromAddress := crypto.PubkeyToAddress(*publicKeyECDSA)
    spender := common.HexToAddress("0x1c91347f2A44538ce62453BEBd9Aa907C662b4bD") //
    nonce := big.NewInt(1)
    // Stake数量
    amount := big.NewInt(100)
    // permit函数截止时间
    deadline := big.NewInt(1686091610)
    bytes, err := contractAbi.Pack("dd",
        crypto.Keccak256Hash([]byte("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)")),
        fromAddress,
        spender,
        amount,
        nonce,
        deadline,
    )
    bytes = bytes[4:]
    hash := crypto.Keccak256Hash(bytes)

    hh := solsha3.SoliditySHA3(
        solsha3.String("\x19\x01"),
        hash0,
        hash,
    )

    // 签名消息
    sig, err := crypto.Sign(hh, privateKey)
    if err != nil {
        log.Fatal(err)
    }

    v := sig[64]
    if v < 27 {
        v += 27
    }

    r := [32]byte{}
    s := [32]byte{}
    copy(r[:], sig[0:32])
    copy(s[:], sig[32:64])

    fmt.Println("amount:", amount)
    fmt.Println("deadline:", deadline)
    fmt.Printf("v: %d\n", v)
    fmt.Printf("r: 0x%x\n", r)
    fmt.Printf("s: 0x%x\n", s)
}
请先 登录 后评论

1 个回答

Tiny熊 - 布道者
  擅长:智能合约,以太坊
请先 登录 后评论