Skip to content

Commit 5d1862f

Browse files
authoredAug 7, 2023
fix(common-scripts): sudt data may over 16 bytes (#549)
1 parent 6bb442c commit 5d1862f

File tree

7 files changed

+51
-19
lines changed

7 files changed

+51
-19
lines changed
 

‎.changeset/orange-flowers-sort.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@ckb-lumos/common-scripts": patch
3+
---
4+
5+
enable ACP to work with sUDT cells with more than 16 bytes of data

‎examples/exchange-sudt-for-ckb/package.json

+4-4
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,10 @@
1515
"process": "^0.11.10"
1616
},
1717
"dependencies": {
18-
"@ckb-lumos/base": "next",
19-
"@ckb-lumos/bi": "next",
20-
"@ckb-lumos/codec": "next",
21-
"@ckb-lumos/common-scripts": "next",
18+
"@ckb-lumos/base": "canary",
19+
"@ckb-lumos/bi": "canary",
20+
"@ckb-lumos/codec": "canary",
21+
"@ckb-lumos/common-scripts": "canary",
2222
"@ckb-lumos/lumos": "next",
2323
"@types/react": "^18.0.25",
2424
"@types/react-dom": "^18.0.9",

‎examples/exchange-sudt-for-ckb/src/lib.ts

+6-6
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { payFeeByFeeRate } from "@ckb-lumos/common-scripts/lib/common";
55
import { addCellDep } from "@ckb-lumos/common-scripts/lib/helper";
66
import { List } from "immutable";
77
import { computeScriptHash } from "@ckb-lumos/base/lib/utils";
8-
import { bytes, number } from "@ckb-lumos/codec";
8+
import { bytes } from "@ckb-lumos/codec";
99
import { blockchain } from "@ckb-lumos/base";
1010

1111
export const { AGGRON4 } = config.predefined;
@@ -122,7 +122,7 @@ export async function transferCKB2SUDT(issuerPrivateKey: string, holderPrivateKe
122122
break;
123123
}
124124
inputs = inputs.push(cell);
125-
total = total.add(number.Uint128LE.unpack(cell.data));
125+
total = total.add(sudt.unpackAmount(cell.data));
126126
}
127127
return inputs;
128128
});
@@ -146,7 +146,7 @@ export async function transferCKB2SUDT(issuerPrivateKey: string, holderPrivateKe
146146
lock: holderAccountInfo.lockScript,
147147
type: issuerTypeScript,
148148
},
149-
data: bytes.hexify(number.Uint128LE.pack(SUDTAmount)),
149+
data: sudt.packAmount(SUDTAmount),
150150
};
151151

152152
console.log(calculateSUDTAmountSum(issuerSUDTCells).toBigInt());
@@ -157,7 +157,7 @@ export async function transferCKB2SUDT(issuerPrivateKey: string, holderPrivateKe
157157
lock: issuerAccountInfo.lockScript,
158158
type: issuerTypeScript,
159159
},
160-
data: bytes.hexify(number.Uint128LE.pack(calculateSUDTAmountSum(issuerSUDTCells).sub(SUDTAmount))),
160+
data: sudt.packAmount(calculateSUDTAmountSum(issuerSUDTCells).sub(SUDTAmount)),
161161
};
162162

