Skip to content
This repository was archived by the owner on Nov 9, 2022. It is now read-only.

Commit 870fb47

Browse files
committed
feat: show functions for contracts
1 parent eb1a048 commit 870fb47

File tree

3 files changed

+1242
-464
lines changed

3 files changed

+1242
-464
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@
7171
"react-time-ago": "^3.0.3",
7272
"shallowequal": "^1.1.0",
7373
"styled-components": "^4.1.1",
74-
"web3": "^1.0.0-beta.37",
74+
"web3": "^1.2.9",
7575
"web3-utils": "^1.2.5-rc.0"
7676
}
7777
}

src/components/add-tx.js

Lines changed: 138 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import { Button, Card, Row, Col, Form, Input, InputNumber } from 'antd'
2-
import React, { useState, useCallback } from 'react'
1+
import { Button, Card, Row, Col, Form, Input, InputNumber, Select } from 'antd'
2+
import React, { useState, useCallback, useEffect } from 'react'
33
import styled from 'styled-components'
44

55
import { useDrizzle, useDrizzleState } from '../bootstrap/drizzle-react-hooks'
@@ -78,6 +78,12 @@ const StyledInputNumber = styled(InputNumber)`
7878

7979
const AddTx = Form.create()(({ form }) => {
8080
const [txs, setTxs] = useState([])
81+
// Selected Contract State
82+
const [abi, setContractABI] = useState([])
83+
const [address, setContractAddress] = useState('')
84+
const [methodSelected, setMethodSelected] = useState('')
85+
const [methodInputs, setMethodInputs] = useState([])
86+
8187
const { drizzle, useCacheCall, useCacheSend } = useDrizzle()
8288
const drizzleState = useDrizzleState(drizzleState => ({
8389
balance: drizzle.web3.utils.toBN(
@@ -100,6 +106,13 @@ const AddTx = Form.create()(({ form }) => {
100106
const _newValues = {
101107
...values
102108
}
109+
110+
if (!_newValues.data && methodSelected) {
111+
const contractInstance = new drizzle.web3.eth.Contract(abi, address)
112+
const _data = contractInstance.methods[methodSelected](...methodInputs).encodeABI()
113+
_newValues.data = _data
114+
}
115+
103116
_newValues.amount = drizzle.web3.utils.toWei(String(Number(_newValues.amount)))
104117
txs.push(_newValues)
105118
setTxs(
@@ -112,6 +125,13 @@ const AddTx = Form.create()(({ form }) => {
112125
})
113126
}
114127

128+
const resetContractState = () => {
129+
setContractABI('')
130+
setContractAddress('')
131+
setMethodSelected('')
132+
setMethodInputs([])
133+
}
134+
115135
const removeTxFromSet = (itemIndex) => {
116136
const txsCopy = [...txs]
117137
txsCopy.splice(itemIndex, 1)
@@ -135,6 +155,46 @@ const AddTx = Form.create()(({ form }) => {
135155
}
136156
}
137157

158+
const getContractABI = async (a) => {
159+
if (a !== address) {
160+
const network = await drizzle.web3.eth.net.getId()
161+
let uri
162+
switch (network) {
163+
case 1:
164+
uri = `https://api.etherscan.io/api?module=contract&action=getabi&address=${a}`
165+
break
166+
case 42:
167+
uri = `https://api-kovan.etherscan.io/api?module=contract&action=getabi&address=${a}`
168+
break
169+
default:
170+
break
171+
}
172+
if (uri) {
173+
const abiQuery = await fetch(
174+
uri
175+
).then(response => response.json())
176+
if (abiQuery.status === "1") {
177+
setContractABI(JSON.parse(abiQuery.result))
178+
setContractAddress(a)
179+
} else {
180+
setContractABI('')
181+
setContractAddress('')
182+
}
183+
}
184+
}
185+
}
186+
187+
let contractInstance
188+
if (address && abi.length) {
189+
contractInstance = new drizzle.web3.eth.Contract(abi, address)
190+
}
191+
192+
let methodInputsList
193+
if (methodSelected) {
194+
methodInputsList = abi.filter(a => a.name === methodSelected)[0].inputs
195+
196+
}
197+
138198
return (
139199
<Form
140200
onSubmit={e => {
@@ -184,7 +244,7 @@ const AddTx = Form.create()(({ form }) => {
184244
}
185245
]
186246
})(
187-
<StyledInput type="text" placeholder={'To Address'} />
247+
<StyledInput type="text" placeholder={'To Address'} onChange={(e) => getContractABI(e.target.value)}/>
188248
)}
189249
</Form.Item>
190250
<Form.Item>
@@ -239,22 +299,81 @@ const AddTx = Form.create()(({ form }) => {
239299
/>
240300
)}
241301
</Form.Item>
242-
<Form.Item>
243-
{form.getFieldDecorator('data', {
244-
rules: [
245-
{
246-
message: "Data required (use 0x for no data)",
247-
validator: (_, _value, callback) => {
248-
if (!_value || _value.length < 1)
249-
return callback(true)
250-
callback()
251-
}
252-
}
253-
]
254-
})(
255-
<StyledTextArea type="text" placeholder={'Data'} />
256-
)}
257-
</Form.Item>
302+
{
303+
contractInstance ? (
304+
<Form.Item>
305+
<Input.Group>
306+
<Form.Item
307+
name={['method', 'methodName']}
308+
noStyle
309+
>
310+
<Select placeholder="Select Function" style={{width: '100%'}} onChange={(value) => {
311+
setMethodSelected(value)
312+
}
313+
}>
314+
{
315+
abi.map((abiItem, i) => {
316+
if (!abiItem.constant) {
317+
return (
318+
<Select.Option
319+
value={abiItem.name}
320+
>
321+
{abiItem.name}
322+
</Select.Option>
323+
)
324+
}
325+
})
326+
}
327+
</Select>
328+
</Form.Item>
329+
{
330+
methodSelected ? (
331+
<div>
332+
{
333+
methodInputsList.map((field, i) => {
334+
return (
335+
<Form.Item
336+
name={['method', field.name]}
337+
>
338+
<Input
339+
key={field.name}
340+
type="text"
341+
placeholder={field.name}
342+
onChange={(val) => {
343+
const _inputs = [...methodInputs]
344+
_inputs.splice(i, 1, val.target.value)
345+
setMethodInputs(_inputs)
346+
}}
347+
/>
348+
</Form.Item>
349+
)
350+
})
351+
}
352+
</div>
353+
)
354+
: ''
355+
}
356+
</Input.Group>
357+
</Form.Item>
358+
) : (
359+
<Form.Item>
360+
{form.getFieldDecorator('data', {
361+
rules: [
362+
{
363+
message: "Data required (use 0x for no data)",
364+
validator: (_, _value, callback) => {
365+
if (!_value || _value.length < 1)
366+
return callback(true)
367+
callback()
368+
}
369+
}
370+
]
371+
})(
372+
<StyledTextArea type="text" placeholder={'Data'} />
373+
)}
374+
</Form.Item>
375+
)
376+
}
258377
</Col>
259378
</Row>
260379
</BackgrounCard>

0 commit comments

Comments
 (0)