go-ethereum/XDCx/token.go
Daniel Liu b0063d39b9 accounts/abi: ABI explicit difference between Unpack and UnpackIntoInterface (#21091)
* accounts/abi: refactored abi.Unpack

* accounts/abi/bind: fixed error

* accounts/abi/bind: modified template

* accounts/abi/bind: added ToStruct for conversion

* accounts/abi: reenabled tests

* accounts/abi: fixed tests

* accounts/abi: fixed tests for packing/unpacking

* accounts/abi: fixed tests

* accounts/abi: added more logic to ToStruct

* accounts/abi/bind: fixed template

* accounts/abi/bind: fixed ToStruct conversion

* accounts/abi/: removed unused code

* accounts/abi: updated template

* accounts/abi: refactored unused code

* contracts/checkpointoracle: updated contracts to sol ^0.6.0

* accounts/abi: refactored reflection logic

* accounts/abi: less code duplication in Unpack*

* accounts/abi: fixed rebasing bug

* fix a few typos in comments

* rebase on master

Co-authored-by: Guillaume Ballet <gballet@gmail.com>
2025-01-24 16:18:30 +08:00

77 lines
2.4 KiB
Go

package XDCx
import (
"math/big"
"strings"
"github.com/XinFinOrg/XDPoSChain"
"github.com/XinFinOrg/XDPoSChain/accounts/abi"
"github.com/XinFinOrg/XDPoSChain/common"
"github.com/XinFinOrg/XDPoSChain/consensus"
"github.com/XinFinOrg/XDPoSChain/contracts/XDCx/contract"
"github.com/XinFinOrg/XDPoSChain/core"
"github.com/XinFinOrg/XDPoSChain/core/state"
"github.com/XinFinOrg/XDPoSChain/log"
)
// 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.UnpackIntoInterface(&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 && tokenDecimal != nil {
return tokenDecimal, nil
}
if tokenAddr == common.XDCNativeAddressBinary {
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)
}