163163
SUDTTargetOutput.cellOutput.capacity = BI.from(helpers.minimalCellCapacity(SUDTTargetOutput)).toHexString();
@@ -274,7 +274,7 @@ export function calculateSUDTAmountSum(cells: Cell[]) {
274274
let amount = BI.from(0);
275275
for (const cell of cells) {
276276
if (cell.cellOutput.type?.codeHash === AGGRON4.SCRIPTS.SUDT.CODE_HASH) {
277-
amount = amount.add(number.Uint128LE.unpack(cell.data));
277+
amount = amount.add(sudt.unpackAmount(cell.data));
278278
}
279279
}
280280

@@ -310,7 +310,7 @@ export async function fetchSUDTBalance(address: string, issuerLockScript: Script
310310
let amount = BI.from(0);
311311

312312
for await (const cell of collector.collect()) {
313-
amount = amount.add(number.Uint128LE.unpack(cell.data));
313+
amount = amount.add(sudt.unpackAmount(cell.data));
314314
}
315315
return amount;
316316
}

‎packages/ckb-indexer/scripts/e2e-test.ts

+1
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ async function main() {
4848

4949
ckbProcess.kill();
5050
indexerProcess.kill();
51+
process.exit();
5152
}
5253

5354
main();

‎packages/common-scripts/src/anyone_can_pay.ts

+5-3
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import {
1313
WitnessArgs,
1414
blockchain,
1515
} from "@ckb-lumos/base";
16-
import { bytes, number } from "@ckb-lumos/codec";
16+
import { bytes } from "@ckb-lumos/codec";
1717
import { Config, getConfig } from "@ckb-lumos/config-manager";
1818
import {
1919
createTransactionFromSkeleton,
@@ -33,6 +33,8 @@ import {
3333
SECP_SIGNATURE_PLACEHOLDER,
3434
} from "./helper";
3535
import { CellCollectorConstructor, CellCollectorType } from "./type";
36+
import { unpackAmount } from "./sudt";
37+
3638
const { ScriptValue } = values;
3739
const { CKBHasher, ckbHash } = utils;
3840

@@ -480,7 +482,7 @@ export function prepareSigningEntries(
480482

481483
const sumOfOutputAmount: BI = outputs
482484
.filter((output) => output.data !== "0x")
483-
.map((output) => number.Uint128LE.unpack(output.data))
485+
.map((output) => unpackAmount(output.data))
484486
.reduce((result, c) => result.add(c), BI.from(0));
485487

486488
const fInputs: List<Cell> = inputs.filter((i) => {
@@ -495,7 +497,7 @@ export function prepareSigningEntries(
495497

496498
const sumOfInputAmount: BI = fInputs
497499
.filter((i) => i.data !== "0x")
498-
.map((i) => BI.from(number.Uint128LE.unpack(i.data)))
500+
.map((i) => BI.from(unpackAmount(i.data)))
499501
.reduce((result, c) => result.add(c), BI.from(0));
500502

501503
if (

‎packages/common-scripts/src/sudt.ts

+15-6
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import {
88
Header,
99
CellCollector as CellCollectorInterface,
1010
values,
11+
HexString,
1112
} from "@ckb-lumos/base";
1213
const { computeScriptHash } = utils;
1314
import secp256k1Blake160Multisig from "./secp256k1_blake160_multisig";
@@ -28,7 +29,7 @@ import anyoneCanPay, {
2829
const { ScriptValue } = values;
2930
import secp256k1Blake160 from "./secp256k1_blake160";
3031
import { BI, BIish } from "@ckb-lumos/bi";
31-
import { bytes, number } from "@ckb-lumos/codec";
32+
import { bytes, type BytesLike, number } from "@ckb-lumos/codec";
3233

3334
export type Token = Hash;
3435

@@ -220,7 +221,7 @@ export async function transfer(
220221
});
221222

222223
toAddressInputCapacity = BI.from(toAddressInput.cellOutput.capacity);
223-
toAddressInputAmount = number.Uint128LE.unpack(toAddressInput.data);
224+
toAddressInputAmount = unpackAmount(toAddressInput.data);
224225
}
225226

226227
const targetOutput: Cell = {
@@ -479,7 +480,7 @@ export async function transfer(
479480

480481
const inputCapacity: BI = BI.from(inputCell.cellOutput.capacity);
481482
const inputAmount: BI = inputCell.cellOutput.type
482-
? number.Uint128LE.unpack(inputCell.data)
483+
? unpackAmount(inputCell.data)
483484
: BI.from(0);
484485
let deductCapacity: BI =
485486
isAnyoneCanPay && !destroyable
@@ -600,9 +601,7 @@ export async function transfer(
600601
.toString(16);
601602
if (changeAmount.gt(0)) {
602603
clonedOutput.data = bytes.hexify(
603-
number.Uint128LE.pack(
604-
number.Uint128LE.unpack(originOutput.data).add(changeAmount)
605-
)
604+
number.Uint128LE.pack(unpackAmount(originOutput.data).add(changeAmount))
606605
);
607606
}
608607

@@ -720,8 +719,18 @@ export function ownerForSudt(
720719
return lockHash;
721720
}
722721

722+
export function unpackAmount(data: BytesLike): BI {
723+
return number.Uint128LE.unpack(bytes.bytify(data).slice(0, 16));
724+
}
725+
726+
export function packAmount(amount: BIish): HexString {
727+
return bytes.hexify(number.Uint128LE.pack(amount));
728+
}
729+
723730
export default {
724731
issueToken,
725732
transfer,
726733
ownerForSudt,
734+
packAmount,
735+
unpackAmount,
727736
};

‎packages/common-scripts/tests/sudt.test.ts

+15
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import {
2020
} from "./inputs";
2121
import { BI } from "@ckb-lumos/bi";
2222
import { bytes, number } from "@ckb-lumos/codec";
23+
import { packAmount, unpackAmount } from "../src/sudt";
2324
const { AGGRON4 } = predefined;
2425

2526
test.before(() => {
@@ -663,3 +664,17 @@ test("transfer secp => secp, change to acp and has previous output, split change
663664
const lastOutput = txSkeleton.get("outputs").get(-1)!;
664665
t.is(lastOutput.cellOutput.type, undefined);
665666
});
667+
668+
test("pack and unpack sudt amount", (t) => {
669+
const unpacked = BI.from(0x1234);
670+
const packed = Buffer.alloc(16);
671+
// little endian of 0x1234
672+
packed.write("3412", "hex");
673+
674+
t.true(bytes.equal(packAmount(unpacked), packed));
675+
t.true(unpackAmount(packed).eq(unpacked));
676+
677+
const over16Bytes = bytes.concat(packed, packed);
678+
t.true(over16Bytes.length > 16);
679+
t.true(unpackAmount(over16Bytes).eq(unpacked));
680+
});

2 commit comments

Comments
 (2)

vercel[bot] commented on Aug 7, 2023

@vercel[bot]

github-actions[bot] commented on Aug 7, 2023

@github-actions[bot]
Contributor

🚀 New canary release: 0.0.0-canary-5d1862f-20230807025040

npm install @ckb-lumos/lumos@0.0.0-canary-5d1862f-20230807025040
Please sign in to comment.