diff --git a/docs/api/docs.go b/docs/api/docs.go
index 976e34e..9283951 100644
--- a/docs/api/docs.go
+++ b/docs/api/docs.go
@@ -1548,6 +1548,9 @@ const docTemplate = `{
"deployer": {
"type": "string"
},
+ "deposit_balance": {
+ "type": "number"
+ },
"eip_standard": {
"type": "string"
},
diff --git a/docs/api/swagger.json b/docs/api/swagger.json
index 98bef7b..bd8b833 100644
--- a/docs/api/swagger.json
+++ b/docs/api/swagger.json
@@ -1537,6 +1537,9 @@
"deployer": {
"type": "string"
},
+ "deposit_balance": {
+ "type": "number"
+ },
"eip_standard": {
"type": "string"
},
diff --git a/docs/api/swagger.yaml b/docs/api/swagger.yaml
index 8709858..fc543c8 100644
--- a/docs/api/swagger.yaml
+++ b/docs/api/swagger.yaml
@@ -87,6 +87,8 @@ definitions:
type: string
deployer:
type: string
+ deposit_balance:
+ type: number
eip_standard:
type: string
event_identifiers:
diff --git a/plugins/evm/dao/contract.go b/plugins/evm/dao/contract.go
index 9b3f9a1..73b81dc 100644
--- a/plugins/evm/dao/contract.go
+++ b/plugins/evm/dao/contract.go
@@ -9,6 +9,8 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/crypto"
"github.com/itering/subscan/model"
+ "github.com/itering/subscan/pkg/go-web3/complex/types"
+ "github.com/itering/subscan/pkg/go-web3/dto"
evmABI "github.com/itering/subscan/plugins/evm/abi"
evmContract "github.com/itering/subscan/plugins/evm/contract"
"github.com/itering/subscan/plugins/evm/feature/delegateProxy"
@@ -54,10 +56,11 @@ type Contract struct {
Precompile uint `json:"precompile"`
CompileSettings datatypes.JSON `json:"CompileSettings"`
- EipStandard string `json:"eip_standard" gorm:"size:100"`
- ProxyImplementation string `json:"proxy_implementation" gorm:"size:64"`
- ConstructorArguments string `json:"constructor_arguments" gorm:"type:string"`
- DeployCodeHash string `json:"deploy_code_hash" gorm:"size:70;index:deploy_code_hash;default:'';not null"`
+ EipStandard string `json:"eip_standard" gorm:"size:100"`
+ ProxyImplementation string `json:"proxy_implementation" gorm:"size:64"`
+ ConstructorArguments string `json:"constructor_arguments" gorm:"type:string"`
+ DeployCodeHash string `json:"deploy_code_hash" gorm:"size:70;index:deploy_code_hash;default:'';not null"`
+ DepositBalance decimal.Decimal `json:"deposit_balance" gorm:"-"`
}
type ContractSampleJson struct {
@@ -285,12 +288,34 @@ func ContractsByAddr(ctx context.Context, contracts string) (contract *Contract)
contract = &dbContract
}
+ if balance, ok := latestEvmContractDepositBalance(ctx, contract.Address); ok {
+ contract.DepositBalance = balance
+ }
+
if len(contract.Abi) > 0 && contract.Abi.String() != "null" {
contract.EventIdentifiers = findEventIdentifiers(ctx, contract.Abi)
}
return
}
+func latestEvmContractDepositBalance(ctx context.Context, contractAddress string) (decimal.Decimal, bool) {
+ if web3.RPC == nil || web3.RPC.Eth == nil {
+ return decimal.Zero, false
+ }
+ result, err := web3.RPC.Eth.Call(ctx, &dto.TransactionParameters{
+ To: contractAddress,
+ Data: types.ComplexString("0xc399ec88"), // getDeposit()
+ })
+ if err != nil || result == nil {
+ return decimal.Zero, false
+ }
+ balance, err := result.ToBigInt()
+ if err != nil || balance == nil {
+ return decimal.Zero, false
+ }
+ return decimal.NewFromBigInt(balance, 0), true
+}
+
func backfillContractFromRuntimeCode(ctx context.Context, contractAddress string) *Contract {
if web3.RPC == nil || web3.RPC.Eth == nil {
return nil
diff --git a/plugins/evm/http/contract_e2e_test.go b/plugins/evm/http/contract_e2e_test.go
new file mode 100644
index 0000000..f31f5f4
--- /dev/null
+++ b/plugins/evm/http/contract_e2e_test.go
@@ -0,0 +1,52 @@
+package http
+
+import (
+ "context"
+ "encoding/json"
+ "net/http"
+ "net/http/httptest"
+ "strings"
+ "testing"
+
+ "github.com/itering/subscan/plugins/evm/dao"
+ "github.com/shopspring/decimal"
+ "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
+)
+
+type contractRouteMockServer struct {
+ MockServer
+}
+
+func (m contractRouteMockServer) ContractsByAddr(_ context.Context, address string) *dao.Contract {
+ return &dao.Contract{
+ Address: address,
+ VerifyStatus: "perfect",
+ DepositBalance: decimal.NewFromInt(2),
+ }
+}
+
+func TestContractRouteReturnsDepositBalance(t *testing.T) {
+ originalSrv := srv
+ srv = contractRouteMockServer{}
+ t.Cleanup(func() { srv = originalSrv })
+
+ request := httptest.NewRequest(
+ http.MethodPost,
+ "/api/plugin/evm/contract",
+ strings.NewReader(`{"address":"0x0000000000000000000000000000000000000002"}`),
+ )
+ recorder := httptest.NewRecorder()
+ require.NoError(t, contractHandle(recorder, request))
+ require.Equal(t, http.StatusOK, recorder.Code)
+
+ var response struct {
+ Code int `json:"code"`
+ Data struct {
+ DepositBalance decimal.Decimal `json:"deposit_balance"`
+ } `json:"data"`
+ }
+ require.NoError(t, json.Unmarshal(recorder.Body.Bytes(), &response))
+ require.Zero(t, response.Code)
+ assert.True(t, response.Data.DepositBalance.Equal(decimal.NewFromInt(2)))
+}
diff --git a/ui-react/src/pages/contract/[id].tsx b/ui-react/src/pages/contract/[id].tsx
index a8ab165..ae33aaf 100644
--- a/ui-react/src/pages/contract/[id].tsx
+++ b/ui-react/src/pages/contract/[id].tsx
@@ -74,6 +74,13 @@ export default function Page() {