prepare txs for ens register

This commit is contained in:
andrey 2022-02-10 15:19:53 +01:00 committed by flexsurfer
parent 353767aee6
commit 3cc683587d
4 changed files with 88 additions and 29 deletions

View File

@ -1 +1 @@
0.94.5 0.94.6

View File

@ -18,6 +18,7 @@ import (
"github.com/ethereum/go-ethereum/accounts/abi" "github.com/ethereum/go-ethereum/accounts/abi"
"github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
ethTypes "github.com/ethereum/go-ethereum/core/types" ethTypes "github.com/ethereum/go-ethereum/core/types"
"github.com/status-im/status-go/account" "github.com/status-im/status-go/account"
"github.com/status-im/status-go/eth-node/types" "github.com/status-im/status-go/eth-node/types"
@ -140,7 +141,7 @@ func (api *API) PublicKeyOf(ctx context.Context, chainID uint64, username string
if err != nil { if err != nil {
return "", err return "", err
} }
return "0x" + hex.EncodeToString(pubKey.X[:]) + hex.EncodeToString(pubKey.Y[:]), nil return "0x04" + hex.EncodeToString(pubKey.X[:]) + hex.EncodeToString(pubKey.Y[:]), nil
} }
func (api *API) AddressOf(ctx context.Context, chainID uint64, username string) (*common.Address, error) { func (api *API) AddressOf(ctx context.Context, chainID uint64, username string) (*common.Address, error) {
@ -290,47 +291,66 @@ func (api *API) Register(ctx context.Context, chainID uint64, txArgs transaction
return tx.Hash().String(), nil return tx.Hash().String(), nil
} }
func (api *API) RegisterEstimate(ctx context.Context, chainID uint64, txArgs transactions.SendTxArgs, username string, pubkey string) (uint64, error) { func (api *API) RegisterPrepareTxCallMsg(ctx context.Context, chainID uint64, txArgs transactions.SendTxArgs, username string, pubkey string) (ethereum.CallMsg, error) {
priceHex, err := api.Price(ctx, chainID) priceHex, err := api.Price(ctx, chainID)
if err != nil { if err != nil {
return 0, err return ethereum.CallMsg{}, err
} }
price := new(big.Int) price := new(big.Int)
price.SetString(priceHex, 16) price.SetString(priceHex, 16)
registrarABI, err := abi.JSON(strings.NewReader(registrar.UsernameRegistrarABI)) registrarABI, err := abi.JSON(strings.NewReader(registrar.UsernameRegistrarABI))
if err != nil { if err != nil {
return 0, err return ethereum.CallMsg{}, err
} }
x, y := extractCoordinates(pubkey) x, y := extractCoordinates(pubkey)
extraData, err := registrarABI.Pack("register", usernameToLabel(username), common.Address(txArgs.From), x, y) extraData, err := registrarABI.Pack("register", usernameToLabel(username), common.Address(txArgs.From), x, y)
if err != nil { if err != nil {
return 0, err return ethereum.CallMsg{}, err
} }
sntABI, err := abi.JSON(strings.NewReader(erc20.SNTABI)) sntABI, err := abi.JSON(strings.NewReader(erc20.SNTABI))
if err != nil { if err != nil {
return 0, err return ethereum.CallMsg{}, err
} }
data, err := sntABI.Pack("approveAndCall", usernameRegistrarsByChainID[chainID], price, extraData) data, err := sntABI.Pack("approveAndCall", usernameRegistrarsByChainID[chainID], price, extraData)
if err != nil { if err != nil {
return 0, err return ethereum.CallMsg{}, err
} }
contractAddress := sntByChainID[chainID]
return ethereum.CallMsg{
From: common.Address(txArgs.From),
To: &contractAddress,
Value: big.NewInt(0),
Data: data,
}, nil
}
func (api *API) RegisterPrepareTx(ctx context.Context, chainID uint64, txArgs transactions.SendTxArgs, username string, pubkey string) (interface{}, error) {
callMsg, err := api.RegisterPrepareTxCallMsg(ctx, chainID, txArgs, username, pubkey)
if err != nil {
return nil, err
}
return toCallArg(callMsg), nil
}
func (api *API) RegisterEstimate(ctx context.Context, chainID uint64, txArgs transactions.SendTxArgs, username string, pubkey string) (uint64, error) {
ethClient, err := api.contractMaker.RPCClient.EthClient(chainID) ethClient, err := api.contractMaker.RPCClient.EthClient(chainID)
if err != nil { if err != nil {
return 0, err return 0, err
} }
contractAddress := sntByChainID[chainID] callMsg, err := api.RegisterPrepareTxCallMsg(ctx, chainID, txArgs, username, pubkey)
return ethClient.EstimateGas(ctx, ethereum.CallMsg{ if err != nil {
From: common.Address(txArgs.From), return 0, err
To: &contractAddress, }
Value: big.NewInt(0),
Data: data, return ethClient.EstimateGas(ctx, callMsg)
})
} }
func (api *API) SetPubKey(ctx context.Context, chainID uint64, txArgs transactions.SendTxArgs, password string, username string, pubkey string) (string, error) { func (api *API) SetPubKey(ctx context.Context, chainID uint64, txArgs transactions.SendTxArgs, password string, username string, pubkey string) (string, error) {
@ -360,39 +380,57 @@ func (api *API) SetPubKey(ctx context.Context, chainID uint64, txArgs transactio
return tx.Hash().String(), nil return tx.Hash().String(), nil
} }
func (api *API) SetPubKeyEstimate(ctx context.Context, chainID uint64, txArgs transactions.SendTxArgs, username string, pubkey string) (uint64, error) { func (api *API) SetPubKeyPrepareTxCallMsg(ctx context.Context, chainID uint64, txArgs transactions.SendTxArgs, username string, pubkey string) (ethereum.CallMsg, error) {
err := validateENSUsername(username) err := validateENSUsername(username)
if err != nil { if err != nil {
return 0, err return ethereum.CallMsg{}, err
} }
x, y := extractCoordinates(pubkey) x, y := extractCoordinates(pubkey)
resolverABI, err := abi.JSON(strings.NewReader(resolver.PublicResolverABI)) resolverABI, err := abi.JSON(strings.NewReader(resolver.PublicResolverABI))
if err != nil { if err != nil {
return 0, err return ethereum.CallMsg{}, err
} }
data, err := resolverABI.Pack("setPubkey", nameHash(username), x, y) data, err := resolverABI.Pack("setPubkey", nameHash(username), x, y)
if err != nil { if err != nil {
return 0, err return ethereum.CallMsg{}, err
} }
resolverAddress, err := api.Resolver(ctx, chainID, username)
if err != nil {
return ethereum.CallMsg{}, err
}
return ethereum.CallMsg{
From: common.Address(txArgs.From),
To: resolverAddress,
Value: big.NewInt(0),
Data: data,
}, nil
}
func (api *API) SetPubKeyPrepareTx(ctx context.Context, chainID uint64, txArgs transactions.SendTxArgs, username string, pubkey string) (interface{}, error) {
callMsg, err := api.SetPubKeyPrepareTxCallMsg(ctx, chainID, txArgs, username, pubkey)
if err != nil {
return nil, err
}
return toCallArg(callMsg), nil
}
func (api *API) SetPubKeyEstimate(ctx context.Context, chainID uint64, txArgs transactions.SendTxArgs, username string, pubkey string) (uint64, error) {
ethClient, err := api.contractMaker.RPCClient.EthClient(chainID) ethClient, err := api.contractMaker.RPCClient.EthClient(chainID)
if err != nil { if err != nil {
return 0, err return 0, err
} }
resolverAddress, err := api.Resolver(ctx, chainID, username) callMsg, err := api.SetPubKeyPrepareTxCallMsg(ctx, chainID, txArgs, username, pubkey)
if err != nil { if err != nil {
return 0, err return 0, err
} }
return ethClient.EstimateGas(ctx, ethereum.CallMsg{ return ethClient.EstimateGas(ctx, callMsg)
From: common.Address(txArgs.From),
To: resolverAddress,
Value: big.NewInt(0),
Data: data,
})
} }
func (api *API) ResourceURL(ctx context.Context, chainID uint64, username string) (*uri, error) { func (api *API) ResourceURL(ctx context.Context, chainID uint64, username string) (*uri, error) {
@ -462,3 +500,23 @@ func (api *API) ResourceURL(ctx context.Context, chainID uint64, username string
return nil, fmt.Errorf("unknown codec name %s", codecName) return nil, fmt.Errorf("unknown codec name %s", codecName)
} }
} }
func toCallArg(msg ethereum.CallMsg) interface{} {
arg := map[string]interface{}{
"from": msg.From,
"to": msg.To,
}
if len(msg.Data) > 0 {
arg["data"] = hexutil.Bytes(msg.Data)
}
if msg.Value != nil {
arg["value"] = (*hexutil.Big)(msg.Value)
}
if msg.Gas != 0 {
arg["gas"] = hexutil.Uint64(msg.Gas)
}
if msg.GasPrice != nil {
arg["gasPrice"] = (*hexutil.Big)(msg.GasPrice)
}
return arg
}

View File

@ -92,7 +92,7 @@ func TestPublicKeyOf(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
require.Equal( require.Equal(
t, t,
"0xe25da6994ea2dc4ac70727e07eca153ae92bf7609db7befb7ebdceaad348f4fc55bbe90abf9501176301db5aa103fc0eb3bc3750272a26c424a10887db2a7ea8", "0x04e25da6994ea2dc4ac70727e07eca153ae92bf7609db7befb7ebdceaad348f4fc55bbe90abf9501176301db5aa103fc0eb3bc3750272a26c424a10887db2a7ea8",
pubKey, pubKey,
) )
} }

View File

@ -1,6 +1,7 @@
package ens package ens
import ( import (
"encoding/hex"
"fmt" "fmt"
"strings" "strings"
@ -40,8 +41,8 @@ func usernameToLabel(username string) [32]byte {
} }
func extractCoordinates(pubkey string) ([32]byte, [32]byte) { func extractCoordinates(pubkey string) ([32]byte, [32]byte) {
x := []byte("0x" + pubkey[4:68]) x, _ := hex.DecodeString(pubkey[4:68])
y := []byte("0x" + pubkey[68:132]) y, _ := hex.DecodeString(pubkey[68:132])
var xByte [32]byte var xByte [32]byte
copy(xByte[:], x) copy(xByte[:], x)