Commit 88ad20bd authored by 贾浩@五瓣科技's avatar 贾浩@五瓣科技

feat: base sepolia

parent cee88648
...@@ -2,5 +2,6 @@ ...@@ -2,5 +2,6 @@
.DS_Store .DS_Store
.vscode .vscode
build build
./log log
ca.crt *.crt
\ No newline at end of file keys
\ No newline at end of file
...@@ -9,18 +9,17 @@ database = "postgres" ...@@ -9,18 +9,17 @@ database = "postgres"
max_conn = 5 max_conn = 5
max_idle_conn = 2 max_idle_conn = 2
enable_log = true enable_log = true
cert_file = "ca.crt" cert_file = "db.crt"
[server] [server]
listen = "0.0.0.0:8080" listen = "0.0.0.0:8080"
[chain] [chain]
rpc = "https://opbnb-testnet-rpc.bnbchain.org" rpc = "https://sepolia.base.org"
user_contract = "0xC1Ae385c6152552d5d8C98d0d2EaCFfD4D526D7F" user_contract = "0xC7Fc6f3EDd3f7da34E8A8ebd9f5e5F667402caCD"
executor_contract = "0x25633efD1449a1e95b04Feb142f8A2E093D28E92" executor_contract = "0xDFC90EF0b1D48d3E08fD155450F0D53BCdb69f45"
app_point_contract = "0x0F0231ffaFf5989f201584cfD4C171b4e34e674B" app_point_contract = "0x88F3EE47113B64caF99e47af4f51333d55d86d85"
x_private_key = "xprv9xwX8JDK1LBoHbfUiif8tmaj5dTGEnrYrDat8RUNowmbz2hCD8N1wydNao1TBhgTzvF1gojUwekF4J28BNo4mCVW81BY3XUwDCQhscSMaC3" x_private_key = "xprv9y6rnLhNwmYzpdFqneZD7f61oj5Bhxi1gFrowBVafGE157V3DXPt7HunUep4dCrJ7UEVRPFDtgWFGNp3R94iMnGhS2wbxQNuJBHKPq2UdjJ"
gas_sender_private_key = "2322e0021df509399321fa934e5869f914f7f82a1e366a29559d4a50bf1afa82" # 0x213EE93Ca7069C587e1a6ce5240B4A5eaD9Dd633
executor_private_key = "61acb7bf51fac4c34767ab0c8faa2205d01d006f41051d86cb284a1e2d1e6f2a" executor_private_key = "61acb7bf51fac4c34767ab0c8faa2205d01d006f41051d86cb284a1e2d1e6f2a"
model_price = 10 model_price = 10
...@@ -14,14 +14,13 @@ type Config struct { ...@@ -14,14 +14,13 @@ type Config struct {
} }
type ChainConfig struct { type ChainConfig struct {
RPC string `toml:"rpc"` RPC string `toml:"rpc"`
UserContract string `toml:"user_contract"` UserContract string `toml:"user_contract"`
ExecutorContract string `toml:"executor_contract"` ExecutorContract string `toml:"executor_contract"`
XPrivateKey string `toml:"x_private_key"` XPrivateKey string `toml:"x_private_key"`
GasSenderPrivateKey string `toml:"gas_sender_private_key"` ExecutorPrivateKey string `toml:"executor_private_key"`
ExecutorPrivateKey string `toml:"executor_private_key"` ModelPrice int `toml:"model_price"`
ModelPrice int `toml:"model_price"` AppPointContract string `toml:"app_point_contract"`
AppPointContract string `toml:"app_point_contract"`
} }
type PGSQLConfig struct { type PGSQLConfig struct {
......
[ [
{
"inputs": [],
"name": "ECDSAInvalidSignature",
"type": "error"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "length",
"type": "uint256"
}
],
"name": "ECDSAInvalidSignatureLength",
"type": "error"
},
{
"inputs": [
{
"internalType": "bytes32",
"name": "s",
"type": "bytes32"
}
],
"name": "ECDSAInvalidSignatureS",
"type": "error"
},
{ {
"inputs": [ "inputs": [
{ {
...@@ -85,6 +112,49 @@ ...@@ -85,6 +112,49 @@
"name": "ERC20InvalidSpender", "name": "ERC20InvalidSpender",
"type": "error" "type": "error"
}, },
{
"inputs": [
{
"internalType": "uint256",
"name": "deadline",
"type": "uint256"
}
],
"name": "ERC2612ExpiredSignature",
"type": "error"
},
{
"inputs": [
{
"internalType": "address",
"name": "signer",
"type": "address"
},
{
"internalType": "address",
"name": "owner",
"type": "address"
}
],
"name": "ERC2612InvalidSigner",
"type": "error"
},
{
"inputs": [
{
"internalType": "address",
"name": "account",
"type": "address"
},
{
"internalType": "uint256",
"name": "currentNonce",
"type": "uint256"
}
],
"name": "InvalidAccountNonce",
"type": "error"
},
{ {
"inputs": [], "inputs": [],
"name": "InvalidInitialization", "name": "InvalidInitialization",
...@@ -142,6 +212,12 @@ ...@@ -142,6 +212,12 @@
"name": "Approval", "name": "Approval",
"type": "event" "type": "event"
}, },
{
"anonymous": false,
"inputs": [],
"name": "EIP712DomainChanged",
"type": "event"
},
{ {
"anonymous": false, "anonymous": false,
"inputs": [ "inputs": [
...@@ -199,6 +275,19 @@ ...@@ -199,6 +275,19 @@
"name": "Transfer", "name": "Transfer",
"type": "event" "type": "event"
}, },
{
"inputs": [],
"name": "DOMAIN_SEPARATOR",
"outputs": [
{
"internalType": "bytes32",
"name": "",
"type": "bytes32"
}
],
"stateMutability": "view",
"type": "function"
},
{ {
"inputs": [ "inputs": [
{ {
...@@ -324,6 +413,49 @@ ...@@ -324,6 +413,49 @@
"stateMutability": "view", "stateMutability": "view",
"type": "function" "type": "function"
}, },
{
"inputs": [],
"name": "eip712Domain",
"outputs": [
{
"internalType": "bytes1",
"name": "fields",
"type": "bytes1"
},
{
"internalType": "string",
"name": "name",
"type": "string"
},
{
"internalType": "string",
"name": "version",
"type": "string"
},
{
"internalType": "uint256",
"name": "chainId",
"type": "uint256"
},
{
"internalType": "address",
"name": "verifyingContract",
"type": "address"
},
{
"internalType": "bytes32",
"name": "salt",
"type": "bytes32"
},
{
"internalType": "uint256[]",
"name": "extensions",
"type": "uint256[]"
}
],
"stateMutability": "view",
"type": "function"
},
{ {
"inputs": [], "inputs": [],
"name": "initialize", "name": "initialize",
...@@ -400,6 +532,25 @@ ...@@ -400,6 +532,25 @@
"stateMutability": "view", "stateMutability": "view",
"type": "function" "type": "function"
}, },
{
"inputs": [
{
"internalType": "address",
"name": "owner",
"type": "address"
}
],
"name": "nonces",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{ {
"inputs": [], "inputs": [],
"name": "owner", "name": "owner",
...@@ -413,6 +564,49 @@ ...@@ -413,6 +564,49 @@
"stateMutability": "view", "stateMutability": "view",
"type": "function" "type": "function"
}, },
{
"inputs": [
{
"internalType": "address",
"name": "owner",
"type": "address"
},
{
"internalType": "address",
"name": "spender",
"type": "address"
},
{
"internalType": "uint256",
"name": "value",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "deadline",
"type": "uint256"
},
{
"internalType": "uint8",
"name": "v",
"type": "uint8"
},
{
"internalType": "bytes32",
"name": "r",
"type": "bytes32"
},
{
"internalType": "bytes32",
"name": "s",
"type": "bytes32"
}
],
"name": "permit",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{ {
"inputs": [ "inputs": [
{ {
......
This diff is collapsed.
...@@ -4,6 +4,7 @@ import ( ...@@ -4,6 +4,7 @@ import (
"contract_backend/contract/aon_executor" "contract_backend/contract/aon_executor"
"contract_backend/contract/aon_user" "contract_backend/contract/aon_user"
"contract_backend/contract/erc20" "contract_backend/contract/erc20"
"contract_backend/util"
"crypto/ecdsa" "crypto/ecdsa"
"math/big" "math/big"
...@@ -13,6 +14,27 @@ import ( ...@@ -13,6 +14,27 @@ import (
"github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/crypto"
) )
func (d *Dao) LoginByServer(byteKey []byte, userAddress, userId string) (txHash common.Hash, err error) {
instance, err := aon_user.NewAonUser(common.HexToAddress(d.c.Chain.UserContract), d.ethClient)
if err != nil {
return common.Hash{}, err
}
privateKey := crypto.ToECDSAUnsafe(byteKey)
auth, err := bind.NewKeyedTransactorWithChainID(privateKey, d.chainId)
if err != nil {
return common.Hash{}, err
}
auth.GasPrice = d.gasPrice
auth.GasLimit = 700000
tx, err := instance.LoginByServer(auth, common.HexToAddress(userAddress), userId, "")
if err != nil {
return common.Hash{}, err
}
_, err = d.WaitForReceipt(tx.Hash())
return tx.Hash(), err
}
func (d *Dao) Login(byteKey []byte, userId string, inviter string) (txHash common.Hash, err error) { func (d *Dao) Login(byteKey []byte, userId string, inviter string) (txHash common.Hash, err error) {
instance, err := aon_user.NewAonUser(common.HexToAddress(d.c.Chain.UserContract), d.ethClient) instance, err := aon_user.NewAonUser(common.HexToAddress(d.c.Chain.UserContract), d.ethClient)
if err != nil { if err != nil {
...@@ -33,14 +55,15 @@ func (d *Dao) Login(byteKey []byte, userId string, inviter string) (txHash commo ...@@ -33,14 +55,15 @@ func (d *Dao) Login(byteKey []byte, userId string, inviter string) (txHash commo
return tx.Hash(), nil return tx.Hash(), nil
} }
func (d *Dao) CheckApprove(byteKey []byte) (txHash common.Hash, err error) { func (d *Dao) CheckPermit(userByteKey []byte) (txHash common.Hash, err error) {
instance, err := erc20.NewErc20(common.HexToAddress(d.c.Chain.AppPointContract), d.ethClient) instance, err := erc20.NewErc20(common.HexToAddress(d.c.Chain.AppPointContract), d.ethClient)
if err != nil { if err != nil {
return return
} }
privateKey := crypto.ToECDSAUnsafe(byteKey) executePrivateKey := crypto.ToECDSAUnsafe(common.Hex2Bytes(d.c.Chain.ExecutorPrivateKey))
user := crypto.PubkeyToAddress(privateKey.PublicKey) userPrivateKey := crypto.ToECDSAUnsafe(userByteKey)
allowance, err := instance.Allowance(&bind.CallOpts{}, user, common.HexToAddress(d.c.Chain.ExecutorContract)) userAddress := crypto.PubkeyToAddress(userPrivateKey.PublicKey)
allowance, err := instance.Allowance(&bind.CallOpts{}, userAddress, common.HexToAddress(d.c.Chain.ExecutorContract))
if err != nil { if err != nil {
return return
} }
...@@ -48,20 +71,44 @@ func (d *Dao) CheckApprove(byteKey []byte) (txHash common.Hash, err error) { ...@@ -48,20 +71,44 @@ func (d *Dao) CheckApprove(byteKey []byte) (txHash common.Hash, err error) {
return return
} }
// 执行approve // 执行permit
auth, err := bind.NewKeyedTransactorWithChainID(privateKey, d.chainId) auth, err := bind.NewKeyedTransactorWithChainID(executePrivateKey, d.chainId)
if err != nil { if err != nil {
return return
} }
auth.GasPrice = d.gasPrice auth.GasPrice = d.gasPrice
auth.GasLimit = 100000 auth.GasLimit = 100000
tx, err := instance.Approve(auth, common.HexToAddress(d.c.Chain.ExecutorContract), abi.MaxUint256) nextNonce, err := instance.Nonces(&bind.CallOpts{}, userAddress)
if err != nil {
return
}
v, r, s, err := util.PermitSign(
userByteKey,
"AON Application Score",
"1",
d.chainId,
nextNonce,
common.HexToAddress(d.c.Chain.AppPointContract),
userAddress,
common.HexToAddress(d.c.Chain.ExecutorContract))
if err != nil { if err != nil {
return return
} }
return tx.Hash(), nil
tx, err := instance.Permit(auth,
userAddress,
common.HexToAddress(d.c.Chain.ExecutorContract),
abi.MaxUint256,
big.NewInt(2000000000),
v,
r,
s)
if err != nil {
return
}
return tx.Hash(), nil
} }
func (d *Dao) ExecuteTask(privateKey *ecdsa.PrivateKey, executeId, userId, appId string, modelIds []string, price *big.Int) (txHash common.Hash, err error) { func (d *Dao) ExecuteTask(privateKey *ecdsa.PrivateKey, executeId, userId, appId string, modelIds []string, price *big.Int) (txHash common.Hash, err error) {
...@@ -77,8 +124,6 @@ func (d *Dao) ExecuteTask(privateKey *ecdsa.PrivateKey, executeId, userId, appId ...@@ -77,8 +124,6 @@ func (d *Dao) ExecuteTask(privateKey *ecdsa.PrivateKey, executeId, userId, appId
auth.GasPrice = d.gasPrice auth.GasPrice = d.gasPrice
auth.GasLimit = 1500000 auth.GasLimit = 1500000
appId = "NYFiNxBEonlwYIrTQ2V8s9ks0I0ZPRoR1UVASanthVMA"
modelIds = []string{"fUIqu5A2igp9nNJaEUMTod4amDFgIXWmHaTZNNbKo58A"}
tx, err := instance.ExecuteByUserId(auth, executeId, userId, appId, modelIds, price) tx, err := instance.ExecuteByUserId(auth, executeId, userId, appId, modelIds, price)
if err != nil { if err != nil {
return common.Hash{}, err return common.Hash{}, err
......
...@@ -9,7 +9,6 @@ import ( ...@@ -9,7 +9,6 @@ import (
"sync" "sync"
"time" "time"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/ethclient" "github.com/ethereum/go-ethereum/ethclient"
"github.com/ethereum/go-ethereum/rpc" "github.com/ethereum/go-ethereum/rpc"
"gorm.io/driver/postgres" "gorm.io/driver/postgres"
...@@ -52,10 +51,6 @@ func New(_c *config.Config) (dao *Dao, err error) { ...@@ -52,10 +51,6 @@ func New(_c *config.Config) (dao *Dao, err error) {
dao.chainId = chainId dao.chainId = chainId
k, _ := crypto.HexToECDSA(_c.Chain.GasSenderPrivateKey)
dao.gasSenderNonce, _ = dao.ethClient.NonceAt(context.Background(), crypto.PubkeyToAddress(k.PublicKey), nil)
go dao.LoopGasPrice()
if _c.PGSQL.CertFile != "" { if _c.PGSQL.CertFile != "" {
dsn = fmt.Sprintf("%s sslmode=require sslrootcert=%s", dsn, _c.PGSQL.CertFile) dsn = fmt.Sprintf("%s sslmode=require sslrootcert=%s", dsn, _c.PGSQL.CertFile)
} }
...@@ -85,9 +80,9 @@ func New(_c *config.Config) (dao *Dao, err error) { ...@@ -85,9 +80,9 @@ func New(_c *config.Config) (dao *Dao, err error) {
migrate := os.Getenv("MIGRATE") migrate := os.Getenv("MIGRATE")
if migrate == "true" { if migrate == "true" {
// err = dao.db.AutoMigrate(&dbModel.User{}, &dbModel.Active{}, &dbModel.ChatGroup{}) // err = dao.db.AutoMigrate(&dbModel.User{}, &dbModel.Active{}, &dbModel.ChatGroup{})
if err != nil { // if err != nil {
return // return
} // }
} }
return dao, nil return dao, nil
......
...@@ -3,7 +3,6 @@ package server ...@@ -3,7 +3,6 @@ package server
import ( import (
. "contract_backend/constant" . "contract_backend/constant"
"contract_backend/util" "contract_backend/util"
"fmt"
"io" "io"
"time" "time"
...@@ -52,27 +51,23 @@ func userChange(c *gin.Context) { ...@@ -52,27 +51,23 @@ func userChange(c *gin.Context) {
} }
needLogin := true needLogin := true
lastLogin := gjson.Get(string(rawJson), "old_row.last_sign_in_at").String()
newLogin := gjson.Get(string(rawJson), "new_row.last_sign_in_at").String()
if lastLogin == newLogin {
needLogin = false
} else if lastLogin != "" {
loginTime, err := time.Parse(lastLogin, "2006-01-02T15:04:05.999999+07:00")
if err != nil {
log.WithError(err).Error("parse time error")
c.JSON(200, withError(InternalError))
return
}
if operation == "UPDATE" { // 如果loginTime是0点之前
lastLogin := gjson.Get(string(rawJson), "old_row.last_sign_in_at").String() todayUnix := time.Now().Unix() % 86400
newLogin := gjson.Get(string(rawJson), "new_row.last_sign_in_at").String() lastLoginUnix := loginTime.Unix() % 86400
if lastLogin == newLogin { if lastLoginUnix >= todayUnix {
needLogin = false needLogin = false
} else if lastLogin != "" {
fmt.Println(lastLogin)
loginTime, err := time.Parse(lastLogin, "2006-01-02T15:04:05.999999+07:00")
if err != nil {
log.WithError(err).Error("parse time error")
c.JSON(200, withError(InternalError))
return
}
// 如果loginTime是0点之前
todayUnix := time.Now().Unix() % 86400
lastLoginUnix := loginTime.Unix() % 86400
if lastLoginUnix >= todayUnix {
needLogin = false
}
} }
} }
...@@ -83,45 +78,8 @@ func userChange(c *gin.Context) { ...@@ -83,45 +78,8 @@ func userChange(c *gin.Context) {
// 需要登录 // 需要登录
userAddress := crypto.PubkeyToAddress(key.PublicKey) userAddress := crypto.PubkeyToAddress(key.PublicKey)
val, err := d.EstimateGasRecharge(userAddress)
if err != nil {
log.WithError(err).Error("estimate gas error")
c.JSON(200, withError(InternalError))
return
}
if val != nil {
// 需要充值
txHash, err := d.TransferETH(conf.Chain.GasSenderPrivateKey, userAddress, val)
if err != nil {
log.WithError(err).Error("transfer eth error")
c.JSON(200, withError(InternalError))
return
}
receipt, err := d.WaitForReceipt(txHash)
if err != nil {
log.WithError(err).Error("wait for receipt error")
c.JSON(200, withError(InternalError))
return
}
if receipt.Status != 1 {
log.WithField("receipt", receipt).Error("receipt status error")
c.JSON(200, withError(InternalError))
return
}
log.WithFields(log.Fields{
"userId": userId,
"address": userAddress.String(),
"txHash": txHash,
"val": val.String(),
}).Info("user recharge success")
time.Sleep(time.Second)
}
// 在alpine nocgo上使用ecdsa.PrivateKey会报错 msg="call ca login error" error="private key curve is not secp256k1" // 在alpine nocgo上使用ecdsa.PrivateKey会报错 msg="call ca login error" error="private key curve is not secp256k1"
txHash, err := d.Login(key.Serialize(), userId, "") txHash, err := d.LoginByServer(common.Hex2Bytes(conf.Chain.ExecutorPrivateKey), userAddress.Hex(), userId)
if err != nil { if err != nil {
log.WithError(err).Error("call ca login error") log.WithError(err).Error("call ca login error")
c.JSON(200, withError(InternalError)) c.JSON(200, withError(InternalError))
...@@ -134,16 +92,17 @@ func userChange(c *gin.Context) { ...@@ -134,16 +92,17 @@ func userChange(c *gin.Context) {
}).Info("user login") }).Info("user login")
go func() { go func() {
txHash, err = d.CheckApprove(key.Serialize()) time.Sleep(time.Second)
txHash, err = d.CheckPermit(key.Serialize())
if err != nil { if err != nil {
log.WithError(err).Error("call ca check approve error") log.WithError(err).Error("call ca check permit error")
return return
} }
if txHash.Hex() != (common.Hash{}).Hex() { if txHash.Hex() != (common.Hash{}).Hex() {
log.WithFields(log.Fields{ log.WithFields(log.Fields{
"userId": userId, "userId": userId,
"txHash": txHash, "txHash": txHash,
}).Info("user do approve tx") }).Info("user do permit tx")
} }
}() }()
......
...@@ -2,7 +2,11 @@ package util ...@@ -2,7 +2,11 @@ package util
import ( import (
"encoding/binary" "encoding/binary"
"encoding/hex"
"encoding/json"
"fmt" "fmt"
"io"
"os"
"strings" "strings"
"testing" "testing"
"time" "time"
...@@ -19,12 +23,32 @@ func TestXpriv(t *testing.T) { ...@@ -19,12 +23,32 @@ func TestXpriv(t *testing.T) {
} }
func TestUidToKey(t *testing.T) {
xpri := "xprv9xwX8JDK1LBoHbfUiif8tmaj5dTGEnrYrDat8RUNowmbz2hCD8N1wydNao1TBhgTzvF1gojUwekF4J28BNo4mCVW81BY3XUwDCQhscSMaC3"
f, _ := os.Open("un.json")
data, _ := io.ReadAll(f)
temp := []string{}
keys := [][]string{}
json.Unmarshal(data, &temp)
for i := 0; i < len(temp); i++ {
k, _ := GetPrivateKeyByUserId(xpri, temp[i])
keys = append(keys, []string{hex.EncodeToString(k.Serialize()), temp[i]})
}
j, _ := json.Marshal(keys)
_ = os.WriteFile("key.json", j, 0644)
}
func TestGenHDKey(t *testing.T) { func TestGenHDKey(t *testing.T) {
xpub := "xpub6C9QTBQW4NDiwahEdPibQbLUtnhfny3E464dgDXGDkWFdqnkddYicVqUvaeAe8QrmXoSqXrcKMxszf8DJ2xzaQhth3nAgoBwjfC1J8jYwFS" xpub := "xpub6C6DBrEGn97J37LJtg6DUo2kMkug7RRs3UnQjZuCDbkywupBm4i8f6EGKwQDyPSX5SFekhHEkXGDbTwoaJUeZLbUXkeK8ETep7qsher1Pk7"
// xpub := "xpub6C2ojpneBn4KHz1zaHpsyVHQMuJQbeDPbdkXywAUR43hXpjyQNcRv1ZQdvxnGmGKvXLoGPoN1G7cwfmW5CGZjPagpLnggXmqN52HhJk9F4B" // xpub := "xpub6C2ojpneBn4KHz1zaHpsyVHQMuJQbeDPbdkXywAUR43hXpjyQNcRv1ZQdvxnGmGKvXLoGPoN1G7cwfmW5CGZjPagpLnggXmqN52HhJk9F4B"
ret, err := GetAddressByUserId("001b6462-43e6-4e8e-88b9-9636c8dece0d", xpub) ret, err := GetAddressByUserId(xpub, "3d6ef12c-c55b-4043-afca-035ccc9a24bb")
t.Log(ret.String(), err) t.Log(ret.String(), err)
return return
// k, _ := GetPubKeyByPub(xpub, "0/1") // k, _ := GetPubKeyByPub(xpub, "0/1")
......
package util
import (
"math/big"
"github.com/ethereum/go-ethereum/accounts/abi"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/math"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/signer/core/apitypes"
)
func PermitSign(k []byte, name, version string, chainId, nextNonce *big.Int, contract, owner, spender common.Address) (v uint8, r, s [32]byte, err error) {
typedData := apitypes.TypedData{
Types: apitypes.Types{
"EIP712Domain": []apitypes.Type{
{Name: "name", Type: "string"},
{Name: "version", Type: "string"},
{Name: "chainId", Type: "uint256"},
{Name: "verifyingContract", Type: "address"},
},
"Permit": []apitypes.Type{
{Name: "owner", Type: "address"},
{Name: "spender", Type: "address"},
{Name: "value", Type: "uint256"},
{Name: "nonce", Type: "uint256"},
{Name: "deadline", Type: "uint256"},
},
},
PrimaryType: "Permit",
Domain: apitypes.TypedDataDomain{
Name: name, // 代币名称
Version: version,
ChainId: math.NewHexOrDecimal256(chainId.Int64()),
VerifyingContract: contract.Hex(),
},
Message: apitypes.TypedDataMessage{
"owner": owner.Hex(),
"spender": spender.Hex(),
"value": abi.MaxUint256,
"nonce": nextNonce,
"deadline": big.NewInt(2000000000),
},
}
domainSeparator, err := typedData.HashStruct("EIP712Domain", typedData.Domain.Map())
if err != nil {
return
}
typedDataHash, err := typedData.HashStruct(typedData.PrimaryType, typedData.Message)
sig, err := crypto.Sign(crypto.Keccak256([]byte("\x19\x01"), domainSeparator, typedDataHash), crypto.ToECDSAUnsafe(k))
if err != nil {
return
}
v = sig[64] + 27
copy(r[:], sig[:32])
copy(s[:], sig[32:64])
return
}
package util
import (
"encoding/hex"
"fmt"
"math/big"
"testing"
"github.com/ethereum/go-ethereum/accounts/abi"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/math"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/signer/core/apitypes"
)
func Test2(t *testing.T) {
v, r, s, e := PermitSign(common.Hex2Bytes("9acd67dc1d0382852501f9970aff6c3641b947c03d618a8e145396dbb62aac35"),
"AON Application Score",
"1",
big.NewInt(84532),
big.NewInt(0),
common.HexToAddress("0x88F3EE47113B64caF99e47af4f51333d55d86d85"),
common.HexToAddress("0xbDE4bD1AE8c0E49940904E721b68a278f4eDBfaf"),
common.HexToAddress("0x88F3EE47113B64caF99e47af4f51333d55d86d85"),
)
t.Log(e)
t.Log(v)
t.Log(common.Bytes2Hex(r[:]))
t.Log(common.Bytes2Hex(s[:]))
}
func TestPermit(t *testing.T) {
chainId := big.NewInt(1)
ca := common.HexToAddress("0xec53bF9167f50cDEB3Ae105f56099aaaB9061F83")
typedata := apitypes.TypedData{
Types: apitypes.Types{
"EIP712Domain": []apitypes.Type{
{Name: "name", Type: "string"},
{Name: "version", Type: "string"},
{Name: "chainId", Type: "uint256"},
{Name: "verifyingContract", Type: "address"},
},
"Permit": []apitypes.Type{
{Name: "owner", Type: "address"},
{Name: "spender", Type: "address"},
{Name: "value", Type: "uint256"},
{Name: "nonce", Type: "uint256"},
{Name: "deadline", Type: "uint256"},
},
},
PrimaryType: "Permit",
Domain: apitypes.TypedDataDomain{
Name: "EIGEN", // 代币名称
Version: "1",
ChainId: math.NewHexOrDecimal256(chainId.Int64()), // 链 ID
VerifyingContract: ca.Hex(), // 代币合约地址
},
Message: apitypes.TypedDataMessage{
"owner": common.HexToAddress("0x00ad3D4cC099Be937879451698C673CBD5C3CEfc").String(),
"spender": common.HexToAddress("0x75d7B715DD175DE4b75A99c1ee2ae278b25BDBbA").String(),
"value": abi.MaxUint256,
"nonce": big.NewInt(0),
"deadline": big.NewInt(2000000000),
},
}
domainSeparator, err := typedata.HashStruct("EIP712Domain", typedata.Domain.Map())
t.Log(err)
t.Log(domainSeparator.String())
typedDataHash, err := typedata.HashStruct(typedata.PrimaryType, typedata.Message)
if err != nil {
t.Log(err)
}
fmt.Println("domainSeparator:", hex.EncodeToString(domainSeparator))
fmt.Println("typedDataHash:", hex.EncodeToString(typedDataHash))
k := crypto.ToECDSAUnsafe(common.Hex2Bytes("9acd67dc1d0382852501f9970aff6c3641b947c03d618a8e145396dbb62aac35"))
// b09b7edc6cf15e9790f017cb13819e21f8b9a6d32163e3c4ec97562506084ec3
t.Log(common.Bytes2Hex(crypto.Keccak256([]byte("\x19\x01"), domainSeparator, typedDataHash)))
sig, err := crypto.Sign(crypto.Keccak256([]byte("\x19\x01"), domainSeparator, typedDataHash), k)
t.Log(common.Bytes2Hex(sig))
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment