Skip to content

Commit c55bb7c

Browse files
committed
feat: preparation for audit for pausable-udt
1 parent f325436 commit c55bb7c

File tree

15 files changed

+827
-111
lines changed

15 files changed

+827
-111
lines changed

.vscode/launch.json

Lines changed: 159 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,16 +19,168 @@
1919
],
2020
"type": "node"
2121
},
22-
2322
{
2423
"type": "node",
2524
"request": "launch",
26-
"name": "Debug ckb_ssri_cli",
27-
"program": "${workspaceFolder}/bin/run",
28-
"args": [
29-
"udt:metadata:name",
30-
"0x5a68061c57b753c941919e42d74254f878ae2786387e42c1b835980443cb5cc8",
31-
"0",
25+
"name": "Test Unauthorized udt:mint",
26+
"runtimeExecutable": "pnpm",
27+
"runtimeArgs": [
28+
"run-script",
29+
"dev",
30+
"udt:mint",
31+
"PUDT",
32+
"--fromAccount=TestNormal",
33+
"ckt1qzda0cr08m85hc8jlnfp3zer7xulejywt49kt2rr0vthywaa50xwsqgatm0277z2rkyraf33rmn7hgl424z0lrg79sqam",
34+
"100"
35+
]
36+
},
37+
{
38+
"type": "node",
39+
"request": "launch",
40+
"name": "Test Normal udt:mint",
41+
"runtimeExecutable": "pnpm",
42+
"runtimeArgs": [
43+
"run-script",
44+
"dev",
45+
"udt:mint",
46+
"PUDT",
47+
"ckt1qzda0cr08m85hc8jlnfp3zer7xulejywt49kt2rr0vthywaa50xwsqgatm0277z2rkyraf33rmn7hgl424z0lrg79sqam",
48+
"100"
49+
]
50+
},
51+
{
52+
"type": "node",
53+
"request": "launch",
54+
"name": "Test Paused udt:mint",
55+
"runtimeExecutable": "pnpm",
56+
"runtimeArgs": [
57+
"run-script",
58+
"dev",
59+
"udt:mint",
60+
"PUDT",
61+
"ckt1qzda0cr08m85hc8jlnfp3zer7xulejywt49kt2rr0vthywaa50xwsqgtlcnzzna2tqst7jw78egjpujn7hdxpackjmmdp",
62+
"100"
63+
]
64+
},
65+
{
66+
"type": "node",
67+
"request": "launch",
68+
"name": "Test Paused udt:transfer",
69+
"runtimeExecutable": "pnpm",
70+
"runtimeArgs": [
71+
"run-script",
72+
"dev",
73+
"udt:transfer",
74+
"PUDT",
75+
"ckt1qzda0cr08m85hc8jlnfp3zer7xulejywt49kt2rr0vthywaa50xwsqgtlcnzzna2tqst7jw78egjpujn7hdxpackjmmdp",
76+
"100"
77+
]
78+
},
79+
{
80+
"type": "node",
81+
"request": "launch",
82+
"name": "Test Normal udt:transfer",
83+
"runtimeExecutable": "pnpm",
84+
"runtimeArgs": [
85+
"run-script",
86+
"dev",
87+
"udt:transfer",
88+
"PUDT",
89+
"ckt1qzda0cr08m85hc8jlnfp3zer7xulejywt49kt2rr0vthywaa50xwsqgatm0277z2rkyraf33rmn7hgl424z0lrg79sqam",
90+
"100"
91+
]
92+
},
93+
{
94+
"type": "node",
95+
"request": "launch",
96+
"name": "Test udt:pausable:enumerate-paused",
97+
"runtimeExecutable": "pnpm",
98+
"runtimeArgs": [
99+
"run-script",
100+
"dev",
101+
"udt:pausable:enumerate-paused",
102+
"PUDT",
103+
// "0xd19228c64920eb8c3d79557d8ae59ee7a14b9d7de45ccf8bafacf82c91fc359e",
104+
// "--newNext"
105+
]
106+
},
107+
{
108+
"type": "node",
109+
"request": "launch",
110+
"name": "Test udt:pausable:pause",
111+
"runtimeExecutable": "pnpm",
112+
"runtimeArgs": [
113+
"run-script",
114+
"dev",
115+
"udt:pausable:pause",
116+
"PUDT",
117+
"0xa320a09489791af2e5e1fe84927eda84f71afcbd2c7a65cb419464fe46e75085",
118+
// "--newNext"
119+
]
120+
},
121+
{
122+
"type": "node",
123+
"request": "launch",
124+
"name": "Test udt:pausable:unpause",
125+
"runtimeExecutable": "pnpm",
126+
"runtimeArgs": [
127+
"run-script",
128+
"dev",
129+
"udt:pausable:unpause",
130+
"PUDT",
131+
"0xa320a09489791af2e5e1fe84927eda84f71afcbd2c7a65cb419464fe46e75085",
132+
// "--newNext"
133+
]
134+
},
135+
{
136+
"type": "node",
137+
"request": "launch",
138+
"name": "Test udt:name",
139+
"runtimeExecutable": "pnpm",
140+
"runtimeArgs": [
141+
"run-script",
142+
"dev",
143+
"udt:name",
144+
"0x72b80b17ab839d50745ad6697520a86bac87b126971c9b7a1e36baba975a995d",
145+
"0"
146+
]
147+
},
148+
{
149+
"type": "node",
150+
"request": "launch",
151+
"name": "Test udt:decimals",
152+
"runtimeExecutable": "pnpm",
153+
"runtimeArgs": [
154+
"run-script",
155+
"dev",
156+
"udt:decimals",
157+
"0x72b80b17ab839d50745ad6697520a86bac87b126971c9b7a1e36baba975a995d",
158+
"0"
159+
]
160+
},
161+
{
162+
"type": "node",
163+
"request": "launch",
164+
"name": "Test udt:symbol",
165+
"runtimeExecutable": "pnpm",
166+
"runtimeArgs": [
167+
"run-script",
168+
"dev",
169+
"udt:symbol",
170+
"0x72b80b17ab839d50745ad6697520a86bac87b126971c9b7a1e36baba975a995d",
171+
"0"
172+
]
173+
},
174+
{
175+
"type": "node",
176+
"request": "launch",
177+
"name": "Test dev:modify-data",
178+
"runtimeExecutable": "pnpm",
179+
"runtimeArgs": [
180+
"run-script",
181+
"dev",
182+
"dev:modify-data",
183+
"PUDT",
32184
]
33185
}
34186
]

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,8 @@
7777
"posttest": "pnpm run lint",
7878
"prepack": "oclif manifest && oclif readme",
7979
"test": "mocha --forbid-only \"test/**/*.test.ts\"",
80-
"version": "oclif readme && git add README.md"
80+
"version": "oclif readme && git add README.md",
81+
"dev": "node --loader ts-node/esm ./bin/dev.js"
8182
},
8283
"types": "dist/index.d.ts"
8384
}

