jsir 1.1.9 → 1.2.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/cmd/ooa.js +38 -7
- package/ethWeb.js +62 -37
- package/index.js +6 -2
- package/package.json +1 -1
- package/sol.js +7 -9
package/cmd/ooa.js
CHANGED
|
@@ -346,13 +346,26 @@ function _nextLine(callback, preStr, hidden, resolve) {
|
|
|
346
346
|
input: process.stdin,
|
|
347
347
|
output: process.stdout
|
|
348
348
|
})
|
|
349
|
+
_rl.on("SIGINT", async () => {
|
|
350
|
+
if (_noAppendNextLine) {
|
|
351
|
+
process.exit(0);
|
|
352
|
+
} else {
|
|
353
|
+
_haveWrapperInput = true;
|
|
354
|
+
_rl.clearLine(0)
|
|
355
|
+
nextLine();
|
|
356
|
+
}
|
|
357
|
+
});
|
|
349
358
|
}
|
|
350
359
|
_haveStartRead = true
|
|
351
360
|
_haveWrapperInput = false
|
|
352
361
|
|
|
353
362
|
_rl._writeToOutput = function _writeToOutput(stringToWrite){
|
|
354
363
|
if(hidden && stringToWrite.indexOf("\n") === -1 && stringToWrite !== promitStr){
|
|
355
|
-
|
|
364
|
+
if (stringToWrite.indexOf(promitStr) === -1) {
|
|
365
|
+
_rl.output.write("*");
|
|
366
|
+
} else {
|
|
367
|
+
_rl.output.write(promitStr + stringToWrite.replace(promitStr, '').replace(/[\s\S]/g, '*'));
|
|
368
|
+
}
|
|
356
369
|
} else {
|
|
357
370
|
_rl.output.write(stringToWrite);
|
|
358
371
|
}
|
|
@@ -380,10 +393,9 @@ function _nextLine(callback, preStr, hidden, resolve) {
|
|
|
380
393
|
let promitStr = (preStr
|
|
381
394
|
|| ((callback && callback !== wrapperInput) ? "-> ":"")
|
|
382
395
|
|| [Object.values(global.$tips).filter(i => String(i)).join(','), repoTip].filter(i => i).join('-') + `> `)
|
|
383
|
-
|
|
384
|
-
|
|
396
|
+
promitStr = '\x1B[32m' + promitStr + '\x1B[39m'
|
|
397
|
+
_rl.setPrompt(promitStr);
|
|
385
398
|
_rl.prompt()
|
|
386
|
-
process.stdout.write('\x1B[39m')
|
|
387
399
|
}
|
|
388
400
|
|
|
389
401
|
async function nextText(callback, preStr, hidden) {
|
|
@@ -487,10 +499,18 @@ function hisToCmdMap() {
|
|
|
487
499
|
_cmdMap = cmdMap
|
|
488
500
|
}
|
|
489
501
|
|
|
490
|
-
function listCmd() {
|
|
502
|
+
function listCmd(onlyRepo = false) {
|
|
503
|
+
let jsLibDir;
|
|
504
|
+
if (onlyRepo) {
|
|
505
|
+
jsLibDir = trim(getConfig("jsLibSource"))
|
|
506
|
+
if (!(jsLibDir && _fs.existsSync(jsLibDir))) {
|
|
507
|
+
jsLibDir = null;
|
|
508
|
+
warn('require config.jsLibSource')
|
|
509
|
+
}
|
|
510
|
+
}
|
|
491
511
|
let newCmdMap = {}
|
|
492
512
|
let items = Object.values(_cmdMap)
|
|
493
|
-
.filter(i => _fs.existsSync(_home + "/" + i))
|
|
513
|
+
.filter(i => _fs.existsSync(_home + "/" + i) && (!jsLibDir || _fs.existsSync(jsLibDir + "/" + i)))
|
|
494
514
|
.sort((a,b) => {
|
|
495
515
|
return String(_types[a.split(/\s+/)[0]]) >= String(_types[b.split(/\s+/)[0]]) ? 1:-1
|
|
496
516
|
})
|
|
@@ -856,6 +876,11 @@ async function dealKeyword(str, strs, fstr, ostr) {
|
|
|
856
876
|
listCmd()
|
|
857
877
|
} else if (fstr === 'f') {
|
|
858
878
|
await fileLine(trim(ostr.join(' ')))
|
|
879
|
+
} else if (fstr === '%') {
|
|
880
|
+
listCmd(true)
|
|
881
|
+
} else if (fstr === 'q') {
|
|
882
|
+
console.log("Bye!")
|
|
883
|
+
process.exit(0)
|
|
859
884
|
} else {
|
|
860
885
|
await save(strs)
|
|
861
886
|
}
|
|
@@ -1008,6 +1033,7 @@ async function runCmd(str) {
|
|
|
1008
1033
|
let args = enrichArgs(str, text)
|
|
1009
1034
|
let argDef = getArgDef(text)
|
|
1010
1035
|
let argNames = Object.keys(argDef)
|
|
1036
|
+
let exactArg = {}
|
|
1011
1037
|
for (let i = 0; i<args.length; i++) {
|
|
1012
1038
|
let arg = args[i]
|
|
1013
1039
|
let pair = arg.split('=', 2).map(i => trim(i))
|
|
@@ -1021,10 +1047,14 @@ async function runCmd(str) {
|
|
|
1021
1047
|
if (argDef.hasOwnProperty(pair[0])) {
|
|
1022
1048
|
args[i] = argVal
|
|
1023
1049
|
delete args[argNames[i]]
|
|
1024
|
-
|
|
1050
|
+
exactArg[pair[0]] = argVal
|
|
1025
1051
|
}
|
|
1026
1052
|
}
|
|
1053
|
+
for (let key of Object.keys(exactArg)) {
|
|
1054
|
+
args[key] = exactArg[key]
|
|
1055
|
+
}
|
|
1027
1056
|
|
|
1057
|
+
delete args['[ParseError]']
|
|
1028
1058
|
let exit = false
|
|
1029
1059
|
for(let name of argNames) {
|
|
1030
1060
|
if (name.startsWith("_")) {
|
|
@@ -1101,6 +1131,7 @@ function getArgDef(text) {
|
|
|
1101
1131
|
argDef = eval(`(${exeStr || '{}'})`) || {}
|
|
1102
1132
|
} catch (e) {
|
|
1103
1133
|
$log(e.stack)
|
|
1134
|
+
argDef['[ParseError]'] = e.stack.split('\n')[0]
|
|
1104
1135
|
}
|
|
1105
1136
|
if (typeof argDef !== 'object') {
|
|
1106
1137
|
argDef = {}
|
package/ethWeb.js
CHANGED
|
@@ -154,7 +154,11 @@ function initRootWallet(mnemonic) {
|
|
|
154
154
|
getWallet(i) {
|
|
155
155
|
i = String(i)
|
|
156
156
|
if (!wallets[i]) {
|
|
157
|
-
|
|
157
|
+
if (/^\d+$/.test(i)) {
|
|
158
|
+
wallets[i] = ethers.Wallet.fromMnemonic(mnemonic, `m/44\'/60\'/0\'/0/${i}`)
|
|
159
|
+
} else {
|
|
160
|
+
wallets[i] = new ethers.Wallet(i);
|
|
161
|
+
}
|
|
158
162
|
}
|
|
159
163
|
return wallets[i]
|
|
160
164
|
},
|
|
@@ -187,9 +191,24 @@ async function initSender(web3, wallet, froms, resetNum) {
|
|
|
187
191
|
senderNonce[aIndex] = Number(await web3.eth.getTransactionCount(walletGet(wallet, aIndex).address)) -1
|
|
188
192
|
}
|
|
189
193
|
|
|
190
|
-
let sender = (txObject) => {
|
|
194
|
+
let sender = async (txObject) => {
|
|
191
195
|
let aIndex = froms[randomInt(froms.length) - 1]
|
|
192
196
|
let adInfo = walletGet(wallet, aIndex)
|
|
197
|
+
|
|
198
|
+
if (!(txObject.gasLimit || txObject.gas)) {
|
|
199
|
+
try {
|
|
200
|
+
let gas = await web3.eth.estimateGas({
|
|
201
|
+
from: adInfo.address,
|
|
202
|
+
to: txObject.to,
|
|
203
|
+
value: txObject.value,
|
|
204
|
+
data: txObject.data
|
|
205
|
+
})
|
|
206
|
+
txObject.gasLimit = gas + 10000;
|
|
207
|
+
} catch (e) {
|
|
208
|
+
return [Promise.reject(e), {}, aIndex]
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
|
|
193
212
|
if (senderBlock[aIndex]) {
|
|
194
213
|
return []
|
|
195
214
|
}
|
|
@@ -243,6 +262,21 @@ async function initSenderWithKeys(web3, privateKeys, resetNum) {
|
|
|
243
262
|
let sender = async (txObject) => {
|
|
244
263
|
let key = privateKeys[randomInt(privateKeys.length) - 1]
|
|
245
264
|
let adds = keyMap[key]
|
|
265
|
+
|
|
266
|
+
if (!(txObject.gasLimit || txObject.gas)) {
|
|
267
|
+
try {
|
|
268
|
+
let gas = await web3.eth.estimateGas({
|
|
269
|
+
from: adds,
|
|
270
|
+
to: txObject.to,
|
|
271
|
+
value: txObject.value,
|
|
272
|
+
data: txObject.data
|
|
273
|
+
})
|
|
274
|
+
txObject.gasLimit = gas + 10000;
|
|
275
|
+
} catch (e) {
|
|
276
|
+
return [Promise.reject(e), {}, adds]
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
|
|
246
280
|
if (senderBlock[adds]) {
|
|
247
281
|
return []
|
|
248
282
|
}
|
|
@@ -288,7 +322,7 @@ function txnSign(txObject, privateKey) {
|
|
|
288
322
|
let params = {
|
|
289
323
|
nonce: web3.utils.toHex(txObject.nonce),
|
|
290
324
|
gasPrice: web3.utils.toHex(txObject.gasPrice),
|
|
291
|
-
gasLimit: web3.utils.toHex(txObject.gasLimit),
|
|
325
|
+
gasLimit: web3.utils.toHex(txObject.gasLimit || txObject.gas),
|
|
292
326
|
to: txObject.to,
|
|
293
327
|
value: web3.utils.toHex(txObject.value),
|
|
294
328
|
data: txObject.data
|
|
@@ -381,16 +415,8 @@ async function tokenMap(address, web3) {
|
|
|
381
415
|
if (!address) {
|
|
382
416
|
return {name: '本币', decimals: 18, symbol: '本币'}
|
|
383
417
|
}
|
|
384
|
-
web3 = web3 || global.web3;
|
|
385
|
-
let chainId = global.chainId || await web3.getChainId()
|
|
386
|
-
if (!tokenMapCache[chainId]) {
|
|
387
|
-
tokenMapCache[chainId] = {}
|
|
388
|
-
}
|
|
389
|
-
let chainMap = tokenMapCache[chainId]
|
|
390
418
|
address = '0x' + address.toLowerCase().replace(/^0x/, '')
|
|
391
|
-
|
|
392
|
-
await getTokenMap([address], web3)
|
|
393
|
-
}
|
|
419
|
+
let chainMap = await getTokenMap([address], web3)
|
|
394
420
|
|
|
395
421
|
if (chainMap[address]) {
|
|
396
422
|
let decimals = chainMap[address].decimals
|
|
@@ -485,6 +511,20 @@ function getPairAmtNoFee(a, b, baseAmt) {
|
|
|
485
511
|
}
|
|
486
512
|
|
|
487
513
|
let tokenMapLoaded = {}
|
|
514
|
+
async function saveTokenMap(web3) {
|
|
515
|
+
web3 = web3 || global.web3;
|
|
516
|
+
let chainId = global.chainId || await web3.getChainId()
|
|
517
|
+
if (!tokenMapCache[chainId]) {
|
|
518
|
+
tokenMapCache[chainId] = {}
|
|
519
|
+
}
|
|
520
|
+
let chainMap = tokenMapCache[chainId]
|
|
521
|
+
let tokenMapFile = `tokenMap_${chainId}`
|
|
522
|
+
if (!tokenMapLoaded[chainId]) {
|
|
523
|
+
Object.assign(chainMap, objDataFile(tokenMapFile))
|
|
524
|
+
tokenMapLoaded[chainId] = true
|
|
525
|
+
}
|
|
526
|
+
objDataFile(tokenMapFile, () => chainMap);
|
|
527
|
+
}
|
|
488
528
|
async function getTokenMap(tokens, web3, batchNum, asyncNum) {
|
|
489
529
|
web3 = web3 || global.web3;
|
|
490
530
|
let chainId = global.chainId || await web3.getChainId()
|
|
@@ -785,7 +825,7 @@ async function ethWrite(sender, address, {data, abi, method, args, gasPrice, gas
|
|
|
785
825
|
let avgGasPrice = await cacheFn('getGasPrice', async () => await web3.eth.getGasPrice(), 1000 * 5)
|
|
786
826
|
let txObject = {
|
|
787
827
|
gasPrice: gasPrice ? gasPrice * 1000000000 : avgGasPrice,
|
|
788
|
-
gasLimit: gasLimit
|
|
828
|
+
gasLimit: gasLimit,
|
|
789
829
|
to: address,
|
|
790
830
|
value
|
|
791
831
|
}
|
|
@@ -804,16 +844,19 @@ async function ethWrite(sender, address, {data, abi, method, args, gasPrice, gas
|
|
|
804
844
|
console.log("No address to used")
|
|
805
845
|
return {}
|
|
806
846
|
}
|
|
807
|
-
|
|
847
|
+
msg = trim(msg)
|
|
848
|
+
msg = msg ? msg + ' ':''
|
|
849
|
+
console.log(`${msg}send ${signedTx.hash} ${txObject.gasPrice/1000000000}g`)
|
|
808
850
|
result = result.then(resp => {
|
|
809
|
-
console.log('\x1B[32m%s\x1B[39m', `${msg}
|
|
851
|
+
console.log('\x1B[32m%s\x1B[39m', `${msg}${signedTx.hash} 交易成功`)
|
|
810
852
|
return true
|
|
811
853
|
}).catch(async e => {
|
|
812
|
-
console.log('\x1B[35m%s\x1B[39m', `${msg}
|
|
854
|
+
console.log('\x1B[35m%s\x1B[39m', `${msg}${signedTx.hash} 交易失败`)
|
|
813
855
|
if (onError) {
|
|
814
856
|
return await onError(e)
|
|
815
857
|
} else {
|
|
816
858
|
console.error(e.toString().split("\n")[0])
|
|
859
|
+
$log(new Error(e.stack).stack);
|
|
817
860
|
return false
|
|
818
861
|
}
|
|
819
862
|
})
|
|
@@ -1104,26 +1147,6 @@ async function getContractJson(address) {
|
|
|
1104
1147
|
return JSON.parse(String(fs.readFileSync(obj[address]['abiPath'])))
|
|
1105
1148
|
}
|
|
1106
1149
|
}
|
|
1107
|
-
|
|
1108
|
-
const agent = new https.Agent({
|
|
1109
|
-
rejectUnauthorized: false
|
|
1110
|
-
});
|
|
1111
|
-
let home = getLibDataDir() + '/abi'
|
|
1112
|
-
mkdir(home)
|
|
1113
|
-
let file = `${home}/${address}`
|
|
1114
|
-
if (fs.existsSync(file)) {
|
|
1115
|
-
let str = String(fs.readFileSync(file))
|
|
1116
|
-
let strs = str.split('\n').map(item => trim(item)).filter(item => item)
|
|
1117
|
-
return {abi: JSON.parse(strs[1])}
|
|
1118
|
-
}
|
|
1119
|
-
return got(`https://api-cn.etherscan.com/api?module=contract&action=getabi&address=${address}`,
|
|
1120
|
-
{ httpsAgent: agent }).then(resp => {
|
|
1121
|
-
if (resp.data.status !== '1') {
|
|
1122
|
-
return ''
|
|
1123
|
-
}
|
|
1124
|
-
fs.writeFileSync(file, `${Date.now()}\n${resp.data.result}`)
|
|
1125
|
-
return {abi: JSON.parse(resp.data.result)}
|
|
1126
|
-
})
|
|
1127
1150
|
}
|
|
1128
1151
|
|
|
1129
1152
|
async function transferToken(ethTranserWrite, sender, address, token, amt, msg) {
|
|
@@ -1229,5 +1252,7 @@ module.exports = {
|
|
|
1229
1252
|
getTokenBal,
|
|
1230
1253
|
transferToken,
|
|
1231
1254
|
tokenApprove,
|
|
1232
|
-
txnInputReplacer
|
|
1255
|
+
txnInputReplacer,
|
|
1256
|
+
abiDecoder,
|
|
1257
|
+
saveTokenMap
|
|
1233
1258
|
}
|
package/index.js
CHANGED
|
@@ -129,7 +129,9 @@ const {
|
|
|
129
129
|
getTokenBal,
|
|
130
130
|
transferToken,
|
|
131
131
|
tokenApprove,
|
|
132
|
-
txnInputReplacer
|
|
132
|
+
txnInputReplacer,
|
|
133
|
+
abiDecoder,
|
|
134
|
+
saveTokenMap
|
|
133
135
|
} = require('./ethWeb')
|
|
134
136
|
|
|
135
137
|
module.exports = {
|
|
@@ -259,5 +261,7 @@ module.exports = {
|
|
|
259
261
|
warn,
|
|
260
262
|
error,
|
|
261
263
|
txnInputReplacer,
|
|
262
|
-
parseSteps
|
|
264
|
+
parseSteps,
|
|
265
|
+
abiDecoder,
|
|
266
|
+
saveTokenMap
|
|
263
267
|
}
|
package/package.json
CHANGED
package/sol.js
CHANGED
|
@@ -107,13 +107,13 @@ async function exeMethods(web3, deployInfo, sol, method, text) {
|
|
|
107
107
|
deployInfo.address);
|
|
108
108
|
text = text + '\n' + fs.readFileSync(deployInfo.abiPath.replace('.json', '.sol').replace('/bin', ''))
|
|
109
109
|
|
|
110
|
-
let args = reget(text, new RegExp(`@${method}
|
|
111
|
-
let sendArgs = reget(text, new RegExp(`@${method}
|
|
112
|
-
let callArgs = reget(text, new RegExp(`@${method}
|
|
113
|
-
let value = reget(text, new RegExp(`@${method}
|
|
114
|
-
let gas = reget(text, new RegExp(`@${method}
|
|
115
|
-
let from = reget(text, new RegExp(`@${method}
|
|
116
|
-
let expect = reget(text, new RegExp(`@${method}
|
|
110
|
+
let args = reget(text, new RegExp(`@${method}\.args[ :=]+(.*)`))
|
|
111
|
+
let sendArgs = reget(text, new RegExp(`@${method}(\.send)`))
|
|
112
|
+
let callArgs = reget(text, new RegExp(`@${method}(\.call)`))
|
|
113
|
+
let value = reget(text, new RegExp(`@${method}\.value[ :=]+(.*)`));
|
|
114
|
+
let gas = reget(text, new RegExp(`@${method}\.gas[ :=]+(.*)`));
|
|
115
|
+
let from = reget(text, new RegExp(`@${method}\.from[ :=]+(.*)`));
|
|
116
|
+
let expect = reget(text, new RegExp(`@${method}\.expect[ :=]+(.*)`));
|
|
117
117
|
let action = 'call';
|
|
118
118
|
|
|
119
119
|
let fnStr = reget(text, new RegExp(`\\s+(function\\s+${method}\\s*\\([\\s\\S]*?)\\{`));
|
|
@@ -121,11 +121,9 @@ async function exeMethods(web3, deployInfo, sol, method, text) {
|
|
|
121
121
|
action = 'send'
|
|
122
122
|
}
|
|
123
123
|
if (callArgs) {
|
|
124
|
-
args = callArgs;
|
|
125
124
|
action = 'call'
|
|
126
125
|
}
|
|
127
126
|
if (sendArgs) {
|
|
128
|
-
args = sendArgs;
|
|
129
127
|
action = 'send'
|
|
130
128
|
}
|
|
131
129
|
|