forked from ethereum/go-ethereum
-
Notifications
You must be signed in to change notification settings - Fork 59
/
token.go
78 lines (70 loc) · 2.38 KB
/
token.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
package XDCx
import (
"math/big"
"strings"
"github.com/XinFinOrg/XDPoSChain/contracts/XDCx/contract"
"github.com/XinFinOrg/XDPoSChain/core"
"github.com/XinFinOrg/XDPoSChain/log"
"github.com/XinFinOrg/XDPoSChain"
"github.com/XinFinOrg/XDPoSChain/accounts/abi"
"github.com/XinFinOrg/XDPoSChain/common"
"github.com/XinFinOrg/XDPoSChain/consensus"
"github.com/XinFinOrg/XDPoSChain/core/state"
)
// GetTokenAbi return token abi
func GetTokenAbi() (*abi.ABI, error) {
contractABI, err := abi.JSON(strings.NewReader(contract.TRC21ABI))
if err != nil {
return nil, err
}
return &contractABI, nil
}
// RunContract run smart contract
func RunContract(chain consensus.ChainContext, statedb *state.StateDB, contractAddr common.Address, abi *abi.ABI, method string, args ...interface{}) (interface{}, error) {
input, err := abi.Pack(method)
if err != nil {
return nil, err
}
fakeCaller := common.HexToAddress("0x0000000000000000000000000000000000000001")
msg := XDPoSChain.CallMsg{To: &contractAddr, Data: input, From: fakeCaller}
result, err := core.CallContractWithState(msg, chain, statedb)
if err != nil {
return nil, err
}
var unpackResult interface{}
err = abi.Unpack(&unpackResult, method, result)
if err != nil {
return nil, err
}
return unpackResult, nil
}
func (XDCx *XDCX) GetTokenDecimal(chain consensus.ChainContext, statedb *state.StateDB, tokenAddr common.Address) (*big.Int, error) {
if tokenDecimal, ok := XDCx.tokenDecimalCache.Get(tokenAddr); ok {
return tokenDecimal.(*big.Int), nil
}
if tokenAddr.String() == common.XDCNativeAddress {
XDCx.tokenDecimalCache.Add(tokenAddr, common.BasePrice)
return common.BasePrice, nil
}
var decimals uint8
defer func() {
log.Debug("GetTokenDecimal from ", "relayerSMC", common.RelayerRegistrationSMC, "tokenAddr", tokenAddr.Hex(), "decimals", decimals)
}()
contractABI, err := GetTokenAbi()
if err != nil {
return nil, err
}
stateCopy := statedb.Copy()
result, err := RunContract(chain, stateCopy, tokenAddr, contractABI, "decimals")
if err != nil {
return nil, err
}
decimals = result.(uint8)
tokenDecimal := new(big.Int).SetUint64(0).Exp(big.NewInt(10), big.NewInt(int64(decimals)), nil)
XDCx.tokenDecimalCache.Add(tokenAddr, tokenDecimal)
return tokenDecimal, nil
}
// FIXME: using in unit tests only
func (XDCx *XDCX) SetTokenDecimal(token common.Address, decimal *big.Int) {
XDCx.tokenDecimalCache.Add(token, decimal)
}