Refactor ethCall method to rpcCall
This commit is contained in:
parent
059086cd3d
commit
76664cdbf3
@ -77,7 +77,7 @@ func (b *BaseChain) EthereumTypeGetStakingPoolsData(addrDesc AddressDescriptor)
|
|||||||
return nil, errors.New("not supported")
|
return nil, errors.New("not supported")
|
||||||
}
|
}
|
||||||
|
|
||||||
// EthereumTypeEthCall calls eth_call with given data and to address
|
// EthereumTypeRpcCall calls eth_call with given data and to address
|
||||||
func (b *BaseChain) EthereumTypeEthCall(data, to, from string) (string, error) {
|
func (b *BaseChain) EthereumTypeRpcCall(data, to, from string) (string, error) {
|
||||||
return "", errors.New("not supported")
|
return "", errors.New("not supported")
|
||||||
}
|
}
|
||||||
|
|||||||
@ -342,10 +342,10 @@ func (c *blockChainWithMetrics) EthereumTypeGetStakingPoolsData(addrDesc bchain.
|
|||||||
return c.b.EthereumTypeGetStakingPoolsData(addrDesc)
|
return c.b.EthereumTypeGetStakingPoolsData(addrDesc)
|
||||||
}
|
}
|
||||||
|
|
||||||
// EthereumTypeEthCall calls eth_call with given data and to address
|
// EthereumTypeRpcCall calls eth_call with given data and to address
|
||||||
func (c *blockChainWithMetrics) EthereumTypeEthCall(data, to, from string) (v string, err error) {
|
func (c *blockChainWithMetrics) EthereumTypeRpcCall(data, to, from string) (v string, err error) {
|
||||||
defer func(s time.Time) { c.observeRPCLatency("EthereumTypeEthCall", s, err) }(time.Now())
|
defer func(s time.Time) { c.observeRPCLatency("EthereumTypeRpcCall", s, err) }(time.Now())
|
||||||
return c.b.EthereumTypeEthCall(data, to, from)
|
return c.b.EthereumTypeRpcCall(data, to, from)
|
||||||
}
|
}
|
||||||
|
|
||||||
type mempoolWithMetrics struct {
|
type mempoolWithMetrics struct {
|
||||||
|
|||||||
@ -273,8 +273,8 @@ func contractGetTransfersFromTx(tx *bchain.RpcTransaction) (bchain.TokenTransfer
|
|||||||
return r, nil
|
return r, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// EthereumTypeEthCall calls eth_call with given data and to address
|
// EthereumTypeRpcCall calls eth_call with given data and to address
|
||||||
func (b *EthereumRPC) EthereumTypeEthCall(data, to, from string) (string, error) {
|
func (b *EthereumRPC) EthereumTypeRpcCall(data, to, from string) (string, error) {
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), b.Timeout)
|
ctx, cancel := context.WithTimeout(context.Background(), b.Timeout)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
var r string
|
var r string
|
||||||
@ -294,7 +294,7 @@ func (b *EthereumRPC) EthereumTypeEthCall(data, to, from string) (string, error)
|
|||||||
|
|
||||||
func (b *EthereumRPC) fetchContractInfo(address string) (*bchain.ContractInfo, error) {
|
func (b *EthereumRPC) fetchContractInfo(address string) (*bchain.ContractInfo, error) {
|
||||||
var contract bchain.ContractInfo
|
var contract bchain.ContractInfo
|
||||||
data, err := b.EthereumTypeEthCall(contractNameSignature, address, "")
|
data, err := b.EthereumTypeRpcCall(contractNameSignature, address, "")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// ignore the error from the eth_call - since geth v1.9.15 they changed the behavior
|
// ignore the error from the eth_call - since geth v1.9.15 they changed the behavior
|
||||||
// and returning error "execution reverted" for some non contract addresses
|
// and returning error "execution reverted" for some non contract addresses
|
||||||
@ -305,14 +305,14 @@ func (b *EthereumRPC) fetchContractInfo(address string) (*bchain.ContractInfo, e
|
|||||||
}
|
}
|
||||||
name := strings.TrimSpace(parseSimpleStringProperty(data))
|
name := strings.TrimSpace(parseSimpleStringProperty(data))
|
||||||
if name != "" {
|
if name != "" {
|
||||||
data, err = b.EthereumTypeEthCall(contractSymbolSignature, address, "")
|
data, err = b.EthereumTypeRpcCall(contractSymbolSignature, address, "")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// glog.Warning(errors.Annotatef(err, "Contract SymbolSignature %v", address))
|
// glog.Warning(errors.Annotatef(err, "Contract SymbolSignature %v", address))
|
||||||
return nil, nil
|
return nil, nil
|
||||||
// return nil, errors.Annotatef(err, "erc20SymbolSignature %v", address)
|
// return nil, errors.Annotatef(err, "erc20SymbolSignature %v", address)
|
||||||
}
|
}
|
||||||
symbol := strings.TrimSpace(parseSimpleStringProperty(data))
|
symbol := strings.TrimSpace(parseSimpleStringProperty(data))
|
||||||
data, _ = b.EthereumTypeEthCall(contractDecimalsSignature, address, "")
|
data, _ = b.EthereumTypeRpcCall(contractDecimalsSignature, address, "")
|
||||||
// if err != nil {
|
// if err != nil {
|
||||||
// glog.Warning(errors.Annotatef(err, "Contract DecimalsSignature %v", address))
|
// glog.Warning(errors.Annotatef(err, "Contract DecimalsSignature %v", address))
|
||||||
// // return nil, errors.Annotatef(err, "erc20DecimalsSignature %v", address)
|
// // return nil, errors.Annotatef(err, "erc20DecimalsSignature %v", address)
|
||||||
@ -345,7 +345,7 @@ func (b *EthereumRPC) EthereumTypeGetErc20ContractBalance(addrDesc, contractDesc
|
|||||||
addr := hexutil.Encode(addrDesc)[2:]
|
addr := hexutil.Encode(addrDesc)[2:]
|
||||||
contract := hexutil.Encode(contractDesc)
|
contract := hexutil.Encode(contractDesc)
|
||||||
req := contractBalanceOfSignature + "0000000000000000000000000000000000000000000000000000000000000000"[len(addr):] + addr
|
req := contractBalanceOfSignature + "0000000000000000000000000000000000000000000000000000000000000000"[len(addr):] + addr
|
||||||
data, err := b.EthereumTypeEthCall(req, contract, "")
|
data, err := b.EthereumTypeRpcCall(req, contract, "")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -369,7 +369,7 @@ func (b *EthereumRPC) GetTokenURI(contractDesc bchain.AddressDescriptor, tokenID
|
|||||||
}
|
}
|
||||||
// try ERC721 tokenURI method and ERC1155 uri method
|
// try ERC721 tokenURI method and ERC1155 uri method
|
||||||
for _, method := range []string{erc721TokenURIMethodSignature, erc1155URIMethodSignature} {
|
for _, method := range []string{erc721TokenURIMethodSignature, erc1155URIMethodSignature} {
|
||||||
data, err := b.EthereumTypeEthCall(method+id, address, "")
|
data, err := b.EthereumTypeRpcCall(method+id, address, "")
|
||||||
if err == nil && data != "" {
|
if err == nil && data != "" {
|
||||||
uri := parseSimpleStringProperty(data)
|
uri := parseSimpleStringProperty(data)
|
||||||
// try to sanitize the URI returned from the contract
|
// try to sanitize the URI returned from the contract
|
||||||
|
|||||||
@ -61,7 +61,7 @@ func isZeroBigInt(b *big.Int) bool {
|
|||||||
|
|
||||||
func (b *EthereumRPC) everstakeBalanceTypeContractCall(signature, addr, contract string) (string, error) {
|
func (b *EthereumRPC) everstakeBalanceTypeContractCall(signature, addr, contract string) (string, error) {
|
||||||
req := signature + "0000000000000000000000000000000000000000000000000000000000000000"[len(addr):] + addr
|
req := signature + "0000000000000000000000000000000000000000000000000000000000000000"[len(addr):] + addr
|
||||||
return b.EthereumTypeEthCall(req, contract, "")
|
return b.EthereumTypeRpcCall(req, contract, "")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *EthereumRPC) everstakeContractCallSimpleNumeric(signature, addr, contract string) (*big.Int, error) {
|
func (b *EthereumRPC) everstakeContractCallSimpleNumeric(signature, addr, contract string) (*big.Int, error) {
|
||||||
|
|||||||
@ -335,7 +335,7 @@ type BlockChain interface {
|
|||||||
EthereumTypeGetErc20ContractBalance(addrDesc, contractDesc AddressDescriptor) (*big.Int, error)
|
EthereumTypeGetErc20ContractBalance(addrDesc, contractDesc AddressDescriptor) (*big.Int, error)
|
||||||
EthereumTypeGetSupportedStakingPools() []string
|
EthereumTypeGetSupportedStakingPools() []string
|
||||||
EthereumTypeGetStakingPoolsData(addrDesc AddressDescriptor) ([]StakingPoolData, error)
|
EthereumTypeGetStakingPoolsData(addrDesc AddressDescriptor) ([]StakingPoolData, error)
|
||||||
EthereumTypeEthCall(data, to, from string) (string, error)
|
EthereumTypeRpcCall(data, to, from string) (string, error)
|
||||||
GetTokenURI(contractDesc AddressDescriptor, tokenID *big.Int) (string, error)
|
GetTokenURI(contractDesc AddressDescriptor, tokenID *big.Int) (string, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -448,12 +448,12 @@ export interface WsMempoolFiltersReq {
|
|||||||
fromTimestamp: number;
|
fromTimestamp: number;
|
||||||
M?: number;
|
M?: number;
|
||||||
}
|
}
|
||||||
export interface WsEthCallReq {
|
export interface WsRpcCallReq {
|
||||||
from?: string;
|
from?: string;
|
||||||
to: string;
|
to: string;
|
||||||
data: string;
|
data: string;
|
||||||
}
|
}
|
||||||
export interface WsEthCallRes {
|
export interface WsRpcCallRes {
|
||||||
data: string;
|
data: string;
|
||||||
}
|
}
|
||||||
export interface MempoolTxidFilterEntries {
|
export interface MempoolTxidFilterEntries {
|
||||||
|
|||||||
@ -60,8 +60,8 @@ func main() {
|
|||||||
t.Add(server.WsFiatRatesForTimestampsReq{})
|
t.Add(server.WsFiatRatesForTimestampsReq{})
|
||||||
t.Add(server.WsFiatRatesTickersListReq{})
|
t.Add(server.WsFiatRatesTickersListReq{})
|
||||||
t.Add(server.WsMempoolFiltersReq{})
|
t.Add(server.WsMempoolFiltersReq{})
|
||||||
t.Add(server.WsEthCallReq{})
|
t.Add(server.WsRpcCallReq{})
|
||||||
t.Add(server.WsEthCallRes{})
|
t.Add(server.WsRpcCallRes{})
|
||||||
t.Add(bchain.MempoolTxidFilterEntries{})
|
t.Add(bchain.MempoolTxidFilterEntries{})
|
||||||
|
|
||||||
err := t.ConvertToFile("blockbook-api.ts")
|
err := t.ConvertToFile("blockbook-api.ts")
|
||||||
|
|||||||
@ -8,4 +8,4 @@ Some behavior of Blockbook can be modified by environment variables. The variabl
|
|||||||
|
|
||||||
- `COINGECKO_API_KEY` or `<coin shortcut>_COINGECKO_API_KEY` - API key for making requests to CoinGecko in the paid tier.
|
- `COINGECKO_API_KEY` or `<coin shortcut>_COINGECKO_API_KEY` - API key for making requests to CoinGecko in the paid tier.
|
||||||
|
|
||||||
- `<coin shortcut>_ALLOWED_ETH_CALL_CONTRACTS` - Contract addresses for which `ethCall` websocket requests can be made, as a comma-separated list. If omitted, `ethCall` is enabled for all addresses.
|
- `<coin shortcut>_ALLOWED_RPC_CALL_TO` - Addresses to which `rpcCall` websocket requests can be made, as a comma-separated list. If omitted, `rpcCall` is enabled for all addresses.
|
||||||
|
|||||||
@ -143,10 +143,10 @@ var websocketTestsEthereumType = []websocketTest{
|
|||||||
want: `{"id":"0","data":{"name":"Fakecoin","shortcut":"FAKE","network":"FAKE","decimals":18,"version":"unknown","bestHeight":4321001,"bestHash":"0x2b57e15e93a0ed197417a34c2498b7187df79099572c04a6b6e6ff418f74e6ee","block0Hash":"","testnet":true,"backend":{"version":"001001","subversion":"/Fakecoin:0.0.1/"}}}`,
|
want: `{"id":"0","data":{"name":"Fakecoin","shortcut":"FAKE","network":"FAKE","decimals":18,"version":"unknown","bestHeight":4321001,"bestHash":"0x2b57e15e93a0ed197417a34c2498b7187df79099572c04a6b6e6ff418f74e6ee","block0Hash":"","testnet":true,"backend":{"version":"001001","subversion":"/Fakecoin:0.0.1/"}}}`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "websocket ethCall",
|
name: "websocket rpcCall",
|
||||||
req: websocketReq{
|
req: websocketReq{
|
||||||
Method: "ethCall",
|
Method: "rpcCall",
|
||||||
Params: WsEthCallReq{
|
Params: WsRpcCallReq{
|
||||||
To: "0xcdA9FC258358EcaA88845f19Af595e908bb7EfE9",
|
To: "0xcdA9FC258358EcaA88845f19Af595e908bb7EfE9",
|
||||||
Data: "0x4567",
|
Data: "0x4567",
|
||||||
},
|
},
|
||||||
|
|||||||
@ -1485,10 +1485,10 @@ var websocketTestsBitcoinType = []websocketTest{
|
|||||||
want: `{"id":"43","data":{"P":0,"M":1,"zeroedKey":false,"blockFilter":""}}`,
|
want: `{"id":"43","data":{"P":0,"M":1,"zeroedKey":false,"blockFilter":""}}`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "websocket ethCall",
|
name: "websocket rpcCall",
|
||||||
req: websocketReq{
|
req: websocketReq{
|
||||||
Method: "ethCall",
|
Method: "rpcCall",
|
||||||
Params: WsEthCallReq{
|
Params: WsRpcCallReq{
|
||||||
To: "0x123",
|
To: "0x123",
|
||||||
Data: "0x456",
|
Data: "0x456",
|
||||||
},
|
},
|
||||||
|
|||||||
@ -71,7 +71,7 @@ type WebsocketServer struct {
|
|||||||
fiatRatesSubscriptions map[string]map[*websocketChannel]string
|
fiatRatesSubscriptions map[string]map[*websocketChannel]string
|
||||||
fiatRatesTokenSubscriptions map[*websocketChannel][]string
|
fiatRatesTokenSubscriptions map[*websocketChannel][]string
|
||||||
fiatRatesSubscriptionsLock sync.Mutex
|
fiatRatesSubscriptionsLock sync.Mutex
|
||||||
allowedEthCallContracts map[string]struct{}
|
allowedRpcCallTo map[string]struct{}
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewWebsocketServer creates new websocket interface to blockbook and returns its handle
|
// NewWebsocketServer creates new websocket interface to blockbook and returns its handle
|
||||||
@ -107,13 +107,13 @@ func NewWebsocketServer(db *db.RocksDB, chain bchain.BlockChain, mempool bchain.
|
|||||||
fiatRatesSubscriptions: make(map[string]map[*websocketChannel]string),
|
fiatRatesSubscriptions: make(map[string]map[*websocketChannel]string),
|
||||||
fiatRatesTokenSubscriptions: make(map[*websocketChannel][]string),
|
fiatRatesTokenSubscriptions: make(map[*websocketChannel][]string),
|
||||||
}
|
}
|
||||||
envEthCall := os.Getenv(strings.ToUpper(is.CoinShortcut) + "_ALLOWED_ETH_CALL_CONTRACTS")
|
envRpcCall := os.Getenv(strings.ToUpper(is.CoinShortcut) + "_ALLOWED_RPC_CALL_TO")
|
||||||
if envEthCall != "" {
|
if envRpcCall != "" {
|
||||||
s.allowedEthCallContracts = make(map[string]struct{})
|
s.allowedRpcCallTo = make(map[string]struct{})
|
||||||
for _, c := range strings.Split(envEthCall, ",") {
|
for _, c := range strings.Split(envRpcCall, ",") {
|
||||||
s.allowedEthCallContracts[strings.ToLower(c)] = struct{}{}
|
s.allowedRpcCallTo[strings.ToLower(c)] = struct{}{}
|
||||||
}
|
}
|
||||||
glog.Info("Support of ethCall for these contracts: ", envEthCall)
|
glog.Info("Support of rpcCall for these contracts: ", envRpcCall)
|
||||||
}
|
}
|
||||||
return s, nil
|
return s, nil
|
||||||
}
|
}
|
||||||
@ -401,11 +401,11 @@ var requestHandlers = map[string]func(*WebsocketServer, *websocketChannel, *WsRe
|
|||||||
}
|
}
|
||||||
return
|
return
|
||||||
},
|
},
|
||||||
"ethCall": func(s *WebsocketServer, c *websocketChannel, req *WsReq) (rv interface{}, err error) {
|
"rpcCall": func(s *WebsocketServer, c *websocketChannel, req *WsReq) (rv interface{}, err error) {
|
||||||
r := WsEthCallReq{}
|
r := WsRpcCallReq{}
|
||||||
err = json.Unmarshal(req.Params, &r)
|
err = json.Unmarshal(req.Params, &r)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
rv, err = s.ethCall(&r)
|
rv, err = s.rpcCall(&r)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
},
|
},
|
||||||
@ -765,18 +765,18 @@ func (s *WebsocketServer) getBlockFiltersBatch(r *WsBlockFiltersBatchReq) (res i
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *WebsocketServer) ethCall(r *WsEthCallReq) (*WsEthCallRes, error) {
|
func (s *WebsocketServer) rpcCall(r *WsRpcCallReq) (*WsRpcCallRes, error) {
|
||||||
if s.allowedEthCallContracts != nil {
|
if s.allowedRpcCallTo != nil {
|
||||||
_, ok := s.allowedEthCallContracts[strings.ToLower(r.To)]
|
_, ok := s.allowedRpcCallTo[strings.ToLower(r.To)]
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, errors.New("Not supported")
|
return nil, errors.New("Not supported")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
data, err := s.chain.EthereumTypeEthCall(r.Data, r.To, r.From)
|
data, err := s.chain.EthereumTypeRpcCall(r.Data, r.To, r.From)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return &WsEthCallRes{Data: data}, nil
|
return &WsRpcCallRes{Data: data}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type subscriptionResponse struct {
|
type subscriptionResponse struct {
|
||||||
|
|||||||
@ -139,12 +139,12 @@ type WsFiatRatesTickersListReq struct {
|
|||||||
Token string `json:"token,omitempty"`
|
Token string `json:"token,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type WsEthCallReq struct {
|
type WsRpcCallReq struct {
|
||||||
From string `json:"from,omitempty"`
|
From string `json:"from,omitempty"`
|
||||||
To string `json:"to"`
|
To string `json:"to"`
|
||||||
Data string `json:"data"`
|
Data string `json:"data"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type WsEthCallRes struct {
|
type WsRpcCallRes struct {
|
||||||
Data string `json:"data"`
|
Data string `json:"data"`
|
||||||
}
|
}
|
||||||
|
|||||||
@ -536,18 +536,18 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function ethCall() {
|
function rpcCall() {
|
||||||
const from = document.getElementById('ethCallFrom').value.trim();
|
const from = document.getElementById('rpcCallFrom').value.trim();
|
||||||
const to = document.getElementById('ethCallTo').value.trim();
|
const to = document.getElementById('rpcCallTo').value.trim();
|
||||||
const data = document.getElementById('ethCallData').value.trim();
|
const data = document.getElementById('rpcCallData').value.trim();
|
||||||
const method = 'ethCall';
|
const method = 'rpcCall';
|
||||||
const params = {
|
const params = {
|
||||||
from,
|
from,
|
||||||
to,
|
to,
|
||||||
data,
|
data,
|
||||||
};
|
};
|
||||||
send(method, params, function (result) {
|
send(method, params, function (result) {
|
||||||
document.getElementById('ethCallResult').innerText = JSON.stringify(
|
document.getElementById('rpcCallResult').innerText = JSON.stringify(
|
||||||
result,
|
result,
|
||||||
).replace(/,/g, ', ');
|
).replace(/,/g, ', ');
|
||||||
});
|
});
|
||||||
@ -1118,8 +1118,8 @@
|
|||||||
<input
|
<input
|
||||||
class="btn btn-secondary"
|
class="btn btn-secondary"
|
||||||
type="button"
|
type="button"
|
||||||
value="ethCall"
|
value="rpcCall"
|
||||||
onclick="ethCall()"
|
onclick="rpcCall()"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-10">
|
<div class="col-10">
|
||||||
@ -1127,7 +1127,7 @@
|
|||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
class="form-control"
|
class="form-control"
|
||||||
id="ethCallFrom"
|
id="rpcCallFrom"
|
||||||
style="width: 60%; margin-right: 5px"
|
style="width: 60%; margin-right: 5px"
|
||||||
value=""
|
value=""
|
||||||
placeholder="from"
|
placeholder="from"
|
||||||
@ -1135,7 +1135,7 @@
|
|||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
class="form-control"
|
class="form-control"
|
||||||
id="ethCallTo"
|
id="rpcCallTo"
|
||||||
style="width: 60%; margin-right: 5px"
|
style="width: 60%; margin-right: 5px"
|
||||||
value="0x624087dd1904ab122a32878ce9e933c7071f53b9"
|
value="0x624087dd1904ab122a32878ce9e933c7071f53b9"
|
||||||
placeholder="to"
|
placeholder="to"
|
||||||
@ -1145,14 +1145,14 @@
|
|||||||
class="form-control"
|
class="form-control"
|
||||||
placeholder="data"
|
placeholder="data"
|
||||||
style="width: 100%"
|
style="width: 100%"
|
||||||
id="ethCallData"
|
id="rpcCallData"
|
||||||
value="0x2fec7966000000000000000000000000ce66a9577f4e2589c1d1547b75b7a2b0807ce0ed"
|
value="0x2fec7966000000000000000000000000ce66a9577f4e2589c1d1547b75b7a2b0807ce0ed"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col" id="ethCallResult"></div>
|
<div class="col" id="rpcCallResult"></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col">
|
<div class="col">
|
||||||
|
|||||||
@ -134,8 +134,8 @@ func (c *fakeBlockChainEthereumType) EthereumTypeGetErc20ContractBalance(addrDes
|
|||||||
return big.NewInt(1000000000 + int64(addrDesc[0])*1000 + int64(contractDesc[0])), nil
|
return big.NewInt(1000000000 + int64(addrDesc[0])*1000 + int64(contractDesc[0])), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// EthereumTypeEthCall calls eth_call with given data and to address
|
// EthereumTypeRpcCall calls eth_call with given data and to address
|
||||||
func (c *fakeBlockChainEthereumType) EthereumTypeEthCall(data, to, from string) (string, error) {
|
func (c *fakeBlockChainEthereumType) EthereumTypeRpcCall(data, to, from string) (string, error) {
|
||||||
return data + "abcd", nil
|
return data + "abcd", nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user