Skip to content

Commit f87d8ab

Browse files
authored
Merge pull request #161 from psy2848048/private/bryan/evm-address-to-xpla
Implemented some simple auth query methods
2 parents 1ce188a + f7b9f5b commit f87d8ab

File tree

9 files changed

+476
-7
lines changed

9 files changed

+476
-7
lines changed

app/keepers/keepers.go

+1
Original file line numberDiff line numberDiff line change
@@ -588,6 +588,7 @@ func NewAppKeeper(
588588
distrkeeper.NewMsgServerImpl(appKeepers.DistrKeeper),
589589
wasmkeeper.NewMsgServerImpl(&appKeepers.WasmKeeper),
590590
appKeepers.WasmKeeper,
591+
appKeepers.AccountKeeper,
591592
)
592593

593594
return appKeepers

precompile/auth/IAuth.abi

+91
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
[
2+
{
3+
"inputs": [
4+
{
5+
"internalType": "address",
6+
"name": "evmAddress",
7+
"type": "address"
8+
}
9+
],
10+
"name": "account",
11+
"outputs": [
12+
{
13+
"internalType": "string",
14+
"name": "stringAddress",
15+
"type": "string"
16+
}
17+
],
18+
"stateMutability": "view",
19+
"type": "function"
20+
},
21+
{
22+
"inputs": [
23+
{
24+
"internalType": "address",
25+
"name": "evmAddress",
26+
"type": "address"
27+
}
28+
],
29+
"name": "addressBytesToString",
30+
"outputs": [
31+
{
32+
"internalType": "string",
33+
"name": "stringAddress",
34+
"type": "string"
35+
}
36+
],
37+
"stateMutability": "view",
38+
"type": "function"
39+
},
40+
{
41+
"inputs": [
42+
{
43+
"internalType": "string",
44+
"name": "stringAddress",
45+
"type": "string"
46+
}
47+
],
48+
"name": "addressStringToBytes",
49+
"outputs": [
50+
{
51+
"internalType": "address",
52+
"name": "byteAddress",
53+
"type": "address"
54+
}
55+
],
56+
"stateMutability": "view",
57+
"type": "function"
58+
},
59+
{
60+
"inputs": [],
61+
"name": "bech32Prefix",
62+
"outputs": [
63+
{
64+
"internalType": "string",
65+
"name": "prefix",
66+
"type": "string"
67+
}
68+
],
69+
"stateMutability": "view",
70+
"type": "function"
71+
},
72+
{
73+
"inputs": [
74+
{
75+
"internalType": "string",
76+
"name": "name",
77+
"type": "string"
78+
}
79+
],
80+
"name": "moduleAccountByName",
81+
"outputs": [
82+
{
83+
"internalType": "string",
84+
"name": "stringAddress",
85+
"type": "string"
86+
}
87+
],
88+
"stateMutability": "view",
89+
"type": "function"
90+
}
91+
]

precompile/auth/IAuth.sol

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// SPDX-License-Identifier: MIT
2+
pragma solidity ^0.8.0;
3+
4+
address constant AUTH_PRECOMPILE_ADDRESS = 0x1000000000000000000000000000000000000005;
5+
6+
IAuth constant AUTH_CONTRACT = IAuth(
7+
AUTH_PRECOMPILE_ADDRESS
8+
);
9+
10+
interface IAuth {
11+
// function accountAddressByID(uint accountId) external view returns (string calldata stringAddress);
12+
// function accounts(address evmAddress) external view returns (string[] calldata stringAddress);
13+
function account(address evmAddress) external view returns (string calldata stringAddress);
14+
// function params() external view returns (...);
15+
// function moduleAccounts() external view returns (string[] calldata stringAddresses);
16+
function moduleAccountByName(string calldata name) external view returns (string calldata stringAddress);
17+
function bech32Prefix() external view returns (string calldata prefix);
18+
function addressBytesToString(address evmAddress) external view returns (string calldata stringAddress);
19+
function addressStringToBytes(string calldata stringAddress) external view returns (address byteAddress);
20+
// function accountInfo(address evmAddress) external view returns (...);
21+
}