src/commands/dev/modify-data.ts

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
import {Args, Command, Flags} from '@oclif/core'
2+
import {getCellDepsFromSearchKeys, getCLIConfig} from '../../libs/config.js'
3+
import {ccc, Cell, CellOutputLike, fixedPointFrom, HasherCkb, numToBytes} from '@ckb-ccc/core'
4+
import {ClientCollectableSearchKeyLike, cccA} from '@ckb-ccc/core/advanced'
5+
// TODO: Switch to codec in CCC.
6+
import {Byte32, Bytes, BytesVec, Script} from '@ckb-lumos/base/lib/blockchain.js'
7+
import axios from 'axios'
8+
import {blockchain} from '@ckb-lumos/base'
9+
import {encodeHex, encodeU832Array} from '../../libs/utils.js'
10+
import {array, option, table, vector} from '@ckb-lumos/codec/lib/molecule/layout.js'
11+
import {BIish, Uint8} from '@ckb-lumos/codec/lib/number/uint.js'
12+
import {decodeHex} from '../../libs/utils.js'
13+
14+
export default class DevModifyData extends Command {
15+
static override args = {
16+
symbol: Args.string({
17+
description: 'Symbol of UDT to unpause. ',
18+
required: true,
19+
}),
20+
lock_hash: Args.string({description: 'Lock hash in hex. Variable length'}),
21+
}
22+
23+
static strict = false
24+
25+
static override description =
26+
'Add a lock_hash to pause list. If UDTPausable.enumerate_paused() returns a list of only one UDTPausableData in the vec which means there is no external pausable data cell, a new pausable data cell will be created but manual reference in the contract code is required. NOTE: You cannot use holdSend for more than one pause/pause action in the same transaction, and results of pause/unpause would only take effect after the transaction is confirmed.'
27+
28+
static override examples = ['<%= config.bin %> <%= command.id %>']
29+
30+
static override flags = {
31+
fromTransactionJSON: Flags.file({
32+
description:
33+
'(NOT IMPLEMENTED YET!) Assemble transaction on the basis of a previous action; use together with holdSend to make multiple transfers within the same transaction.',
34+
exists: true,
35+
}),
36+
holdSendToJSON: Flags.file({
37+
description:
38+
'(NOT IMPLEMENTED YET!) Hold the transaction and send it later. Will output the transaction JSON. Use together with fromTransactionJson to make multiple transfers within the same transaction.',
39+
exists: false,
40+
}),
41+
holdSend: Flags.boolean({
42+
description:
43+
'(NOT IMPLEMENTED YET!) Hold the transaction and send it later. When neither holdSend nor holdSendToJSON is set, the transaction will be sent immediately.',
44+
}),
45+
}
46+
47+
public async run(): Promise<void> {
48+
const {args, argv, flags} = await this.parse(DevModifyData)
49+
50+
const CLIConfig = await getCLIConfig(this.config.configDir)
51+
const client = new ccc.ClientPublicTestnet({url: process.env.CKB_RPC_URL})
52+
53+
const signer = new ccc.SignerCkbPrivateKey(
54+
client,
55+
flags.privateKey ??
56+
CLIConfig.accountRegistry[flags.fromAccount ?? '']?.privateKey ??
57+
process.env.MAIN_WALLET_PRIVATE_KEY!,
58+
)
59+
60+
const udtConfig = CLIConfig.UDTRegistry[args.symbol]
61+
62+
const unpauseHasher = new HasherCkb()
63+
const unpausePathHex = unpauseHasher.update(Buffer.from('UDTPausable.unpause')).digest().slice(0, 18)
64+
65+
const codeCellDep = (await getCellDepsFromSearchKeys(client, udtConfig.cellDepSearchKeys))[0]
66+
67+
const u832Codec = array(Uint8, 32)
68+
const u832VecCodec = vector(u832Codec)
69+
70+
const udtPausableDataCodec = table(
71+
{
72+
pause_list: u832VecCodec,
73+
next_type_script: option(Script),
74+
},
75+
['pause_list', 'next_type_script'],
76+
)
77+
78+
const {script: ownerLock} = await signer.getRecommendedAddressObj()
79+
80+
let lockHashU832Array = []
81+
for (const lockHash of argv.slice(1)) {
82+
lockHashU832Array.push(numToBytes(String(lockHash), 32).reverse())
83+
}
84+
this.debug(`lockHashU832Array: ${lockHashU832Array}`)
85+
const lockHashU832ArrayEncoded = encodeU832Array(lockHashU832Array)
86+
this.debug(`lockHashArrayEncoded: ${lockHashU832ArrayEncoded}`)
87+
const lockHashU832ArrayEncodedHex = encodeHex(lockHashU832ArrayEncoded)
88+
const inputTypeScript = await ccc.Script.fromKnownScript(
89+
client,
90+
ccc.KnownScript.TypeId,
91+
'0x4804b04f37f22f77b3cb621e6fbc471330893c98c56868f0d74b91cc996fe0cb',
92+
)
93+
94+
const inputTypeIDCell = (await client.findCellsByType(inputTypeScript).next()).value as Cell
95+
96+
const inputTypeIDCellInput = new ccc.CellInput(inputTypeIDCell.outPoint, BigInt(0))
97+
98+
// TODO: Placeholder for holdSend and holdSendToJSON.
99+
const modifyTx = ccc.Transaction.from({
100+
version: 0,
101+
cellDeps: [],
102+
headerDeps: [],
103+
inputs: [inputTypeIDCellInput],
104+
outputs: [],
105+
outputsData: [],
106+
witnesses: [],
107+
})
108+
109+
modifyTx.addOutput(
110+
{
111+
lock: ownerLock,
112+
type: inputTypeScript,
113+
},
114+
'0x500000000c0000005000000002000000d19228c64920eb8c3d79557d8ae59ee7a14b9d7de45ccf8bafacf82c91fc359ea320a09489791af2e5e1fe84927eda84f71afcbd2c7a65cb419464fe46e75085',
115+
)
116+
117+
try {
118+
await modifyTx.completeInputsByCapacity(signer)
119+
await modifyTx.completeFeeBy(signer)
120+
const modifyTxHash = await signer.sendTransaction(modifyTx)
121+
this.log(`Modified. Tx hash: ${modifyTxHash}`)
122+
} catch (error) {
123+
// ISSUE: [Prettify responses from SSRI calls #21](https://github.com/Alive24/ckb_ssri_cli/issues/21)
124+
console.error('Request failed', error)
125+
}
126+
}
127+
}

