Skip to content

Commit 79e5acb

Browse files
committed
Import ABI for unknown contract
1 parent 491e0e4 commit 79e5acb

File tree

14 files changed

+280
-61
lines changed

14 files changed

+280
-61
lines changed

internal/common/conv/argument.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import (
99
"github.com/ethereum/go-ethereum/common"
1010
)
1111

12-
func Unpack(t abi.Type, s string) (any, error) {
12+
func UnpackArgument(t abi.Type, s string) (any, error) {
1313
switch t.T {
1414
case abi.StringTy:
1515
return s, nil

internal/service/contract.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package service
22

33
import (
44
"fmt"
5+
"strings"
56

67
"github.com/ethereum/go-ethereum/accounts/abi"
78
"github.com/ethereum/go-ethereum/log"
@@ -13,6 +14,10 @@ type Contract struct {
1314
source string
1415
}
1516

17+
func (c *Contract) HasABI() bool {
18+
return c.abi != nil
19+
}
20+
1621
func (c *Contract) GetABI() *abi.ABI {
1722
return c.abi
1823
}
@@ -34,3 +39,15 @@ func (c *Contract) Call(method string, args ...any) ([]any, error) {
3439
log.Debug("Try to call contract", "method", method, "args", args)
3540
return c.service.provider.CallContract(c.address, c.abi, method, args...)
3641
}
42+
43+
func (c *Contract) ImportABI(abiJson string) error {
44+
log.Debug("Try to parse abi json", "json", abiJson)
45+
parsedAbi, err := abi.JSON(strings.NewReader(abiJson))
46+
if err != nil {
47+
return err
48+
}
49+
50+
c.abi = &parsedAbi
51+
52+
return nil
53+
}

internal/service/service.go

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,10 @@ func (s *Service) transactionsByTraverse(addr common.Address) (common.Transactio
168168

169169
txns := make([]common.Transaction, 0)
170170
for _, t := range candidates {
171-
if t.From().String() == addr.String() || t.To().String() == addr.String() {
171+
if t.From().String() == addr.String() {
172+
txns = append(txns, t)
173+
}
174+
if t.To() != nil && t.To().String() == addr.String() {
172175
txns = append(txns, t)
173176
}
174177
}
@@ -241,7 +244,13 @@ func (s *Service) ToContract(account *Account) (*Contract, error) {
241244
return nil, fmt.Errorf("Address %s is not a contract account", account.address.Hex())
242245
}
243246

244-
// FIXME: support local chain
247+
if s.GetNetwork().NetType() == TypeDevnet {
248+
// in case of devnet, return a contract skeleton
249+
return &Contract{
250+
Account: account,
251+
}, nil
252+
}
253+
245254
source, abi, err := s.esclient.GetSourceCode(account.address)
246255
if err != nil {
247256
return nil, err

internal/view/account.go

Lines changed: 52 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,9 @@ type Account struct {
1818
accountInfo *AccountInfo
1919
transactionList *TransactionList
2020
methodCall *MethodCallDialog
21+
importABI *ImportABIDialog
2122
account *serv.Account
23+
contract *serv.Contract
2224
}
2325

2426
type AccountInfo struct {
@@ -50,6 +52,7 @@ func (a *Account) SetAccount(account *serv.Account) {
5052
if account.IsContract() {
5153
contract, err := account.AsContract()
5254
if err == nil {
55+
a.contract = contract
5356
a.methodCall.SetContract(contract)
5457
} else {
5558
log.Error("Cannot upgrade account to contract", "account", account.GetAddress(), "error", err)
@@ -80,6 +83,10 @@ func (a *Account) initLayout() {
8083
methodCall := NewMethodCallDialog(a.app)
8184
a.methodCall = methodCall
8285

86+
// ImportABIDialog
87+
importABI := NewImportABIDialog(a.app)
88+
a.importABI = importABI
89+
8390
// Transactions
8491
transactions := NewTransactionList(a.app, true)
8592
transactions.SetTitleColor(s.SecondaryTitleColor)
@@ -99,16 +106,7 @@ func (a *Account) initLayout() {
99106
}
100107

101108
func (a *Account) initKeymap() {
102-
keymaps := a.KeyMaps()
103-
a.SetInputCapture(func(event *tcell.EventKey) *tcell.EventKey {
104-
handler, ok := keymaps.FindHandler(util.AsKey(event))
105-
if ok {
106-
handler(event)
107-
return nil
108-
} else {
109-
return event
110-
}
111-
})
109+
InitKeymap(a, a.app)
112110
}
113111

114112
func (a *Account) KeyMaps() util.KeyMaps {
@@ -120,7 +118,14 @@ func (a *Account) KeyMaps() util.KeyMaps {
120118
Shortcut: "C",
121119
Description: "Call Contract",
122120
Handler: func(*tcell.EventKey) {
123-
a.ShowMethodCallDialog()
121+
// FIXME: don't show "Call Contract" for wallet account
122+
if a.account.IsContract() {
123+
if a.methodCall.contract.HasABI() {
124+
a.ShowMethodCallDialog()
125+
} else {
126+
a.ShowImportABIDialog()
127+
}
128+
}
124129
},
125130
})
126131

@@ -152,6 +157,27 @@ func (a *Account) HideMethodCallDialog() {
152157
a.app.SetFocus(a)
153158
}
154159

160+
func (a *Account) ShowImportABIDialog() {
161+
log.Debug("Show importABI dialog")
162+
163+
if !a.importABI.IsDisplay() {
164+
a.importABI.Clear()
165+
a.importABI.Display(true)
166+
}
167+
168+
a.app.SetFocus(a.importABI)
169+
}
170+
171+
func (a *Account) HideImportABIDialog() {
172+
log.Debug("Hide importABI dialog")
173+
174+
if a.importABI.IsDisplay() {
175+
a.importABI.Display(false)
176+
}
177+
178+
a.app.SetFocus(a)
179+
}
180+
155181
func (a *Account) refresh() {
156182
addr := a.account.GetAddress()
157183
a.accountInfo.address.SetText(addr.Hex())
@@ -180,20 +206,29 @@ func (a *Account) HasFocus() bool {
180206
if a.methodCall.HasFocus() {
181207
return true
182208
}
209+
if a.importABI.HasFocus() {
210+
return true
211+
}
183212
return a.Flex.HasFocus()
184213
}
185214

186215
// InputHandler implements tview.Primitive
187216
func (a *Account) InputHandler() func(event *tcell.EventKey, setFocus func(p tview.Primitive)) {
188217
return func(event *tcell.EventKey, setFocus func(p tview.Primitive)) {
189-
if a.Flex.HasFocus() {
190-
if handler := a.Flex.InputHandler(); handler != nil {
218+
if a.methodCall.HasFocus() {
219+
if handler := a.methodCall.InputHandler(); handler != nil {
191220
handler(event, setFocus)
192221
return
193222
}
194223
}
195-
if a.methodCall.HasFocus() {
196-
if handler := a.methodCall.InputHandler(); handler != nil {
224+
if a.importABI.HasFocus() {
225+
if handler := a.importABI.InputHandler(); handler != nil {
226+
handler(event, setFocus)
227+
return
228+
}
229+
}
230+
if a.Flex.HasFocus() {
231+
if handler := a.Flex.InputHandler(); handler != nil {
197232
handler(event, setFocus)
198233
return
199234
}
@@ -205,10 +240,12 @@ func (a *Account) InputHandler() func(event *tcell.EventKey, setFocus func(p tvi
205240
func (a *Account) SetRect(x int, y int, width int, height int) {
206241
a.Flex.SetRect(x, y, width, height)
207242
a.methodCall.SetRect(a.GetInnerRect())
243+
a.importABI.SetRect(a.GetInnerRect())
208244
}
209245

210246
// Draw implements tview.Primitive
211247
func (a *Account) Draw(screen tcell.Screen) {
212248
a.Flex.Draw(screen)
213249
a.methodCall.Draw(screen)
250+
a.importABI.Draw(screen)
214251
}

internal/view/contract.go

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ func (d *MethodCallDialog) initLayout() {
4545
// method list
4646
methods := tview.NewTable()
4747
methods.SetBorder(true)
48-
methods.SetBorderColor(s.MethNameBorderColor)
48+
methods.SetBorderColor(s.DialogBorderColor)
4949
methods.SetTitle(style.Padding("Method"))
5050
methods.SetSelectable(true, false)
5151
methods.SetSelectionChangedFunc(func(row, column int) {
@@ -73,7 +73,7 @@ func (d *MethodCallDialog) initLayout() {
7373
// arguments form
7474
args := tview.NewForm()
7575
args.SetBorder(true)
76-
args.SetBorderColor(s.MethArgsBorderColor)
76+
args.SetBorderColor(s.DialogBorderColor)
7777
args.SetTitle(style.Padding("Arguments"))
7878
args.SetLabelColor(s.InputFieldLableColor)
7979
args.SetFieldBackgroundColor(s.InputFieldBgColor)
@@ -133,9 +133,12 @@ func (d *MethodCallDialog) Clear() {
133133
}
134134

135135
func (d *MethodCallDialog) refresh() {
136+
d.methods.Clear()
136137
d.args.Clear(true)
137138
d.result.Clear()
138-
d.showMethodList()
139+
if d.contract.HasABI() {
140+
d.showMethodList()
141+
}
139142
}
140143

141144
func (d *MethodCallDialog) showMethodList() {
@@ -199,7 +202,7 @@ func (d *MethodCallDialog) callMethod() {
199202
for i := 0; i < d.args.GetFormItemCount(); i++ {
200203
item := d.args.GetFormItem(i).(*tview.InputField)
201204
arg := method.Inputs[i]
202-
val, err := conv.Unpack(arg.Type, item.GetText())
205+
val, err := conv.UnpackArgument(arg.Type, item.GetText())
203206
if err == nil {
204207
args = append(args, val)
205208
} else {

internal/view/format/string.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ func TruncateText(text string, size int) string {
1616

1717
func NormalizeReceiverAddress(receiver *common.Address) string {
1818
if receiver == nil {
19-
return "0x"
19+
return "0x0"
2020
} else {
2121
return receiver.Hex()
2222
}

internal/view/helper.go

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,36 @@ import (
55

66
"github.com/dyng/ramen/internal/common"
77
serv "github.com/dyng/ramen/internal/service"
8+
"github.com/dyng/ramen/internal/view/util"
9+
"github.com/gdamore/tcell/v2"
10+
"github.com/rivo/tview"
811
)
912

13+
type KeymapPrimitive interface {
14+
SetInputCapture(capture func(event *tcell.EventKey) *tcell.EventKey) *tview.Box
15+
16+
KeyMaps() util.KeyMaps
17+
}
18+
19+
func InitKeymap(p KeymapPrimitive, app *App) {
20+
keymaps := p.KeyMaps()
21+
p.SetInputCapture(func(event *tcell.EventKey) *tcell.EventKey {
22+
// do not capture characters for InputField and TextArea
23+
switch app.GetFocus().(type) {
24+
case *tview.InputField, *tview.TextArea:
25+
return event
26+
}
27+
28+
handler, ok := keymaps.FindHandler(util.AsKey(event))
29+
if ok {
30+
handler(event)
31+
return nil
32+
} else {
33+
return event
34+
}
35+
})
36+
}
37+
1038
func Inc(i *int) int {
1139
t := *i
1240
*i++

0 commit comments

Comments
 (0)