From 9ffb5506f6736ea4444a20ef1530fb2938d97196 Mon Sep 17 00:00:00 2001 From: yanguoyu <841185308@qq.com> Date: Mon, 28 Feb 2022 16:06:04 +0800 Subject: [PATCH 1/8] implement rpc calculate_dao_maximum_withdraw in sdk --- packages/ckb-sdk-core/src/index.ts | 45 ++++++++++++++++++- .../ckb-sdk-utils/src/convertors/index.ts | 16 ++++++- 2 files changed, 59 insertions(+), 2 deletions(-) diff --git a/packages/ckb-sdk-core/src/index.ts b/packages/ckb-sdk-core/src/index.ts index 96662a38..30bf8477 100644 --- a/packages/ckb-sdk-core/src/index.ts +++ b/packages/ckb-sdk-core/src/index.ts @@ -1,7 +1,7 @@ /// import RPC from '@nervosnetwork/ckb-sdk-rpc' -import { ParameterRequiredException } from '@nervosnetwork/ckb-sdk-utils/lib/exceptions' +import { ParameterRequiredException, HexStringWithout0xException } from '@nervosnetwork/ckb-sdk-utils/lib/exceptions' import * as utils from '@nervosnetwork/ckb-sdk-utils' import generateRawTransaction from './generateRawTransaction' @@ -420,6 +420,49 @@ class CKB { } } + public calculateDaoMaximumWithdraw = async ( + outPoint: CKBComponents.OutPoint, + withdrawBlockHash: string + ): Promise => { + const depositTx = await this.rpc.getTransaction(outPoint.txHash) + if (depositTx.txStatus.status !== 'committed') throw new Error('Transaction is not committed yet') + const depositCell = depositTx.transaction.outputs[+outPoint.index] + const depositBlockHash = depositTx.txStatus.blockHash + const depositHeader = await this.rpc.getHeader(depositBlockHash) + const depositAr = this.#extracDaoData(depositHeader.dao).ar + const withDrawHeader = await this.rpc.getHeader(withdrawBlockHash) + const withdrawAr = this.#extracDaoData(withDrawHeader.dao).ar + const { JSBI } = this.utils + const occupiedCapacity = JSBI.asUintN(64, JSBI.BigInt(10200000000)); + return JSBI.add( + JSBI.divide( + JSBI.multiply( + JSBI.subtract( + JSBI.asUintN(64, JSBI.BigInt(depositCell.capacity)), + occupiedCapacity + ), + JSBI.asUintN(64, JSBI.BigInt(withdrawAr)) + ), + JSBI.asUintN(64, JSBI.BigInt(depositAr)) + ), + occupiedCapacity + ).toString() + } + + #extracDaoData = (dao: CKBComponents.DAO) => { + if (!dao.startsWith('0x')) { + throw new HexStringWithout0xException(dao) + } + const value = dao.replace('0x', ''); + const toBigEndian = utils.toBigEndian; + return { + c: toBigEndian(`0x${value.slice(0, 8)}`), + ar: toBigEndian(`0x${value.slice(16, 32)}`), + s: toBigEndian(`0x${value.slice(32, 48)}`), + u: toBigEndian(`0x${value.slice(48, 64)}`) + } + } + #secp256k1DepsShouldBeReady = () => { if (!this.config.secp256k1Dep) { throw new ParameterRequiredException('Secp256k1 dep') diff --git a/packages/ckb-sdk-utils/src/convertors/index.ts b/packages/ckb-sdk-utils/src/convertors/index.ts index bb3e9eaa..346bf0f6 100644 --- a/packages/ckb-sdk-utils/src/convertors/index.ts +++ b/packages/ckb-sdk-utils/src/convertors/index.ts @@ -1,4 +1,4 @@ -import { assertToBeHexStringOrBigint } from '../validators' +import { assertToBeHexStringOrBigint, assertToBeHexString } from '../validators' import { HexStringWithout0xException } from '../exceptions' /** @@ -61,6 +61,19 @@ export const hexToBytes = (rawhex: string | number | bigint) => { return new Uint8Array(bytes) } +/** + * Converts a hex string in little endian into big endian + * + * @memberof convertors + * @param {string} le16 The hex string to convert + * @returns {string} Returns a big endian + */ + export const toBigEndian = (leHex: string) => { + assertToBeHexString(leHex) + const bytes = hexToBytes(leHex); + return `0x${bytes.reduceRight((pre, cur) => pre + cur.toString(16), '')}` +} + export const bytesToHex = (bytes: Uint8Array): string => `0x${[...bytes].map(b => b.toString(16).padStart(2, '0')).join('')}` @@ -70,4 +83,5 @@ export default { toUint64Le, hexToBytes, bytesToHex, + toBigEndian } From 94a34a560d85e252f133d1a66568a00b8324bfbd Mon Sep 17 00:00:00 2001 From: yanguoyu <841185308@qq.com> Date: Mon, 28 Feb 2022 18:42:20 +0800 Subject: [PATCH 2/8] move data calc into utils --- packages/ckb-sdk-core/src/index.ts | 16 +--------------- packages/ckb-sdk-utils/src/index.ts | 28 +++++++++++++++++++++++++++- 2 files changed, 28 insertions(+), 16 deletions(-) diff --git a/packages/ckb-sdk-core/src/index.ts b/packages/ckb-sdk-core/src/index.ts index 30bf8477..da3d050d 100644 --- a/packages/ckb-sdk-core/src/index.ts +++ b/packages/ckb-sdk-core/src/index.ts @@ -432,21 +432,7 @@ class CKB { const depositAr = this.#extracDaoData(depositHeader.dao).ar const withDrawHeader = await this.rpc.getHeader(withdrawBlockHash) const withdrawAr = this.#extracDaoData(withDrawHeader.dao).ar - const { JSBI } = this.utils - const occupiedCapacity = JSBI.asUintN(64, JSBI.BigInt(10200000000)); - return JSBI.add( - JSBI.divide( - JSBI.multiply( - JSBI.subtract( - JSBI.asUintN(64, JSBI.BigInt(depositCell.capacity)), - occupiedCapacity - ), - JSBI.asUintN(64, JSBI.BigInt(withdrawAr)) - ), - JSBI.asUintN(64, JSBI.BigInt(depositAr)) - ), - occupiedCapacity - ).toString() + return utils.calculateMaximumWithdraw(depositCell, depositAr, withdrawAr); } #extracDaoData = (dao: CKBComponents.DAO) => { diff --git a/packages/ckb-sdk-utils/src/index.ts b/packages/ckb-sdk-utils/src/index.ts index c8843628..aa0d7a6c 100644 --- a/packages/ckb-sdk-utils/src/index.ts +++ b/packages/ckb-sdk-utils/src/index.ts @@ -4,7 +4,7 @@ import { hexToBytes } from './convertors' import { pubkeyToAddress, AddressOptions } from './address' import { ParameterRequiredException } from './exceptions' import crypto from './crypto' -import { serializeScript } from './serialization/script' +import { serializeOutput, serializeScript } from './serialization'; import { serializeRawTransaction, serializeTransaction, serializeWitnessArgs } from './serialization/transaction' import { PERSONAL } from './const' @@ -44,3 +44,29 @@ export const privateKeyToPublicKey = (privateKey: string) => { export const privateKeyToAddress = (privateKey: string, options: AddressOptions) => pubkeyToAddress(privateKeyToPublicKey(privateKey), options) + +export const calculateMaximumWithdraw = ( + depositCell: CKBComponents.CellOutput, + depositAr: string, + withdrawAr: string +) => { + const depositCellSerialized = serializeOutput(depositCell).slice(2).length / 2; + console.log(depositCellSerialized); + const occupiedCapacity = JSBI.asUintN( + 64, + JSBI.multiply(JSBI.BigInt(100000000), JSBI.BigInt(depositCellSerialized)) + ); + return JSBI.add( + JSBI.divide( + JSBI.multiply( + JSBI.subtract( + JSBI.asUintN(64, JSBI.BigInt(depositCell.capacity)), + occupiedCapacity + ), + JSBI.asUintN(64, JSBI.BigInt(withdrawAr)) + ), + JSBI.asUintN(64, JSBI.BigInt(depositAr)) + ), + occupiedCapacity + ).toString() +} \ No newline at end of file From 62feec643fa7e0984686b8fcd2e9e89ea122affe Mon Sep 17 00:00:00 2001 From: yanguoyu <841185308@qq.com> Date: Mon, 28 Feb 2022 19:01:24 +0800 Subject: [PATCH 3/8] add unit test --- .../__tests__/convertors/index.test.js | 6 ++++- .../__tests__/utils/index.test.js | 24 ++++++++++++++++++- .../ckb-sdk-utils/src/convertors/index.ts | 2 +- packages/ckb-sdk-utils/src/index.ts | 1 - 4 files changed, 29 insertions(+), 4 deletions(-) diff --git a/packages/ckb-sdk-utils/__tests__/convertors/index.test.js b/packages/ckb-sdk-utils/__tests__/convertors/index.test.js index 7b5ec2b0..34a3407a 100644 --- a/packages/ckb-sdk-utils/__tests__/convertors/index.test.js +++ b/packages/ckb-sdk-utils/__tests__/convertors/index.test.js @@ -1,4 +1,4 @@ -const { toUint16Le, toUint32Le, toUint64Le, hexToBytes, bytesToHex } = require('../../lib/convertors') +const { toUint16Le, toUint32Le, toUint64Le, hexToBytes, bytesToHex, toBigEndian } = require('../../lib/convertors') const { HexStringWithout0xException } = require('../../lib/exceptions') const { @@ -68,3 +68,7 @@ describe('bytes to hex', () => { expect(bytesToHex(bytes)).toEqual(expected) }) }) + +describe('to big endian', () => { + expect(toBigEndian('0x3ef9e8c069c92500')).toBe('0x0025c969c0e8f93e') +}) \ No newline at end of file diff --git a/packages/ckb-sdk-utils/__tests__/utils/index.test.js b/packages/ckb-sdk-utils/__tests__/utils/index.test.js index c236a4b2..a7791c76 100644 --- a/packages/ckb-sdk-utils/__tests__/utils/index.test.js +++ b/packages/ckb-sdk-utils/__tests__/utils/index.test.js @@ -1,4 +1,4 @@ -const { privateKeyToPublicKey, privateKeyToAddress, scriptToHash, rawTransactionToHash } = require('../..') +const { privateKeyToPublicKey, privateKeyToAddress, scriptToHash, rawTransactionToHash, calculateMaximumWithdraw } = require('../..') const exceptions = require('../../lib/exceptions') const rawTransactionToHashFixtures = require('./rawTransactionToHash.fixtures.json') @@ -82,3 +82,25 @@ describe('privateKeyToAddress', () => { }), ).toBe(fixture.testnetAddress) }) + +describe('calculate-maximum-withdraw', () => { + const outputCell = { + "capacity":"0xe8d4a51000", + "lock":{ + "args":"0xf601cac75568afec3b9c9af1e1ff730062007685", + "codeHash":"0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8", + "hashType":"type" + }, + "type":{ + "args":"0x", + "codeHash":"0x82d76d1b75fe2fd9a27dfbaa65a039221a380d76c926f378d3f81cf3e7e13f2e", + "hashType":"type" + } + }; + expect( + calculateMaximumWithdraw( + outputCell, + '0x0025c969c0e8f93e', + '0x0025cb34dbf9c694' + )).toBe('1000182611968') +}) \ No newline at end of file diff --git a/packages/ckb-sdk-utils/src/convertors/index.ts b/packages/ckb-sdk-utils/src/convertors/index.ts index 346bf0f6..b80c850a 100644 --- a/packages/ckb-sdk-utils/src/convertors/index.ts +++ b/packages/ckb-sdk-utils/src/convertors/index.ts @@ -71,7 +71,7 @@ export const hexToBytes = (rawhex: string | number | bigint) => { export const toBigEndian = (leHex: string) => { assertToBeHexString(leHex) const bytes = hexToBytes(leHex); - return `0x${bytes.reduceRight((pre, cur) => pre + cur.toString(16), '')}` + return `0x${bytes.reduceRight((pre, cur) => pre + cur.toString(16).padStart(2, '0'), '')}` } export const bytesToHex = (bytes: Uint8Array): string => diff --git a/packages/ckb-sdk-utils/src/index.ts b/packages/ckb-sdk-utils/src/index.ts index aa0d7a6c..c966d513 100644 --- a/packages/ckb-sdk-utils/src/index.ts +++ b/packages/ckb-sdk-utils/src/index.ts @@ -51,7 +51,6 @@ export const calculateMaximumWithdraw = ( withdrawAr: string ) => { const depositCellSerialized = serializeOutput(depositCell).slice(2).length / 2; - console.log(depositCellSerialized); const occupiedCapacity = JSBI.asUintN( 64, JSBI.multiply(JSBI.BigInt(100000000), JSBI.BigInt(depositCellSerialized)) From 7e5a8fc2b8fbb60e5d01ed8efba29f568031518e Mon Sep 17 00:00:00 2001 From: yanguoyu <841185308@qq.com> Date: Tue, 1 Mar 2022 09:18:01 +0800 Subject: [PATCH 4/8] move extract DAO to utils and add test --- packages/ckb-sdk-core/src/index.ts | 26 ++++------------- .../__tests__/utils/index.test.js | 14 ++++++++-- packages/ckb-sdk-utils/src/index.ts | 28 ++++++++++++++----- 3 files changed, 38 insertions(+), 30 deletions(-) diff --git a/packages/ckb-sdk-core/src/index.ts b/packages/ckb-sdk-core/src/index.ts index da3d050d..7c32a275 100644 --- a/packages/ckb-sdk-core/src/index.ts +++ b/packages/ckb-sdk-core/src/index.ts @@ -1,7 +1,7 @@ /// import RPC from '@nervosnetwork/ckb-sdk-rpc' -import { ParameterRequiredException, HexStringWithout0xException } from '@nervosnetwork/ckb-sdk-utils/lib/exceptions' +import { ParameterRequiredException } from '@nervosnetwork/ckb-sdk-utils/lib/exceptions' import * as utils from '@nervosnetwork/ckb-sdk-utils' import generateRawTransaction from './generateRawTransaction' @@ -428,25 +428,11 @@ class CKB { if (depositTx.txStatus.status !== 'committed') throw new Error('Transaction is not committed yet') const depositCell = depositTx.transaction.outputs[+outPoint.index] const depositBlockHash = depositTx.txStatus.blockHash - const depositHeader = await this.rpc.getHeader(depositBlockHash) - const depositAr = this.#extracDaoData(depositHeader.dao).ar - const withDrawHeader = await this.rpc.getHeader(withdrawBlockHash) - const withdrawAr = this.#extracDaoData(withDrawHeader.dao).ar - return utils.calculateMaximumWithdraw(depositCell, depositAr, withdrawAr); - } - - #extracDaoData = (dao: CKBComponents.DAO) => { - if (!dao.startsWith('0x')) { - throw new HexStringWithout0xException(dao) - } - const value = dao.replace('0x', ''); - const toBigEndian = utils.toBigEndian; - return { - c: toBigEndian(`0x${value.slice(0, 8)}`), - ar: toBigEndian(`0x${value.slice(16, 32)}`), - s: toBigEndian(`0x${value.slice(32, 48)}`), - u: toBigEndian(`0x${value.slice(48, 64)}`) - } + const [depositHeader, withDrawHeader] = await Promise.all([ + this.rpc.getHeader(depositBlockHash), + this.rpc.getHeader(withdrawBlockHash) + ]) + return utils.calculateMaximumWithdraw(depositCell, depositHeader.dao, withDrawHeader.dao); } #secp256k1DepsShouldBeReady = () => { diff --git a/packages/ckb-sdk-utils/__tests__/utils/index.test.js b/packages/ckb-sdk-utils/__tests__/utils/index.test.js index a7791c76..4fa6a20b 100644 --- a/packages/ckb-sdk-utils/__tests__/utils/index.test.js +++ b/packages/ckb-sdk-utils/__tests__/utils/index.test.js @@ -1,4 +1,4 @@ -const { privateKeyToPublicKey, privateKeyToAddress, scriptToHash, rawTransactionToHash, calculateMaximumWithdraw } = require('../..') +const { privateKeyToPublicKey, privateKeyToAddress, scriptToHash, rawTransactionToHash, calculateMaximumWithdraw, extractDAOData } = require('../..') const exceptions = require('../../lib/exceptions') const rawTransactionToHashFixtures = require('./rawTransactionToHash.fixtures.json') @@ -100,7 +100,15 @@ describe('calculate-maximum-withdraw', () => { expect( calculateMaximumWithdraw( outputCell, - '0x0025c969c0e8f93e', - '0x0025cb34dbf9c694' + '0x1aaf2ca6847c223c3ef9e8c069c9250020212a6311e2d30200609349396eb407', + '0x9bafffa73e432e3c94c6f9db34cb25009f9e4efe4b5fd60200ea63c6d4ffb407' )).toBe('1000182611968') +}) + +describe('extract header dao', () => { + const DAOData = extractDAOData('0x1aaf2ca6847c223c3ef9e8c069c9250020212a6311e2d30200609349396eb407'); + expect(DAOData.c).toBe('0x3c227c84a62caf1a'); + expect(DAOData.ar).toBe('0x0025c969c0e8f93e'); + expect(DAOData.s).toBe('0x02d3e211632a2120'); + expect(DAOData.u).toBe('0x07b46e3949936000'); }) \ No newline at end of file diff --git a/packages/ckb-sdk-utils/src/index.ts b/packages/ckb-sdk-utils/src/index.ts index c966d513..e5ffde1c 100644 --- a/packages/ckb-sdk-utils/src/index.ts +++ b/packages/ckb-sdk-utils/src/index.ts @@ -1,8 +1,8 @@ import JSBI from 'jsbi' import ECPair from './ecpair' -import { hexToBytes } from './convertors' +import { hexToBytes, toBigEndian } from './convertors' import { pubkeyToAddress, AddressOptions } from './address' -import { ParameterRequiredException } from './exceptions' +import { ParameterRequiredException, HexStringWithout0xException } from './exceptions' import crypto from './crypto' import { serializeOutput, serializeScript } from './serialization'; import { serializeRawTransaction, serializeTransaction, serializeWitnessArgs } from './serialization/transaction' @@ -45,10 +45,24 @@ export const privateKeyToPublicKey = (privateKey: string) => { export const privateKeyToAddress = (privateKey: string, options: AddressOptions) => pubkeyToAddress(privateKeyToPublicKey(privateKey), options) + +export const extractDAOData = (dao: CKBComponents.DAO) => { + if (!dao.startsWith('0x')) { + throw new HexStringWithout0xException(dao) + } + const value = dao.replace('0x', ''); + return { + c: toBigEndian(`0x${value.slice(0, 16)}`), + ar: toBigEndian(`0x${value.slice(16, 32)}`), + s: toBigEndian(`0x${value.slice(32, 48)}`), + u: toBigEndian(`0x${value.slice(48, 64)}`) + } +} + export const calculateMaximumWithdraw = ( depositCell: CKBComponents.CellOutput, - depositAr: string, - withdrawAr: string + depositDAO: CKBComponents.DAO, + withdrawDAO: CKBComponents.DAO ) => { const depositCellSerialized = serializeOutput(depositCell).slice(2).length / 2; const occupiedCapacity = JSBI.asUintN( @@ -62,10 +76,10 @@ export const calculateMaximumWithdraw = ( JSBI.asUintN(64, JSBI.BigInt(depositCell.capacity)), occupiedCapacity ), - JSBI.asUintN(64, JSBI.BigInt(withdrawAr)) + JSBI.asUintN(64, JSBI.BigInt(extractDAOData(withdrawDAO).ar)) ), - JSBI.asUintN(64, JSBI.BigInt(depositAr)) + JSBI.asUintN(64, JSBI.BigInt(extractDAOData(depositDAO).ar)) ), occupiedCapacity ).toString() -} \ No newline at end of file +} From ed53a49d257d5ab0040aa165d5566e422b35819c Mon Sep 17 00:00:00 2001 From: yanguoyu <841185308@qq.com> Date: Tue, 1 Mar 2022 09:23:57 +0800 Subject: [PATCH 5/8] add test for calculateDaoMaximumWithdraw --- packages/ckb-sdk-core/__tests__/index.test.js | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/packages/ckb-sdk-core/__tests__/index.test.js b/packages/ckb-sdk-core/__tests__/index.test.js index 64534542..81b66fed 100644 --- a/packages/ckb-sdk-core/__tests__/index.test.js +++ b/packages/ckb-sdk-core/__tests__/index.test.js @@ -176,4 +176,44 @@ describe('ckb', () => { expect(tx).toEqual(expected) }) }) + + describe('calculate dao maximum withdraw', () => { + it('normal', async () => { + ckb.rpc = { + getTransaction: jest.fn().mockResolvedValueOnce({ + txStatus: { status: 'committed' }, + transaction: { + outputs: [ + { + "capacity":"0xe8d4a51000", + "lock":{ + "args":"0xf601cac75568afec3b9c9af1e1ff730062007685", + "codeHash":"0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8", + "hashType":"type" + }, + "type":{ + "args":"0x", + "codeHash":"0x82d76d1b75fe2fd9a27dfbaa65a039221a380d76c926f378d3f81cf3e7e13f2e", + "hashType":"type" + } + } + ] + } + }), + getHeader: jest.fn() + .mockResolvedValueOnce({ dao: '0x1aaf2ca6847c223c3ef9e8c069c9250020212a6311e2d30200609349396eb407' }) + .mockResolvedValueOnce({ dao: '0x9bafffa73e432e3c94c6f9db34cb25009f9e4efe4b5fd60200ea63c6d4ffb407' }) + } + const res = await ckb.calculateDaoMaximumWithdraw({ tx: '', index: '0x0' }, '') + expect(res).toBe('1000182611968'); + ckb.rpc = rpc; + }) + it('exception', async () => { + ckb.rpc = { + getTransaction: jest.fn().mockResolvedValueOnce({ txStatus: {}}) + } + await expect(ckb.calculateDaoMaximumWithdraw({ tx: '', index: '0x0' }, '')).rejects.toThrow('Transaction is not committed yet') + ckb.rpc = rpc; + }) + }) }) From b8da57f444bdb798f544a83a0fb8a7b375d0a54e Mon Sep 17 00:00:00 2001 From: yanguoyu <841185308@qq.com> Date: Wed, 2 Mar 2022 09:32:04 +0800 Subject: [PATCH 6/8] fix 1: cal occupied capacity don't use serialize data 2: calculateDaoMaximumWithdraw second params accept two kind --- packages/ckb-sdk-core/__tests__/index.test.js | 93 ++++++++++++++++++- packages/ckb-sdk-core/src/index.ts | 30 ++++-- .../__tests__/utils/index.test.js | 3 +- .../__tests__/utils/occupiedCapacity.test.js | 51 ++++++++++ packages/ckb-sdk-utils/src/index.ts | 21 +++-- .../ckb-sdk-utils/src/occupiedCapacity.ts | 7 ++ 6 files changed, 185 insertions(+), 20 deletions(-) create mode 100644 packages/ckb-sdk-utils/__tests__/utils/occupiedCapacity.test.js create mode 100644 packages/ckb-sdk-utils/src/occupiedCapacity.ts diff --git a/packages/ckb-sdk-core/__tests__/index.test.js b/packages/ckb-sdk-core/__tests__/index.test.js index 81b66fed..dd4a202a 100644 --- a/packages/ckb-sdk-core/__tests__/index.test.js +++ b/packages/ckb-sdk-core/__tests__/index.test.js @@ -178,7 +178,7 @@ describe('ckb', () => { }) describe('calculate dao maximum withdraw', () => { - it('normal', async () => { + it('normal withdraw hash', async () => { ckb.rpc = { getTransaction: jest.fn().mockResolvedValueOnce({ txStatus: { status: 'committed' }, @@ -197,7 +197,8 @@ describe('ckb', () => { "hashType":"type" } } - ] + ], + outputsData: ["0x0000000000000000","0x"] } }), getHeader: jest.fn() @@ -205,7 +206,93 @@ describe('ckb', () => { .mockResolvedValueOnce({ dao: '0x9bafffa73e432e3c94c6f9db34cb25009f9e4efe4b5fd60200ea63c6d4ffb407' }) } const res = await ckb.calculateDaoMaximumWithdraw({ tx: '', index: '0x0' }, '') - expect(res).toBe('1000182611968'); + expect(res).toBe('1000183501854'); + ckb.rpc = rpc; + }) + it('another normal withdraw hash', async () => { + ckb.rpc = { + getTransaction: jest.fn().mockResolvedValueOnce({ + "transaction":{ + "outputs":[ + { + "capacity":"0x6fc23ac00", + "lock":{ + "args":"0x4cc2e6526204ae6a2e8fcf12f7ad472f41a1606d5b9624beebd215d780809f6aa10000001000000030000000990000009cdfb2824302e0cd0ee1fb4ac9849c8c2348ab84f2e7d2c6e12e8b6f5f5f378d69000000100000003000000031000000deec13a7b8e100579541384ccaf4b5223733e4a5483c3aec95ddc4c1d5ea5b2201340000004cc2e6526204ae6a2e8fcf12f7ad472f41a1606d5b9624beebd215d780809f6a153ab336340f7985b8b9e412b7968fedabd69a9cb0040000000000c0", + "codeHash":"0x5a2506bb68d81a11dcadad4cb7eae62a17c43c619fe47ac8037bc8ce2dd90360", + "hashType":"type" + }, + "type":null + }, + { + "capacity":"0x83e607de09", + "lock":{ + "args":"0x2718f00d61e6fb37eed98cfdf6b30bde38cad8f6", + "codeHash":"0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8", + "hashType":"type" + }, + "type":null + } + ], + "outputsData":[ + "0x", + "0x" + ], + }, + "txStatus":{ + "blockHash":"0x8c14f374c5934613dbb0f9cbebb0edaabe259291a08e2dd3afbb291b1b8be359", + "reason":null, + "status":"committed" + } + }), + getHeader: jest.fn() + .mockResolvedValueOnce({ dao: '0x7e9a4d29f532433cb8dbe56b64ce2500b4c9c67a3fccda020098a1f224a4b707' }) + .mockResolvedValueOnce({ dao: '0xd87090655733433c2395d67a64ce2500d73e963e54ccda0200f244c504a4b707' }) + } + const res = await ckb.calculateDaoMaximumWithdraw({index: '0x0', txHash: '0xabd4f1b9e914cd859cb7ecf4f57009ef7cd2d84a799ed61acff904bdf5fea91a'}, '0x04914c83fa9ea4126279ebe2d2cdff74235f63227821882e4e16f6a908f43691') + expect(res).toBe('30000000155'); + ckb.rpc = rpc; + }) + it('normal withdraw outputpoint', async () => { + ckb.rpc = { + getTransaction: jest.fn().mockResolvedValue({ + "transaction":{ + "outputs":[ + { + "capacity":"0x6fc23ac00", + "lock":{ + "args":"0x4cc2e6526204ae6a2e8fcf12f7ad472f41a1606d5b9624beebd215d780809f6aa10000001000000030000000990000009cdfb2824302e0cd0ee1fb4ac9849c8c2348ab84f2e7d2c6e12e8b6f5f5f378d69000000100000003000000031000000deec13a7b8e100579541384ccaf4b5223733e4a5483c3aec95ddc4c1d5ea5b2201340000004cc2e6526204ae6a2e8fcf12f7ad472f41a1606d5b9624beebd215d780809f6a153ab336340f7985b8b9e412b7968fedabd69a9cb0040000000000c0", + "codeHash":"0x5a2506bb68d81a11dcadad4cb7eae62a17c43c619fe47ac8037bc8ce2dd90360", + "hashType":"type" + }, + "type":null + }, + { + "capacity":"0x83e607de09", + "lock":{ + "args":"0x2718f00d61e6fb37eed98cfdf6b30bde38cad8f6", + "codeHash":"0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8", + "hashType":"type" + }, + "type":null + } + ], + "outputsData":[ + "0x", + "0x" + ], + }, + "txStatus":{ + "blockHash":"0x8c14f374c5934613dbb0f9cbebb0edaabe259291a08e2dd3afbb291b1b8be359", + "reason":null, + "status":"committed" + } + }), + getHeader: jest.fn() + .mockResolvedValueOnce({ dao: '0x7e9a4d29f532433cb8dbe56b64ce2500b4c9c67a3fccda020098a1f224a4b707' }) + .mockResolvedValueOnce({ dao: '0xd87090655733433c2395d67a64ce2500d73e963e54ccda0200f244c504a4b707' }) + } + const res = await ckb.calculateDaoMaximumWithdraw({index: '0x0', txHash: '0xabd4f1b9e914cd859cb7ecf4f57009ef7cd2d84a799ed61acff904bdf5fea91a'}, '0x04914c83fa9ea4126279ebe2d2cdff74235f63227821882e4e16f6a908f43691') + expect(res).toBe('30000000155'); ckb.rpc = rpc; }) it('exception', async () => { diff --git a/packages/ckb-sdk-core/src/index.ts b/packages/ckb-sdk-core/src/index.ts index 7c32a275..e44edf9e 100644 --- a/packages/ckb-sdk-core/src/index.ts +++ b/packages/ckb-sdk-core/src/index.ts @@ -421,18 +421,34 @@ class CKB { } public calculateDaoMaximumWithdraw = async ( - outPoint: CKBComponents.OutPoint, - withdrawBlockHash: string + depositOutPoint: CKBComponents.OutPoint, + withdraw: CKBComponents.Hash | CKBComponents.OutPoint ): Promise => { - const depositTx = await this.rpc.getTransaction(outPoint.txHash) - if (depositTx.txStatus.status !== 'committed') throw new Error('Transaction is not committed yet') - const depositCell = depositTx.transaction.outputs[+outPoint.index] - const depositBlockHash = depositTx.txStatus.blockHash + let tx = await this.rpc.getTransaction(depositOutPoint.txHash) + if (tx.txStatus.status !== 'committed') throw new Error('Transaction is not committed yet') + const depositBlockHash = tx.txStatus.blockHash + let celloutput = tx.transaction.outputs[+depositOutPoint.index]; + let celloutputData = tx.transaction.outputsData[+depositOutPoint.index]; + let withdrawBlockHash: CKBComponents.Hash; + if (typeof withdraw === 'string') { + withdrawBlockHash = withdraw + } else { + tx = await this.rpc.getTransaction(withdraw.txHash); + if (tx.txStatus.status !== 'committed') throw new Error('Transaction is not committed yet') + withdrawBlockHash = tx.txStatus.blockHash; + celloutput = tx.transaction.outputs[+withdraw.index]; + celloutputData = tx.transaction.outputsData[+withdraw.index]; + } const [depositHeader, withDrawHeader] = await Promise.all([ this.rpc.getHeader(depositBlockHash), this.rpc.getHeader(withdrawBlockHash) ]) - return utils.calculateMaximumWithdraw(depositCell, depositHeader.dao, withDrawHeader.dao); + return utils.calculateMaximumWithdraw( + celloutput, + celloutputData, + depositHeader.dao, + withDrawHeader.dao + ) } #secp256k1DepsShouldBeReady = () => { diff --git a/packages/ckb-sdk-utils/__tests__/utils/index.test.js b/packages/ckb-sdk-utils/__tests__/utils/index.test.js index 4fa6a20b..4f56de37 100644 --- a/packages/ckb-sdk-utils/__tests__/utils/index.test.js +++ b/packages/ckb-sdk-utils/__tests__/utils/index.test.js @@ -100,9 +100,10 @@ describe('calculate-maximum-withdraw', () => { expect( calculateMaximumWithdraw( outputCell, + '0x0000000000000000', '0x1aaf2ca6847c223c3ef9e8c069c9250020212a6311e2d30200609349396eb407', '0x9bafffa73e432e3c94c6f9db34cb25009f9e4efe4b5fd60200ea63c6d4ffb407' - )).toBe('1000182611968') + )).toBe('1000183501854') }) describe('extract header dao', () => { diff --git a/packages/ckb-sdk-utils/__tests__/utils/occupiedCapacity.test.js b/packages/ckb-sdk-utils/__tests__/utils/occupiedCapacity.test.js new file mode 100644 index 00000000..a9d36541 --- /dev/null +++ b/packages/ckb-sdk-utils/__tests__/utils/occupiedCapacity.test.js @@ -0,0 +1,51 @@ +const { scriptOccupied, cellOccupied } = require('../..') + +describe('script occupied', () => { + it('no args', () => { + const occupied = scriptOccupied({ + args: '0x', + codeHash: '0x82d76d1b75fe2fd9a27dfbaa65a039221a380d76c926f378d3f81cf3e7e13f2e', + hashType: 'type' + }); + expect(occupied).toBe(33); + }) + it('with args', () => { + const occupied = scriptOccupied({ + args: '0x00ffee', + codeHash: '0x82d76d1b75fe2fd9a27dfbaa65a039221a380d76c926f378d3f81cf3e7e13f2e', + hashType: 'type' + }); + expect(occupied).toBe(36); + }) +}) + + +describe('cell occupied', () => { + it('no type', () => { + const occupied = cellOccupied({ + capacity: '0xe8d4a51000', + lock: { + args: '0x', + codeHash: '0x82d76d1b75fe2fd9a27dfbaa65a039221a380d76c926f378d3f81cf3e7e13f2e', + hashType: 'type' + }, + }); + expect(occupied).toBe(41); + }) + it('with type', () => { + const occupied = cellOccupied({ + capacity: '0xe8d4a51000', + lock: { + args: '0x', + codeHash: '0x82d76d1b75fe2fd9a27dfbaa65a039221a380d76c926f378d3f81cf3e7e13f2e', + hashType: 'type' + }, + type: { + args: '0x00ff', + codeHash: '0x82d76d1b75fe2fd9a27dfbaa65a039221a380d76c926f378d3f81cf3e7e13f2e', + hashType: 'type' + } + }); + expect(occupied).toBe(76); + }) +}) \ No newline at end of file diff --git a/packages/ckb-sdk-utils/src/index.ts b/packages/ckb-sdk-utils/src/index.ts index e5ffde1c..4a62d4e5 100644 --- a/packages/ckb-sdk-utils/src/index.ts +++ b/packages/ckb-sdk-utils/src/index.ts @@ -4,7 +4,8 @@ import { hexToBytes, toBigEndian } from './convertors' import { pubkeyToAddress, AddressOptions } from './address' import { ParameterRequiredException, HexStringWithout0xException } from './exceptions' import crypto from './crypto' -import { serializeOutput, serializeScript } from './serialization'; +import { serializeScript } from './serialization' +import { cellOccupied } from './occupiedCapacity' import { serializeRawTransaction, serializeTransaction, serializeWitnessArgs } from './serialization/transaction' import { PERSONAL } from './const' @@ -13,6 +14,7 @@ export * from './serialization' export * from './convertors' export * from './epochs' export * from './sizes' +export * from './occupiedCapacity' export * as systemScripts from './systemScripts' export * as reconcilers from './reconcilers' @@ -50,7 +52,7 @@ export const extractDAOData = (dao: CKBComponents.DAO) => { if (!dao.startsWith('0x')) { throw new HexStringWithout0xException(dao) } - const value = dao.replace('0x', ''); + const value = dao.replace('0x', '') return { c: toBigEndian(`0x${value.slice(0, 16)}`), ar: toBigEndian(`0x${value.slice(16, 32)}`), @@ -60,25 +62,26 @@ export const extractDAOData = (dao: CKBComponents.DAO) => { } export const calculateMaximumWithdraw = ( - depositCell: CKBComponents.CellOutput, + outputCell: CKBComponents.CellOutput, + outputDataCapacity: CKBComponents.Bytes, depositDAO: CKBComponents.DAO, withdrawDAO: CKBComponents.DAO ) => { - const depositCellSerialized = serializeOutput(depositCell).slice(2).length / 2; + const depositCellSerialized = cellOccupied(outputCell) + outputDataCapacity.slice(2).length / 2 const occupiedCapacity = JSBI.asUintN( - 64, + 128, JSBI.multiply(JSBI.BigInt(100000000), JSBI.BigInt(depositCellSerialized)) - ); + ) return JSBI.add( JSBI.divide( JSBI.multiply( JSBI.subtract( - JSBI.asUintN(64, JSBI.BigInt(depositCell.capacity)), + JSBI.asUintN(128, JSBI.BigInt(outputCell.capacity)), occupiedCapacity ), - JSBI.asUintN(64, JSBI.BigInt(extractDAOData(withdrawDAO).ar)) + JSBI.asUintN(128, JSBI.BigInt(extractDAOData(withdrawDAO).ar)) ), - JSBI.asUintN(64, JSBI.BigInt(extractDAOData(depositDAO).ar)) + JSBI.asUintN(128, JSBI.BigInt(extractDAOData(depositDAO).ar)) ), occupiedCapacity ).toString() diff --git a/packages/ckb-sdk-utils/src/occupiedCapacity.ts b/packages/ckb-sdk-utils/src/occupiedCapacity.ts new file mode 100644 index 00000000..0365e928 --- /dev/null +++ b/packages/ckb-sdk-utils/src/occupiedCapacity.ts @@ -0,0 +1,7 @@ +export const scriptOccupied = (script: CKBComponents.Script) => { + return script.args.slice(2).length / 2 + 32 + 1 +} + +export const cellOccupied = (cell: CKBComponents.CellOutput) => { + return 8 + scriptOccupied(cell.lock) + (cell.type ? scriptOccupied(cell.type) : 0) +} \ No newline at end of file From cbe3765c6124d09c8e18796ff161394359df5f7f Mon Sep 17 00:00:00 2001 From: yanguoyu <841185308@qq.com> Date: Wed, 2 Mar 2022 09:34:11 +0800 Subject: [PATCH 7/8] delete ; --- packages/ckb-sdk-core/__tests__/index.test.js | 14 +++++++------- packages/ckb-sdk-core/src/index.ts | 14 +++++++------- .../ckb-sdk-utils/__tests__/utils/index.test.js | 12 ++++++------ .../__tests__/utils/occupiedCapacity.test.js | 16 ++++++++-------- 4 files changed, 28 insertions(+), 28 deletions(-) diff --git a/packages/ckb-sdk-core/__tests__/index.test.js b/packages/ckb-sdk-core/__tests__/index.test.js index dd4a202a..d2d6649b 100644 --- a/packages/ckb-sdk-core/__tests__/index.test.js +++ b/packages/ckb-sdk-core/__tests__/index.test.js @@ -206,8 +206,8 @@ describe('ckb', () => { .mockResolvedValueOnce({ dao: '0x9bafffa73e432e3c94c6f9db34cb25009f9e4efe4b5fd60200ea63c6d4ffb407' }) } const res = await ckb.calculateDaoMaximumWithdraw({ tx: '', index: '0x0' }, '') - expect(res).toBe('1000183501854'); - ckb.rpc = rpc; + expect(res).toBe('1000183501854') + ckb.rpc = rpc }) it('another normal withdraw hash', async () => { ckb.rpc = { @@ -249,8 +249,8 @@ describe('ckb', () => { .mockResolvedValueOnce({ dao: '0xd87090655733433c2395d67a64ce2500d73e963e54ccda0200f244c504a4b707' }) } const res = await ckb.calculateDaoMaximumWithdraw({index: '0x0', txHash: '0xabd4f1b9e914cd859cb7ecf4f57009ef7cd2d84a799ed61acff904bdf5fea91a'}, '0x04914c83fa9ea4126279ebe2d2cdff74235f63227821882e4e16f6a908f43691') - expect(res).toBe('30000000155'); - ckb.rpc = rpc; + expect(res).toBe('30000000155') + ckb.rpc = rpc }) it('normal withdraw outputpoint', async () => { ckb.rpc = { @@ -292,15 +292,15 @@ describe('ckb', () => { .mockResolvedValueOnce({ dao: '0xd87090655733433c2395d67a64ce2500d73e963e54ccda0200f244c504a4b707' }) } const res = await ckb.calculateDaoMaximumWithdraw({index: '0x0', txHash: '0xabd4f1b9e914cd859cb7ecf4f57009ef7cd2d84a799ed61acff904bdf5fea91a'}, '0x04914c83fa9ea4126279ebe2d2cdff74235f63227821882e4e16f6a908f43691') - expect(res).toBe('30000000155'); - ckb.rpc = rpc; + expect(res).toBe('30000000155') + ckb.rpc = rpc }) it('exception', async () => { ckb.rpc = { getTransaction: jest.fn().mockResolvedValueOnce({ txStatus: {}}) } await expect(ckb.calculateDaoMaximumWithdraw({ tx: '', index: '0x0' }, '')).rejects.toThrow('Transaction is not committed yet') - ckb.rpc = rpc; + ckb.rpc = rpc }) }) }) diff --git a/packages/ckb-sdk-core/src/index.ts b/packages/ckb-sdk-core/src/index.ts index e44edf9e..fe42a28a 100644 --- a/packages/ckb-sdk-core/src/index.ts +++ b/packages/ckb-sdk-core/src/index.ts @@ -427,17 +427,17 @@ class CKB { let tx = await this.rpc.getTransaction(depositOutPoint.txHash) if (tx.txStatus.status !== 'committed') throw new Error('Transaction is not committed yet') const depositBlockHash = tx.txStatus.blockHash - let celloutput = tx.transaction.outputs[+depositOutPoint.index]; - let celloutputData = tx.transaction.outputsData[+depositOutPoint.index]; - let withdrawBlockHash: CKBComponents.Hash; + let celloutput = tx.transaction.outputs[+depositOutPoint.index] + let celloutputData = tx.transaction.outputsData[+depositOutPoint.index] + let withdrawBlockHash: CKBComponents.Hash if (typeof withdraw === 'string') { withdrawBlockHash = withdraw } else { - tx = await this.rpc.getTransaction(withdraw.txHash); + tx = await this.rpc.getTransaction(withdraw.txHash) if (tx.txStatus.status !== 'committed') throw new Error('Transaction is not committed yet') - withdrawBlockHash = tx.txStatus.blockHash; - celloutput = tx.transaction.outputs[+withdraw.index]; - celloutputData = tx.transaction.outputsData[+withdraw.index]; + withdrawBlockHash = tx.txStatus.blockHash + celloutput = tx.transaction.outputs[+withdraw.index] + celloutputData = tx.transaction.outputsData[+withdraw.index] } const [depositHeader, withDrawHeader] = await Promise.all([ this.rpc.getHeader(depositBlockHash), diff --git a/packages/ckb-sdk-utils/__tests__/utils/index.test.js b/packages/ckb-sdk-utils/__tests__/utils/index.test.js index 4f56de37..9bf301c6 100644 --- a/packages/ckb-sdk-utils/__tests__/utils/index.test.js +++ b/packages/ckb-sdk-utils/__tests__/utils/index.test.js @@ -96,7 +96,7 @@ describe('calculate-maximum-withdraw', () => { "codeHash":"0x82d76d1b75fe2fd9a27dfbaa65a039221a380d76c926f378d3f81cf3e7e13f2e", "hashType":"type" } - }; + } expect( calculateMaximumWithdraw( outputCell, @@ -107,9 +107,9 @@ describe('calculate-maximum-withdraw', () => { }) describe('extract header dao', () => { - const DAOData = extractDAOData('0x1aaf2ca6847c223c3ef9e8c069c9250020212a6311e2d30200609349396eb407'); - expect(DAOData.c).toBe('0x3c227c84a62caf1a'); - expect(DAOData.ar).toBe('0x0025c969c0e8f93e'); - expect(DAOData.s).toBe('0x02d3e211632a2120'); - expect(DAOData.u).toBe('0x07b46e3949936000'); + const DAOData = extractDAOData('0x1aaf2ca6847c223c3ef9e8c069c9250020212a6311e2d30200609349396eb407') + expect(DAOData.c).toBe('0x3c227c84a62caf1a') + expect(DAOData.ar).toBe('0x0025c969c0e8f93e') + expect(DAOData.s).toBe('0x02d3e211632a2120') + expect(DAOData.u).toBe('0x07b46e3949936000') }) \ No newline at end of file diff --git a/packages/ckb-sdk-utils/__tests__/utils/occupiedCapacity.test.js b/packages/ckb-sdk-utils/__tests__/utils/occupiedCapacity.test.js index a9d36541..7741fb25 100644 --- a/packages/ckb-sdk-utils/__tests__/utils/occupiedCapacity.test.js +++ b/packages/ckb-sdk-utils/__tests__/utils/occupiedCapacity.test.js @@ -6,16 +6,16 @@ describe('script occupied', () => { args: '0x', codeHash: '0x82d76d1b75fe2fd9a27dfbaa65a039221a380d76c926f378d3f81cf3e7e13f2e', hashType: 'type' - }); - expect(occupied).toBe(33); + }) + expect(occupied).toBe(33) }) it('with args', () => { const occupied = scriptOccupied({ args: '0x00ffee', codeHash: '0x82d76d1b75fe2fd9a27dfbaa65a039221a380d76c926f378d3f81cf3e7e13f2e', hashType: 'type' - }); - expect(occupied).toBe(36); + }) + expect(occupied).toBe(36) }) }) @@ -29,8 +29,8 @@ describe('cell occupied', () => { codeHash: '0x82d76d1b75fe2fd9a27dfbaa65a039221a380d76c926f378d3f81cf3e7e13f2e', hashType: 'type' }, - }); - expect(occupied).toBe(41); + }) + expect(occupied).toBe(41) }) it('with type', () => { const occupied = cellOccupied({ @@ -45,7 +45,7 @@ describe('cell occupied', () => { codeHash: '0x82d76d1b75fe2fd9a27dfbaa65a039221a380d76c926f378d3f81cf3e7e13f2e', hashType: 'type' } - }); - expect(occupied).toBe(76); + }) + expect(occupied).toBe(76) }) }) \ No newline at end of file From 8cd4f45aa852444276e15efe555fcb6f1289a435 Mon Sep 17 00:00:00 2001 From: yanguoyu <841185308@qq.com> Date: Wed, 2 Mar 2022 14:09:45 +0800 Subject: [PATCH 8/8] change calculateMaximumWithdraw return value to hex string --- packages/ckb-sdk-core/__tests__/index.test.js | 6 +++--- packages/ckb-sdk-utils/__tests__/utils/index.test.js | 2 +- packages/ckb-sdk-utils/src/index.ts | 4 ++-- packages/ckb-sdk-utils/src/occupiedCapacity.ts | 5 ++++- 4 files changed, 10 insertions(+), 7 deletions(-) diff --git a/packages/ckb-sdk-core/__tests__/index.test.js b/packages/ckb-sdk-core/__tests__/index.test.js index d2d6649b..f2b8bfd2 100644 --- a/packages/ckb-sdk-core/__tests__/index.test.js +++ b/packages/ckb-sdk-core/__tests__/index.test.js @@ -206,7 +206,7 @@ describe('ckb', () => { .mockResolvedValueOnce({ dao: '0x9bafffa73e432e3c94c6f9db34cb25009f9e4efe4b5fd60200ea63c6d4ffb407' }) } const res = await ckb.calculateDaoMaximumWithdraw({ tx: '', index: '0x0' }, '') - expect(res).toBe('1000183501854') + expect(res).toBe('0xe8df95141e') ckb.rpc = rpc }) it('another normal withdraw hash', async () => { @@ -249,7 +249,7 @@ describe('ckb', () => { .mockResolvedValueOnce({ dao: '0xd87090655733433c2395d67a64ce2500d73e963e54ccda0200f244c504a4b707' }) } const res = await ckb.calculateDaoMaximumWithdraw({index: '0x0', txHash: '0xabd4f1b9e914cd859cb7ecf4f57009ef7cd2d84a799ed61acff904bdf5fea91a'}, '0x04914c83fa9ea4126279ebe2d2cdff74235f63227821882e4e16f6a908f43691') - expect(res).toBe('30000000155') + expect(res).toBe('0x6fc23ac9b') ckb.rpc = rpc }) it('normal withdraw outputpoint', async () => { @@ -292,7 +292,7 @@ describe('ckb', () => { .mockResolvedValueOnce({ dao: '0xd87090655733433c2395d67a64ce2500d73e963e54ccda0200f244c504a4b707' }) } const res = await ckb.calculateDaoMaximumWithdraw({index: '0x0', txHash: '0xabd4f1b9e914cd859cb7ecf4f57009ef7cd2d84a799ed61acff904bdf5fea91a'}, '0x04914c83fa9ea4126279ebe2d2cdff74235f63227821882e4e16f6a908f43691') - expect(res).toBe('30000000155') + expect(res).toBe('0x6fc23ac9b') ckb.rpc = rpc }) it('exception', async () => { diff --git a/packages/ckb-sdk-utils/__tests__/utils/index.test.js b/packages/ckb-sdk-utils/__tests__/utils/index.test.js index 9bf301c6..c818e614 100644 --- a/packages/ckb-sdk-utils/__tests__/utils/index.test.js +++ b/packages/ckb-sdk-utils/__tests__/utils/index.test.js @@ -103,7 +103,7 @@ describe('calculate-maximum-withdraw', () => { '0x0000000000000000', '0x1aaf2ca6847c223c3ef9e8c069c9250020212a6311e2d30200609349396eb407', '0x9bafffa73e432e3c94c6f9db34cb25009f9e4efe4b5fd60200ea63c6d4ffb407' - )).toBe('1000183501854') + )).toBe('0xe8df95141e') }) describe('extract header dao', () => { diff --git a/packages/ckb-sdk-utils/src/index.ts b/packages/ckb-sdk-utils/src/index.ts index 4a62d4e5..3326cacb 100644 --- a/packages/ckb-sdk-utils/src/index.ts +++ b/packages/ckb-sdk-utils/src/index.ts @@ -72,7 +72,7 @@ export const calculateMaximumWithdraw = ( 128, JSBI.multiply(JSBI.BigInt(100000000), JSBI.BigInt(depositCellSerialized)) ) - return JSBI.add( + return `0x${JSBI.add( JSBI.divide( JSBI.multiply( JSBI.subtract( @@ -84,5 +84,5 @@ export const calculateMaximumWithdraw = ( JSBI.asUintN(128, JSBI.BigInt(extractDAOData(depositDAO).ar)) ), occupiedCapacity - ).toString() + ).toString(16)}` } diff --git a/packages/ckb-sdk-utils/src/occupiedCapacity.ts b/packages/ckb-sdk-utils/src/occupiedCapacity.ts index 0365e928..45729d92 100644 --- a/packages/ckb-sdk-utils/src/occupiedCapacity.ts +++ b/packages/ckb-sdk-utils/src/occupiedCapacity.ts @@ -1,5 +1,8 @@ +const codeHashOccupied = 32 +const hashTypeOccupied = 1 + export const scriptOccupied = (script: CKBComponents.Script) => { - return script.args.slice(2).length / 2 + 32 + 1 + return script.args.slice(2).length / 2 + codeHashOccupied + hashTypeOccupied } export const cellOccupied = (cell: CKBComponents.CellOutput) => {