precompile/auth/auth.go

+140
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
package auth
2+
3+
import (
4+
"embed"
5+
"errors"
6+
7+
"github.com/ethereum/go-ethereum/accounts/abi"
8+
"github.com/ethereum/go-ethereum/common"
9+
ethcommon "github.com/ethereum/go-ethereum/common"
10+
"github.com/ethereum/go-ethereum/core/vm"
11+
12+
sdk "github.com/cosmos/cosmos-sdk/types"
13+
14+
"github.com/xpladev/ethermint/x/evm/statedb"
15+
16+
"github.com/xpladev/xpla/precompile/util"
17+
xplatypes "github.com/xpladev/xpla/types"
18+
)
19+
20+
var _ vm.PrecompiledContract = PrecompiledAuth{}
21+
22+
var (
23+
Address = common.HexToAddress(hexAddress)
24+
ABI = abi.ABI{}
25+
26+
//go:embed IAuth.abi
27+
abiFS embed.FS
28+
)
29+
30+
type PrecompiledAuth struct {
31+
ak AccountKeeper
32+
}
33+
34+
func init() {
35+
var err error
36+
ABI, err = util.LoadABI(abiFS, abiFile)
37+
if err != nil {
38+
panic(err)
39+
}
40+
}
41+
42+
func NewPrecompiledAuth(ak AccountKeeper) PrecompiledAuth {
43+
return PrecompiledAuth{ak}
44+
}
45+
46+
func (p PrecompiledAuth) RequiredGas(input []byte) uint64 {
47+
// Implement the method as needed
48+
return 0
49+
}
50+
51+
func (p PrecompiledAuth) Run(evm *vm.EVM, input []byte) ([]byte, error) {
52+
method, argsBz := util.SplitInput(input)
53+
54+
abiMethod, err := ABI.MethodById(method)
55+
if err != nil {
56+
return nil, err
57+
}
58+
59+
args, err := abiMethod.Inputs.Unpack(argsBz)
60+
if err != nil {
61+
return nil, err
62+
}
63+
64+
ctx := evm.StateDB.(*statedb.StateDB).GetContext()
65+
66+
switch MethodAuth(abiMethod.Name) {
67+
case Account:
68+
return p.account(ctx, abiMethod, args)
69+
case ModuleAccountByName:
70+
return p.moduleAccountByName(ctx, abiMethod, args)
71+
case Bech32Prefix:
72+
return p.bech32Prefix(ctx, abiMethod, args)
73+
case AddressBytesToString:
74+
return p.addressBytesToString(ctx, abiMethod, args)
75+
case AddressStringToBytes:
76+
return p.addressStringToBytes(ctx, abiMethod, args)
77+
default:
78+
return nil, errors.New("method not found")
79+
}
80+
}
81+
82+
func (p PrecompiledAuth) account(ctx sdk.Context, method *abi.Method, args []interface{}) ([]byte, error) {
83+
address, err := util.GetAccAddress(args[0])
84+
if err != nil {
85+
return nil, err
86+
}
87+
88+
var strAddress string
89+
if p.ak.HasAccount(ctx, address) {
90+
// address: contract or address
91+
account := p.ak.GetAccount(ctx, address)
92+
strAddress = account.GetAddress().String()
93+
} else {
94+
// cannot query
95+
strAddress = ""
96+
}
97+
98+
return method.Outputs.Pack(strAddress)
99+
}
100+
101+
func (p PrecompiledAuth) moduleAccountByName(ctx sdk.Context, method *abi.Method, args []interface{}) ([]byte, error) {
102+
moduleName, err := util.GetString(args[0])
103+
if err != nil {
104+
return nil, err
105+
}
106+
107+
account := p.ak.GetModuleAccount(ctx, moduleName)
108+
if account == nil {
109+
return method.Outputs.Pack("")
110+
} else {
111+
return method.Outputs.Pack(account.GetAddress().String())
112+
}
113+
}
114+
115+
func (p PrecompiledAuth) bech32Prefix(_ sdk.Context, method *abi.Method, _ []interface{}) ([]byte, error) {
116+
return method.Outputs.Pack(xplatypes.Bech32MainPrefix)
117+
}
118+
119+
func (p PrecompiledAuth) addressBytesToString(_ sdk.Context, method *abi.Method, args []interface{}) ([]byte, error) {
120+
address, err := util.GetAccAddress(args[0])
121+
if err != nil {
122+
return nil, err
123+
}
124+
125+
return method.Outputs.Pack(address.String())
126+
}
127+
128+
func (p PrecompiledAuth) addressStringToBytes(_ sdk.Context, method *abi.Method, args []interface{}) ([]byte, error) {
129+
stringAddress, err := util.GetString(args[0])
130+
if err != nil {
131+
return nil, err
132+
}
133+
134+
byteAddress, err := sdk.AccAddressFromBech32(stringAddress)
135+
if err != nil {
136+
return nil, err
137+
}
138+
139+
return method.Outputs.Pack(ethcommon.BytesToAddress(byteAddress.Bytes()))
140+
}