src/commands/udt/metadata/decimals.ts renamed to src/commands/udt/decimals.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
import { ccc, HasherCkb } from '@ckb-ccc/core'
22
import {Args, Command, Flags} from '@oclif/core'
3-
import { getCLIConfig } from '../../../libs/config.js'
3+
import { getCLIConfig } from '../../libs/config.js'
44
import axios from 'axios'
55

6-
export default class UDTMetadataDecimals extends Command {
6+
export default class UDTDecimals extends Command {
77
static override args = {
88
txHash: Args.string({description: 'txHash of the UDT cell (Note: Not the script cell).', required: true}),
99
index: Args.integer({description: 'index of the UDT cell (Note: Not the script cell).', required: true}),
@@ -18,10 +18,10 @@ export default class UDTMetadataDecimals extends Command {
1818
}
1919

2020
public async run(): Promise<void> {
21-
const {args, flags} = await this.parse(UDTMetadataDecimals)
21+
const {args, flags} = await this.parse(UDTDecimals)
2222
// Method path hex function
2323
const hasher = new HasherCkb()
24-
const decimalPathHex = hasher.update(Buffer.from('UDTMetadata.decimals')).digest().slice(0, 18)
24+
const decimalPathHex = hasher.update(Buffer.from('UDT.decimals')).digest().slice(0, 18)
2525
this.debug(`Hashed method path hex: ${decimalPathHex}`)
2626

2727
const client = new ccc.ClientPublicTestnet({url: process.env.CKB_RPC_URL})

0 commit comments

Comments
 (0)