Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(common-scripts): sudt data may over 16 bytes #549

Merged
merged 6 commits into from
Aug 7, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/orange-flowers-sort.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@ckb-lumos/common-scripts": patch
---

enable ACP to work with sUDT cells with more than 16 bytes of data
8 changes: 4 additions & 4 deletions examples/exchange-sudt-for-ckb/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@
"process": "^0.11.10"
},
"dependencies": {
"@ckb-lumos/base": "next",
"@ckb-lumos/bi": "next",
"@ckb-lumos/codec": "next",
"@ckb-lumos/common-scripts": "next",
"@ckb-lumos/base": "canary",
"@ckb-lumos/bi": "canary",
"@ckb-lumos/codec": "canary",
"@ckb-lumos/common-scripts": "canary",
"@ckb-lumos/lumos": "next",
"@types/react": "^18.0.25",
"@types/react-dom": "^18.0.9",
Expand Down
12 changes: 6 additions & 6 deletions examples/exchange-sudt-for-ckb/src/lib.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { payFeeByFeeRate } from "@ckb-lumos/common-scripts/lib/common";
import { addCellDep } from "@ckb-lumos/common-scripts/lib/helper";
import { List } from "immutable";
import { computeScriptHash } from "@ckb-lumos/base/lib/utils";
import { bytes, number } from "@ckb-lumos/codec";
import { bytes } from "@ckb-lumos/codec";
import { blockchain } from "@ckb-lumos/base";

export const { AGGRON4 } = config.predefined;
Expand Down Expand Up @@ -122,7 +122,7 @@ export async function transferCKB2SUDT(issuerPrivateKey: string, holderPrivateKe
break;
}
inputs = inputs.push(cell);
total = total.add(number.Uint128LE.unpack(cell.data));
total = total.add(sudt.unpackAmount(cell.data));
}
return inputs;
});
Expand All @@ -146,7 +146,7 @@ export async function transferCKB2SUDT(issuerPrivateKey: string, holderPrivateKe
lock: holderAccountInfo.lockScript,
type: issuerTypeScript,
},
data: bytes.hexify(number.Uint128LE.pack(SUDTAmount)),
data: sudt.packAmount(SUDTAmount),
};

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

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

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

for await (const cell of collector.collect()) {
amount = amount.add(number.Uint128LE.unpack(cell.data));
amount = amount.add(sudt.unpackAmount(cell.data));
}
return amount;
}
Expand Down
1 change: 1 addition & 0 deletions packages/ckb-indexer/scripts/e2e-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ async function main() {

ckbProcess.kill();
indexerProcess.kill();
process.exit();
}

main();
8 changes: 5 additions & 3 deletions packages/common-scripts/src/anyone_can_pay.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import {
WitnessArgs,
blockchain,
} from "@ckb-lumos/base";
import { bytes, number } from "@ckb-lumos/codec";
import { bytes } from "@ckb-lumos/codec";
import { Config, getConfig } from "@ckb-lumos/config-manager";
import {
createTransactionFromSkeleton,
Expand All @@ -33,6 +33,8 @@ import {
SECP_SIGNATURE_PLACEHOLDER,
} from "./helper";
import { CellCollectorConstructor, CellCollectorType } from "./type";
import { unpackAmount } from "./sudt";

const { ScriptValue } = values;
const { CKBHasher, ckbHash } = utils;

Expand Down Expand Up @@ -480,7 +482,7 @@ export function prepareSigningEntries(

const sumOfOutputAmount: BI = outputs
.filter((output) => output.data !== "0x")
.map((output) => number.Uint128LE.unpack(output.data))
.map((output) => unpackAmount(output.data))
.reduce((result, c) => result.add(c), BI.from(0));

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

const sumOfInputAmount: BI = fInputs
.filter((i) => i.data !== "0x")
.map((i) => BI.from(number.Uint128LE.unpack(i.data)))
.map((i) => BI.from(unpackAmount(i.data)))
.reduce((result, c) => result.add(c), BI.from(0));

if (
Expand Down
21 changes: 15 additions & 6 deletions packages/common-scripts/src/sudt.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
Header,
CellCollector as CellCollectorInterface,
values,
HexString,
} from "@ckb-lumos/base";
const { computeScriptHash } = utils;
import secp256k1Blake160Multisig from "./secp256k1_blake160_multisig";
Expand All @@ -28,7 +29,7 @@ import anyoneCanPay, {
const { ScriptValue } = values;
import secp256k1Blake160 from "./secp256k1_blake160";
import { BI, BIish } from "@ckb-lumos/bi";
import { bytes, number } from "@ckb-lumos/codec";
import { bytes, type BytesLike, number } from "@ckb-lumos/codec";

export type Token = Hash;

Expand Down Expand Up @@ -220,7 +221,7 @@ export async function transfer(
});

toAddressInputCapacity = BI.from(toAddressInput.cellOutput.capacity);
toAddressInputAmount = number.Uint128LE.unpack(toAddressInput.data);
toAddressInputAmount = unpackAmount(toAddressInput.data);
}

const targetOutput: Cell = {
Expand Down Expand Up @@ -479,7 +480,7 @@ export async function transfer(

const inputCapacity: BI = BI.from(inputCell.cellOutput.capacity);
const inputAmount: BI = inputCell.cellOutput.type
? number.Uint128LE.unpack(inputCell.data)
? unpackAmount(inputCell.data)
: BI.from(0);
let deductCapacity: BI =
isAnyoneCanPay && !destroyable
Expand Down Expand Up @@ -600,9 +601,7 @@ export async function transfer(
.toString(16);
if (changeAmount.gt(0)) {
clonedOutput.data = bytes.hexify(
number.Uint128LE.pack(
number.Uint128LE.unpack(originOutput.data).add(changeAmount)
)
number.Uint128LE.pack(unpackAmount(originOutput.data).add(changeAmount))
);
}

Expand Down Expand Up @@ -720,8 +719,18 @@ export function ownerForSudt(
return lockHash;
}

export function unpackAmount(data: BytesLike): BI {
return number.Uint128LE.unpack(bytes.bytify(data).slice(0, 16));
}

export function packAmount(amount: BIish): HexString {
return bytes.hexify(number.Uint128LE.pack(amount));
}

export default {
issueToken,
transfer,
ownerForSudt,
packAmount,
unpackAmount,
};
15 changes: 15 additions & 0 deletions packages/common-scripts/tests/sudt.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import {
} from "./inputs";
import { BI } from "@ckb-lumos/bi";
import { bytes, number } from "@ckb-lumos/codec";
import { packAmount, unpackAmount } from "../src/sudt";
const { AGGRON4 } = predefined;

test.before(() => {
Expand Down Expand Up @@ -663,3 +664,17 @@ test("transfer secp => secp, change to acp and has previous output, split change
const lastOutput = txSkeleton.get("outputs").get(-1)!;
t.is(lastOutput.cellOutput.type, undefined);
});

test("pack and unpack sudt amount", (t) => {
const unpacked = BI.from(0x1234);
const packed = Buffer.alloc(16);
// little endian of 0x1234
packed.write("3412", "hex");

t.true(bytes.equal(packAmount(unpacked), packed));
t.true(unpackAmount(packed).eq(unpacked));

const over16Bytes = bytes.concat(packed, packed);
t.true(over16Bytes.length > 16);
t.true(unpackAmount(over16Bytes).eq(unpacked));
});