Skip to content

Commit

Permalink
Merge pull request #64 from sCrypt-Inc/from-tx
Browse files Browse the repository at this point in the history
Add fromTx for bsv20v2
  • Loading branch information
zhfnjust authored Apr 4, 2024
2 parents 2043fc9 + d2dc145 commit f4817ef
Show file tree
Hide file tree
Showing 2 changed files with 100 additions and 3 deletions.
31 changes: 28 additions & 3 deletions src/contracts/bsv20V2.ts
Original file line number Diff line number Diff line change
Expand Up @@ -188,9 +188,9 @@ export abstract class BSV20V2 extends SmartContract {
| FTReceiver
const tokenChangeAmt = Array.isArray(recipients)
? current.getAmt() -
recipients.reduce((acc, receiver) => {
return (acc += receiver.amt)
}, 0n)
recipients.reduce((acc, receiver) => {
return (acc += receiver.amt)
}, 0n)
: current.getAmt() - recipients.amt
if (tokenChangeAmt < 0n) {
throw new Error(`Not enough tokens`)
Expand Down Expand Up @@ -316,4 +316,29 @@ export abstract class BSV20V2 extends SmartContract {
cloned.prependNOPScript(this.getPrependNOPScript())
return cloned
}

/**
* recover a `BSV20V2` instance from the transaction
* if the contract contains onchain properties of type `HashedMap` or `HashedSet`
* it's required to pass all their offchain raw data at this transaction moment
* @param tx transaction
* @param atOutputIndex output index of `tx`
* @param offchainValues the value of offchain properties, the raw data of onchain `HashedMap` and `HashedSet` properties, at this transaction moment
*/
static override fromTx<T extends SmartContract>(
this: new (...args: any[]) => T,
tx: bsv.Transaction,
atOutputIndex: number,
offchainValues?: Record<string, any>
): T {
const outputScript = tx.outputs[atOutputIndex].script
const nopScript = Ordinal.nopScriptFromScript(outputScript)
const instance = super.fromTx(
tx,
atOutputIndex,
offchainValues,
nopScript
)
return instance as T
}
}
72 changes: 72 additions & 0 deletions tests/specs/fromTx.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import { Addr, PubKey, findSig, fromByteString, toByteString } from "scrypt-ts"
import { BSV20V1P2PKH, BSV20V2P2PKH, Ordinal } from "../scrypt-ord"
import { myAddress, myPublicKey } from "../utils/privateKey"
import { getDefaultSigner } from "../utils/txHelper"
import { expect, use } from "chai"
import chaiAsPromised from 'chai-as-promised'
use(chaiAsPromised)

describe('Test `fromTx`', () => {

it('BSV20V1P2PKH', async () => {
const tick = toByteString('abcd', true)
const max = 100n
const lim = 10n
const dec = 0n
const addr = Addr(myAddress.toByteString())
// mint token
const instance = new BSV20V1P2PKH(tick, max, lim, dec, addr)
await instance.connect(getDefaultSigner())
await instance.deployToken()
const mintTx = await instance.mint(lim)
// recover instance from the mint tx
const recoveredInstance = BSV20V1P2PKH.fromTx(mintTx, 0)
await recoveredInstance.connect(getDefaultSigner())
// call
const callContract = async () => recoveredInstance.methods.unlock(
(sigResps) => findSig(sigResps, myPublicKey),
PubKey(myPublicKey.toHex()),
{
pubKeyOrAddrToSign: myPublicKey,
transfer: {
instance: new BSV20V1P2PKH(tick, max, lim, dec, addr),
amt: 1n
}
}
)
return expect(callContract()).not.rejected
})

it('BSV20V2P2PKH', async () => {
const sym = toByteString('abcd', true)
const amt = 100n
const dec = 0n
const addr = Addr(myAddress.toByteString())
// deploy token
const instance = new BSV20V2P2PKH(toByteString(''), sym, amt, dec, addr)
await instance.connect(getDefaultSigner())
instance.prependNOPScript(Ordinal.createDeployV2(
fromByteString(instance.sym),
instance.max,
instance.dec,
))
const deployTx = await instance.deploy(1)
const tokenId = toByteString(`${deployTx.id}_0`, true)
// recover instance from the deploy tx
const recoveredInstance = BSV20V2P2PKH.fromTx(deployTx, 0)
await recoveredInstance.connect(getDefaultSigner())
// call
const callContract = async () => recoveredInstance.methods.unlock(
(sigResps) => findSig(sigResps, myPublicKey),
PubKey(myPublicKey.toHex()),
{
pubKeyOrAddrToSign: myPublicKey,
transfer: {
instance: new BSV20V2P2PKH(tokenId, sym, amt, dec, addr),
amt: 1n
}
}
)
return expect(callContract()).not.rejected
})
})

0 comments on commit f4817ef

Please sign in to comment.