Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
C
contract_backend
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Odysseus
contract_backend
Commits
88ad20bd
Commit
88ad20bd
authored
Jan 08, 2025
by
贾浩@五瓣科技
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat: base sepolia
parent
cee88648
Changes
11
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
744 additions
and
99 deletions
+744
-99
.gitignore
.gitignore
+3
-2
config.toml
config.toml
+6
-7
config.go
config/config.go
+7
-8
erc20.abi
contract/erc20.abi
+194
-0
erc20.go
contract/erc20/erc20.go
+287
-1
contract.go
dao/contract.go
+55
-10
dao.go
dao/dao.go
+3
-8
user.go
server/user.go
+20
-61
hdkey_test.go
util/hdkey_test.go
+26
-2
permit.go
util/permit.go
+61
-0
permit_test.go
util/permit_test.go
+82
-0
No files found.
.gitignore
View file @
88ad20bd
...
@@ -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
config.toml
View file @
88ad20bd
...
@@ -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
=
"0xC
1Ae385c6152552d5d8C98d0d2EaCFfD4D526D7F
"
user_contract
=
"0xC
7Fc6f3EDd3f7da34E8A8ebd9f5e5F667402caCD
"
executor_contract
=
"0x
25633efD1449a1e95b04Feb142f8A2E093D28E92
"
executor_contract
=
"0x
DFC90EF0b1D48d3E08fD155450F0D53BCdb69f45
"
app_point_contract
=
"0x
0F0231ffaFf5989f201584cfD4C171b4e34e674B
"
app_point_contract
=
"0x
88F3EE47113B64caF99e47af4f51333d55d86d85
"
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
config/config.go
View file @
88ad20bd
...
@@ -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
{
...
...
contract/erc20.abi
View file @
88ad20bd
[
[
{
"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": [
{
{
...
...
contract/erc20/erc20.go
View file @
88ad20bd
This diff is collapsed.
Click to expand it.
dao/contract.go
View file @
88ad20bd
...
@@ -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
)
Check
Approve
(
b
yteKey
[]
byte
)
(
txHash
common
.
Hash
,
err
error
)
{
func
(
d
*
Dao
)
Check
Permit
(
userB
yteKey
[]
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
(
p
rivateKey
,
d
.
chainId
)
auth
,
err
:=
bind
.
NewKeyedTransactorWithChainID
(
executeP
rivateKey
,
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
...
...
dao/dao.go
View file @
88ad20bd
...
@@ -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
...
...
server/user.go
View file @
88ad20bd
...
@@ -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
lastLogin
Unix
>=
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
.
Login
ByServer
(
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"
)
}
}
}()
}()
...
...
util/hdkey_test.go
View file @
88ad20bd
...
@@ -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
:=
"xpub6C
9QTBQW4NDiwahEdPibQbLUtnhfny3E464dgDXGDkWFdqnkddYicVqUvaeAe8QrmXoSqXrcKMxszf8DJ2xzaQhth3nAgoBwjfC1J8jYwFS
"
xpub
:=
"xpub6C
6DBrEGn97J37LJtg6DUo2kMkug7RRs3UnQjZuCDbkywupBm4i8f6EGKwQDyPSX5SFekhHEkXGDbTwoaJUeZLbUXkeK8ETep7qsher1Pk7
"
// 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")
...
...
util/permit.go
0 → 100644
View file @
88ad20bd
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
}
util/permit_test.go
0 → 100644
View file @
88ad20bd
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
))
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment