Skip to content

Commit

Permalink
Add DfTx TokenUpdate, TokenUpdateAny (#300)
Browse files Browse the repository at this point in the history
Co-authored-by: Fuxing Loh <[email protected]>
  • Loading branch information
canonbrother and fuxingloh authored May 28, 2021
1 parent a7a9637 commit 31ec934
Show file tree
Hide file tree
Showing 5 changed files with 211 additions and 3 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import { SmartBuffer } from 'smart-buffer'
import { OP_DEFI_TX } from '../../../../src/script/defi'
import { CTokenUpdate, TokenUpdate } from '../../../../src/script/defi/dftx_token'
import { OP_CODES } from '../../../../src/script'
import { toBuffer, toOPCodes } from '../../../../src/script/_buffer'

it('should bi-directional buffer-object-buffer', () => {
const fixtures = [
// regtest fixtures
// 1 fixture as only 'isDAT' flag modification allowed before Bayfront fork
// and only 'UpdateToken' is triggered while before Bayfront fork
// https://github.com/DeFiCh/ain/blob/c7b13959cc84c6d6210927b0e2377432c0dcadeb/src/masternodes/rpc_tokens.cpp#L278
'6a26446654784effe50b27cd4325e9a87401e833a9caccf256e0b4ea37b6c4fb038bedc1cb247100'

// BUG(canonbrother): isDAT is not updated after modified
// Issue is submitted: https://github.com/DeFiCh/ain/issues/440
]

fixtures.forEach(hex => {
const stack: any = toOPCodes(
SmartBuffer.fromBuffer(Buffer.from(hex, 'hex'))
)
const buffer = toBuffer(stack)
expect(buffer.toString('hex')).toBe(hex)
expect((stack[1] as OP_DEFI_TX).tx.type).toBe(0x4e)
})
})

const header = '6a26446654784e' // OP_RETURN, PUSH_DATA(44665478, 4e)
const data = 'ffe50b27cd4325e9a87401e833a9caccf256e0b4ea37b6c4fb038bedc1cb247100'
const tokenUpdate: TokenUpdate = {
isDAT: false,
creationTx: '7124cbc1ed8b03fbc4b637eab4e056f2cccaa933e80174a8e92543cd270be5ff'
}

it('should craft dftx with OP_CODES._()', () => {
const stack = [
OP_CODES.OP_RETURN,
OP_CODES.OP_DEFI_TX_TOKEN_UPDATE(tokenUpdate)
]

const buffer = toBuffer(stack)
expect(buffer.toString('hex')).toBe(header + data)
})

describe('Composable', () => {
it('should compose from buffer to composable', () => {
const buffer = SmartBuffer.fromBuffer(Buffer.from(data, 'hex'))
const composable = new CTokenUpdate(buffer)

expect(composable.toObject()).toEqual(tokenUpdate)
})

it('should compose from composable to buffer', () => {
const composable = new CTokenUpdate(tokenUpdate)
const buffer = new SmartBuffer()
composable.toBuffer(buffer)

expect(buffer.toBuffer().toString('hex')).toEqual(data)
})
})
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import { SmartBuffer } from 'smart-buffer'
import { OP_DEFI_TX } from '../../../../src/script/defi'
import { CTokenUpdateAny, TokenUpdateAny } from '../../../../src/script/defi/dftx_token'
import { OP_CODES } from '../../../../src/script'
import { toBuffer, toOPCodes } from '../../../../src/script/_buffer'
import BigNumber from 'bignumber.js'

it('should bi-directional buffer-object-buffer', () => {
const fixtures = [
// regtest fixtures
// flags
'6a37446654786ed819f622ced3616e3c02e5337b54cbf921c364e182a80925219e1f60461ee5fc034341540343415408000000000000000001',

// symbol (symbolKey)
'6a38446654786effe50b27cd4325e9a87401e833a9caccf256e0b4ea37b6c4fb038bedc1cb2471044f57574c034f574c08000000000000000007',

// name
'6a39446654786effe50b27cd4325e9a87401e833a9caccf256e0b4ea37b6c4fb038bedc1cb2471034f574c054e4947485408000000000000000007'
]

fixtures.forEach(hex => {
const stack: any = toOPCodes(
SmartBuffer.fromBuffer(Buffer.from(hex, 'hex'))
)
const buffer = toBuffer(stack)
expect(buffer.toString('hex')).toBe(hex)
expect((stack[1] as OP_DEFI_TX).tx.type).toBe(0x6e)
})
})

const header = '6a37446654786e' // OP_RETURN, PUSH_DATA(44665478, 6e)
const data = 'd819f622ced3616e3c02e5337b54cbf921c364e182a80925219e1f60461ee5fc034341540343415408000000000000000007'
const tokenUpdateAny: TokenUpdateAny = {
symbol: 'CAT',
name: 'CAT',
decimal: 8,
limit: new BigNumber('0'),
mintable: true,
tradeable: true,
isDAT: true,
creationTx: 'fce51e46601f9e212509a882e164c321f9cb547b33e5023c6e61d3ce22f619d8'
}

it('should craft dftx with OP_CODES._()', () => {
const stack = [
OP_CODES.OP_RETURN,
OP_CODES.OP_DEFI_TX_TOKEN_UPDATE_ANY(tokenUpdateAny)
]

const buffer = toBuffer(stack)
expect(buffer.toString('hex')).toBe(header + data)
})

describe('Composable', () => {
it('should compose from buffer to composable', () => {
const buffer = SmartBuffer.fromBuffer(Buffer.from(data, 'hex'))
const composable = new CTokenUpdateAny(buffer)

expect(composable.toObject()).toEqual(tokenUpdateAny)
})

it('should compose from composable to buffer', () => {
const composable = new CTokenUpdateAny(tokenUpdateAny)
const buffer = new SmartBuffer()
composable.toBuffer(buffer)

expect(buffer.toBuffer().toString('hex')).toEqual(data)
})
})
6 changes: 5 additions & 1 deletion packages/jellyfish-transaction/src/script/defi/dftx.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import {
CPoolAddLiquidity, CPoolRemoveLiquidity, CPoolSwap, PoolAddLiquidity, PoolRemoveLiquidity,
PoolSwap
} from './dftx_pool'
import { CTokenCreate, CTokenMint, TokenCreate, TokenMint } from './dftx_token'
import { CTokenCreate, CTokenMint, CTokenUpdate, CTokenUpdateAny, TokenCreate, TokenMint, TokenUpdate, TokenUpdateAny } from './dftx_token'
import {
CAppointOracle,
AppointOracle,
Expand Down Expand Up @@ -114,6 +114,10 @@ export class CDfTx extends ComposableBuffer<DfTx<any>> {
return compose<TokenMint>(CTokenMint.OP_NAME, d => new CTokenMint(d))
case CTokenCreate.OP_CODE:
return compose<TokenCreate>(CTokenCreate.OP_NAME, d => new CTokenCreate(d))
case CTokenUpdate.OP_CODE:
return compose<TokenUpdate>(CTokenUpdate.OP_NAME, d => new CTokenUpdate(d))
case CTokenUpdateAny.OP_CODE:
return compose<TokenUpdateAny>(CTokenUpdateAny.OP_NAME, d => new CTokenUpdateAny(d))
case CUtxosToAccount.OP_CODE:
return compose<UtxosToAccount>(CUtxosToAccount.OP_NAME, d => new CUtxosToAccount(d))
case CAccountToUtxos.OP_CODE:
Expand Down
60 changes: 59 additions & 1 deletion packages/jellyfish-transaction/src/script/defi/dftx_token.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ export interface TokenCreate {
}

/**
* Composable TokenMint, C stands for Composable.
* Composable TokenCreate, C stands for Composable.
* Immutable by design, bi-directional fromBuffer, toBuffer deep composer.
*/
export class CTokenCreate extends ComposableBuffer<TokenCreate> {
Expand All @@ -62,3 +62,61 @@ export class CTokenCreate extends ComposableBuffer<TokenCreate> {
]
}
}

/**
* TokenUpdate DeFi Transaction
* Note(canonbrother): Only 'isDAT' flag modification allowed before Bayfront fork (<10000)
*/
export interface TokenUpdate {
creationTx: string // -----------------| 32 bytes hex string
isDAT: boolean // ---------------------| 1 byte bitmask start, position 0
}

/**
* Composable CTokenUpdate, C stands for Composable.
* Immutable by design, bi-directional fromBuffer, toBuffer deep composer.
*/
export class CTokenUpdate extends ComposableBuffer<TokenUpdate> {
static OP_CODE = 0x4e /// 'N'
static OP_NAME = 'OP_DEFI_TX_TOKEN_UPDATE'

composers (tu: TokenUpdate): BufferComposer[] {
return [
ComposableBuffer.hexBEBufferLE(32, () => tu.creationTx, v => tu.creationTx = v),
ComposableBuffer.bitmask1Byte(1, () => [tu.isDAT], v => {
tu.isDAT = v[0]
})
]
}
}

/**
* TokenUpdateAny DeFi Transaction
*/
export interface TokenUpdateAny extends TokenCreate {
creationTx: string // -----------------| 32 bytes hex string
}

/**
* Composable TokenUpdateAny, C stands for Composable.
* Immutable by design, bi-directional fromBuffer, toBuffer deep composer.
*/
export class CTokenUpdateAny extends ComposableBuffer<TokenUpdateAny> {
static OP_CODE = 0x6e /// 'n'
static OP_NAME = 'OP_DEFI_TX_TOKEN_UPDATE_ANY'

composers (tua: TokenUpdateAny): BufferComposer[] {
return [
ComposableBuffer.hexBEBufferLE(32, () => tua.creationTx, v => tua.creationTx = v),
ComposableBuffer.varUIntUtf8BE(() => tua.symbol, v => tua.symbol = v),
ComposableBuffer.varUIntUtf8BE(() => tua.name, v => tua.name = v),
ComposableBuffer.uInt8(() => tua.decimal, v => tua.decimal = v),
ComposableBuffer.bigNumberUInt64(() => tua.limit, v => tua.limit = v),
ComposableBuffer.bitmask1Byte(3, () => [tua.isDAT, tua.tradeable, tua.mintable], v => {
tua.isDAT = v[0]
tua.tradeable = v[1]
tua.mintable = v[2]
})
]
}
}
18 changes: 17 additions & 1 deletion packages/jellyfish-transaction/src/script/mapping.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import {
PoolRemoveLiquidity,
PoolSwap
} from './defi/dftx_pool'
import { CTokenCreate, CTokenMint, TokenCreate, TokenMint } from './defi/dftx_token'
import { CTokenCreate, CTokenUpdate, CTokenUpdateAny, CTokenMint, TokenCreate, TokenUpdate, TokenUpdateAny, TokenMint } from './defi/dftx_token'
import {
AccountToAccount,
AccountToUtxos,
Expand Down Expand Up @@ -170,6 +170,22 @@ export const OP_CODES = {
data: tokenCreate
})
},
OP_DEFI_TX_TOKEN_UPDATE: (tokenUpdate: TokenUpdate): OP_DEFI_TX => {
return new OP_DEFI_TX({
signature: CDfTx.SIGNATURE,
type: CTokenUpdate.OP_CODE,
name: CTokenUpdate.OP_NAME,
data: tokenUpdate
})
},
OP_DEFI_TX_TOKEN_UPDATE_ANY: (tokenUpdateAny: TokenUpdateAny): OP_DEFI_TX => {
return new OP_DEFI_TX({
signature: CDfTx.SIGNATURE,
type: CTokenUpdateAny.OP_CODE,
name: CTokenUpdateAny.OP_NAME,
data: tokenUpdateAny
})
},
OP_DEFI_TX_UTXOS_TO_ACCOUNT: (utxosToAccount: UtxosToAccount): OP_DEFI_TX => {
return new OP_DEFI_TX({
signature: CDfTx.SIGNATURE,
Expand Down

0 comments on commit 31ec934

Please sign in to comment.