Skip to content

Commit 7470a74

Browse files
authored
🐛 Add debug command (#24)
1 parent cff738e commit 7470a74

File tree

8 files changed

+126
-15
lines changed

8 files changed

+126
-15
lines changed

packages/example/deployments.json

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,24 @@
11
{
22
"kovan": {
33
"dai": {
4-
"txHash": "0xa5395bb2ad241d3a7a1813e9191d208a0b974e8eb4585c8eb346f85da27e3c2e",
5-
"address": "0x2f9ac14463db2B3283aE99FA9158a01968585DDd"
4+
"txHash": "0x7c058a68e08739b173f5acace0e6fa29dd95aafc5601733fef46bfe4de37ca6f",
5+
"address": "0x0a3BDD55AbA03BE21365A164bac541845f2412AF"
66
},
77
"btc": {
8-
"txHash": "0x6e3305488edc15414943574008b5dda95c00057432adeb1e4e0cb9f962de169e",
9-
"address": "0xC05e6f465aaB3d42aC98C9e860275056872311C1"
8+
"txHash": "0x795a6145e6f2fd8574cd0c56fc4f514b826cf61b467abb4c5ee805f1849edd7e",
9+
"address": "0x28562C8c670BdA5AA186156Fff49F07C2Ff0124F"
1010
},
1111
"market": {
12-
"txHash": "0x042584491c4c4323c4ff80807b2d0ebc2259772a51c4df0122a4e8c08a99d098",
13-
"address": "0x945989f49B4Ea0756e97ef1B8fBFE81DD5c9142E"
12+
"txHash": "0xe8bf839c398e01d19b366bf9ac2fbd07c9c142fd2b8de4ca65218c4e4604dfb4",
13+
"address": "0x51Ef1C90C02bE44d8609EAc9A3Fe30b7B907fB9c"
14+
},
15+
"dai_proxy": {
16+
"txHash": "0xe2b80e23d3a90278e0f0e623d74802c00084872e15ad5950480d2f0004c4f6fc",
17+
"address": "0xD6c9fb590c15EA0B8FF016934488459E1578C66c"
18+
},
19+
"btc_proxy": {
20+
"txHash": "0x28e6d21a3e8f224967ba3a7d09c9a1298f81f8cad450085949530826399727a9",
21+
"address": "0x92146cB5fCC0fCA0d1A0E24f28Ebc447D73983E1"
1422
}
1523
}
1624
}

packages/example/src/index.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { contract, createProxy, deploy, runIf } from 'ethereum-mars'
1+
import { contract, createProxy, deploy, runIf, debug } from 'ethereum-mars'
22
import { Market, Token, UpgradeabilityProxy } from '../build/artifacts'
33

44
deploy({}, (deployer) => {
@@ -8,6 +8,8 @@ deploy({}, (deployer) => {
88
const apple = proxy(appleImplementation, 'initialize', [100])
99
const orange = proxy(orangeImplementation, 'initialize', [200])
1010
const market = contract(Market, [apple, orange])
11+
debug('Apple', apple)
12+
debug('Allowances', [apple.allowance(deployer, market), orange.allowance(deployer, market)])
1113
runIf(apple.allowance(deployer, market).equals(0), () => apple.approve(market, 100)).else(() =>
1214
orange.approve(market, 100)
1315
)

packages/mars/src/actions.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ export type Action =
99
| EncodeAction
1010
| StartConditionalAction
1111
| EndConditionalAction
12+
| DebugAction
1213

1314
export interface DeployAction {
1415
type: 'DEPLOY'
@@ -53,3 +54,8 @@ export interface EncodeAction {
5354
params: any[]
5455
resolve: (value: Buffer) => void
5556
}
57+
58+
export interface DebugAction {
59+
type: 'DEBUG'
60+
messages: any[]
61+
}

packages/mars/src/execute/execute.ts

Lines changed: 51 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,15 @@
1-
import { Action, DeployAction, EncodeAction, ReadAction, StartConditionalAction, TransactionAction } from '../actions'
2-
import { Contract, providers, utils } from 'ethers'
3-
import { AbiSymbol, Address, Bytecode, Name } from '../symbols'
1+
import chalk from 'chalk'
2+
import {
3+
Action,
4+
DebugAction,
5+
DeployAction,
6+
EncodeAction,
7+
ReadAction,
8+
StartConditionalAction,
9+
TransactionAction,
10+
} from '../actions'
11+
import { BigNumber, Contract, providers, utils } from 'ethers'
12+
import { AbiSymbol, Address, ArtifactSymbol, Bytecode, Name } from '../symbols'
413
import { Future, resolveBytesLike } from '../values'
514
import { getDeployTx } from './getDeployTx'
615
import { sendTransaction, TransactionOptions } from './sendTransaction'
@@ -49,6 +58,8 @@ async function executeAction(action: Action, options: ExecuteOptions) {
4958
return executeEncode(action)
5059
case 'CONDITIONAL_START':
5160
return executeConditionalStart(action)
61+
case 'DEBUG':
62+
return executeDebug(action)
5263
}
5364
}
5465

@@ -122,13 +133,21 @@ async function executeRead(action: ReadAction, options: ExecuteOptions) {
122133
async function executeTransaction(action: TransactionAction, globalOptions: ExecuteOptions) {
123134
const options = { ...globalOptions, ...action.options }
124135
const params = action.params.map((param) => resolveValue(param))
125-
const { txHash } = await sendTransaction(`${action.name}.${action.method.name}`, options, {
126-
to: resolveValue(action.address),
127-
data: new utils.Interface([action.method]).encodeFunctionData(action.method.name, params),
128-
})
136+
const { txHash } = await sendTransaction(
137+
`${action.name}.${action.method.name}(${printableTransactionParams(params)})`,
138+
options,
139+
{
140+
to: resolveValue(action.address),
141+
data: new utils.Interface([action.method]).encodeFunctionData(action.method.name, params),
142+
}
143+
)
129144
action.resolve(resolveBytesLike(txHash))
130145
}
131146

147+
function printableTransactionParams(params: unknown[]) {
148+
return params.map(printableToString).join(', ')
149+
}
150+
132151
async function executeEncode(action: EncodeAction) {
133152
const params = action.params.map((param) => resolveValue(param))
134153
const result = new utils.Interface([action.method]).encodeFunctionData(action.method.name, params)
@@ -143,3 +162,28 @@ function resolveValue(value: unknown) {
143162
}
144163
return resolved
145164
}
165+
166+
function executeDebug({ messages }: DebugAction) {
167+
console.log(chalk.yellow('🛠', ...messages.map(printableToString)))
168+
}
169+
170+
export function printableToString(data: unknown): string | number | boolean | null | undefined {
171+
const resolved = data instanceof Future ? Future.resolve(data) : data
172+
if (!resolved || typeof resolved !== 'object') {
173+
return resolved
174+
}
175+
if (resolved instanceof BigNumber) {
176+
return resolved.toString()
177+
}
178+
if (ArtifactSymbol in resolved && Address in resolved) {
179+
return `${resolved[ArtifactSymbol][Name]}#${Future.resolve(resolved[Address])}`
180+
}
181+
if (Array.isArray(resolved)) {
182+
return JSON.stringify(resolved.map(printableToString))
183+
}
184+
return JSON.stringify(
185+
Object.fromEntries(Object.entries(resolved).map(([key, value]) => [key, printableToString(value)])),
186+
null,
187+
2
188+
)
189+
}

packages/mars/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,5 @@ export { contract } from './syntax/contract'
55
export { createProxy } from './syntax/createProxy'
66
export { createArtifact, ArtifactFrom } from './syntax/artifact'
77
export { runIf } from './syntax/conditionals'
8+
export { debug } from './syntax/debug'
89
export * from './values'

packages/mars/src/syntax/debug.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import { context } from '../context'
2+
3+
export function debug(...messages: any[]) {
4+
context.ensureEnabled()
5+
6+
context.actions.push({
7+
type: 'DEBUG',
8+
messages,
9+
})
10+
}

packages/mars/test/syntax/debug.ts

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import { expect } from 'chai'
2+
import { printableToString } from '../../src/execute/execute'
3+
import { BigNumber } from 'ethers'
4+
import { testDeploy } from '../utils/testDeploy'
5+
import { contract, Future } from '../../src'
6+
import { SimpleContract } from '../fixtures/exampleArtifacts'
7+
import { Address } from '../../src/symbols'
8+
import fs from 'fs'
9+
10+
describe('Debug', () => {
11+
describe('object conversions', () => {
12+
it('BigNumber', () => {
13+
expect(printableToString(BigNumber.from('123'))).to.equal('123')
14+
})
15+
16+
it('For contracts prints contract solidity name and address', async () => {
17+
const deployed = await testDeploy(() => contract('name', SimpleContract))
18+
const address = Future.resolve(deployed.result[Address])
19+
expect(printableToString(deployed.result)).to.equal(`SimpleContract#${address}`)
20+
fs.unlinkSync('./test/deployments.json')
21+
})
22+
23+
it('Array', () => {
24+
expect(printableToString([BigNumber.from('123'), '321'])).to.deep.equal('["123","321"]')
25+
})
26+
27+
it('Object', () => {
28+
expect(
29+
printableToString({
30+
foo: BigNumber.from('123'),
31+
bar: 'bar',
32+
})
33+
).to.deep.equal('{\n "foo": "123",\n "bar": "bar"\n}')
34+
})
35+
36+
it('Future', async () => {
37+
expect(printableToString(new Future(() => BigNumber.from('123')))).to.equal('123')
38+
})
39+
})
40+
})

tsconfig.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"compilerOptions": {
33
"strict": true,
4-
"target": "ES2017",
4+
"target": "ES2019",
55
"moduleResolution": "node",
66
"resolveJsonModule": true,
77
"esModuleInterop": true,

0 commit comments

Comments
 (0)