precompile/auth/const.go

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package auth
2+
3+
const (
4+
hexAddress = "0x1000000000000000000000000000000000000005"
5+
abiFile = "IAuth.abi"
6+
)
7+
8+
type MethodAuth string
9+
10+
const (
11+
Account MethodAuth = "account"
12+
ModuleAccountByName MethodAuth = "moduleAccountByName"
13+
Bech32Prefix MethodAuth = "bech32Prefix"
14+
AddressBytesToString MethodAuth = "addressBytesToString"
15+
AddressStringToBytes MethodAuth = "addressStringToBytes"
16+
)

precompile/auth/expected_keepers.go

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package auth
2+
3+
import (
4+
"context"
5+
6+
sdk "github.com/cosmos/cosmos-sdk/types"
7+
)
8+
9+
type AccountKeeper interface {
10+
GetAccount(ctx context.Context, addr sdk.AccAddress) (acc sdk.AccountI)
11+
HasAccount(ctx context.Context, addr sdk.AccAddress) bool
12+
GetModuleAccount(ctx context.Context, moduleName string) sdk.ModuleAccountI
13+
}

precompile/precompiles.go

+3-1
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,17 @@ package precompile
33
import (
44
"github.com/ethereum/go-ethereum/core/vm"
55

6+
pauth "github.com/xpladev/xpla/precompile/auth"
67
pbank "github.com/xpladev/xpla/precompile/bank"
78
pdistribution "github.com/xpladev/xpla/precompile/distribution"
89
pstaking "github.com/xpladev/xpla/precompile/staking"
910
pwasm "github.com/xpladev/xpla/precompile/wasm"
1011
)
1112

12-
func RegistPrecompiledContract(ak pwasm.AccountKeeper, bk pbank.BankKeeper, sk pstaking.StakingKeeper, dk pdistribution.DistributionKeeper, wms pwasm.WasmMsgServer, wk pwasm.WasmKeeper) {
13+
func RegistPrecompiledContract(ak pwasm.AccountKeeper, bk pbank.BankKeeper, sk pstaking.StakingKeeper, dk pdistribution.DistributionKeeper, wms pwasm.WasmMsgServer, wk pwasm.WasmKeeper, authAk pauth.AccountKeeper) {
1314
vm.PrecompiledContractsBerlin[pbank.Address] = pbank.NewPrecompiledBank(bk)
1415
vm.PrecompiledContractsBerlin[pstaking.Address] = pstaking.NewPrecompiledStaking(sk)
1516
vm.PrecompiledContractsBerlin[pdistribution.Address] = pdistribution.NewPrecompiledDistribution(dk)
1617
vm.PrecompiledContractsBerlin[pwasm.Address] = pwasm.NewPrecompiledWasm(ak, wms, wk)
18+
vm.PrecompiledContractsBerlin[pauth.Address] = pauth.NewPrecompiledAuth(authAk)
1719
}

0 commit comments

Comments
 (0)