@smartledger/bsv 7.2.0 → 7.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +136 -0
- package/README.md +38 -38
- package/bsv-gdaf.min.js +44 -44
- package/bsv-ltp.min.js +44 -44
- package/bsv-smartcontract.min.js +1 -1
- package/bsv.bundle.js +44 -44
- package/bsv.d.ts +19 -4
- package/bsv.min.js +44 -44
- package/docs/MODULE_REFERENCE_COMPLETE.md +27 -27
- package/docs/advanced/UTXO_MANAGER_GUIDE.md +1 -1
- package/docs/getting-started/INSTALLATION.md +23 -23
- package/docs/getting-started/QUICK_START.md +7 -7
- package/docs/migration/FROM_BSV_1_5_6.md +5 -5
- package/lib/ordinals/README.md +48 -5
- package/lib/ordinals/bsv20.js +215 -15
- package/lib/ordinals/ordlock.js +27 -1
- package/package.json +1 -1
- package/test/ordinals/bsv20.js +213 -2
- package/test/ordinals/ordlock.js +71 -0
- package/version.js +1 -1
package/test/ordinals/ordlock.js
CHANGED
|
@@ -549,4 +549,75 @@ describe('Ordinals OrdLock — code-review regressions', function () {
|
|
|
549
549
|
})
|
|
550
550
|
Ord.parseOrdLock(lock).totalPrice.should.equal(777)
|
|
551
551
|
})
|
|
552
|
+
|
|
553
|
+
// parseOrdLock recovers terms from the script's shape. Shape alone proves nothing: a
|
|
554
|
+
// script wearing the same opcode arrangement without the OP_PUSH_TX covenant enforces no
|
|
555
|
+
// payment, and reporting a seller and a price for it invents a listing that does not
|
|
556
|
+
// exist. The terms are therefore verified by rebuilding the listing and comparing bytes.
|
|
557
|
+
describe('is a verifier, not a shape matcher', function () {
|
|
558
|
+
var attacker = bsv.PrivateKey.fromBuffer(Buffer.alloc(32, 9))
|
|
559
|
+
|
|
560
|
+
// Wears the fingerprint parseOrdLock keys off: a top-level OP_IF with a 20-byte push,
|
|
561
|
+
// and OP_TOALTSTACK <blob> OP_CAT OP_SWAP in the OP_ELSE branch. Enforces nothing.
|
|
562
|
+
function fabricatedListing () {
|
|
563
|
+
var payout = new bsv.Transaction.Output({
|
|
564
|
+
script: bsv.Script.buildPublicKeyHashOut(attacker.toAddress()),
|
|
565
|
+
satoshis: 100000000
|
|
566
|
+
})
|
|
567
|
+
var s = new bsv.Script()
|
|
568
|
+
s.add(bsv.Opcode.OP_IF)
|
|
569
|
+
s.add(attacker.toAddress().hashBuffer)
|
|
570
|
+
s.add(bsv.Opcode.OP_DROP)
|
|
571
|
+
s.add(bsv.Opcode.OP_ELSE)
|
|
572
|
+
s.add(bsv.Opcode.OP_TOALTSTACK)
|
|
573
|
+
s.add(payout.toBufferWriter().toBuffer())
|
|
574
|
+
s.add(bsv.Opcode.OP_CAT)
|
|
575
|
+
s.add(bsv.Opcode.OP_SWAP)
|
|
576
|
+
s.add(bsv.Opcode.OP_ENDIF)
|
|
577
|
+
s.add(bsv.Opcode.OP_TRUE)
|
|
578
|
+
return s
|
|
579
|
+
}
|
|
580
|
+
|
|
581
|
+
it('rejects a fabricated listing that enforces no payment', function () {
|
|
582
|
+
var fake = fabricatedListing()
|
|
583
|
+
Ord.isOrdLock(fake).should.equal(false)
|
|
584
|
+
;(Ord.parseOrdLock(fake) === null).should.equal(true)
|
|
585
|
+
})
|
|
586
|
+
|
|
587
|
+
it('proves the fabricated listing really is spendable for free', function () {
|
|
588
|
+
// Without this, the test above only shows we reject *something*.
|
|
589
|
+
var interp = new bsv.Script.Interpreter()
|
|
590
|
+
var unlock = new bsv.Script().add(bsv.Opcode.OP_1)
|
|
591
|
+
var spent = interp.verify(unlock, fabricatedListing(), new bsv.Transaction(), 0, 0)
|
|
592
|
+
spent.should.equal(true)
|
|
593
|
+
})
|
|
594
|
+
|
|
595
|
+
it('rejects a genuine listing with anything appended', function () {
|
|
596
|
+
var real = Ord.buildOrdLock({ seller: owner.toAddress(), price: 50000 })
|
|
597
|
+
var tampered = bsv.Script.fromHex(real.toHex()).add(bsv.Opcode.OP_NOP)
|
|
598
|
+
Ord.isOrdLock(tampered).should.equal(false)
|
|
599
|
+
})
|
|
600
|
+
|
|
601
|
+
it('still accepts every genuine listing shape', function () {
|
|
602
|
+
var simple = Ord.buildOrdLock({ seller: owner.toAddress(), price: 50000 })
|
|
603
|
+
Ord.parseOrdLock(simple).totalPrice.should.equal(50000)
|
|
604
|
+
|
|
605
|
+
var withInsc = Ord.buildOrdLock({
|
|
606
|
+
seller: owner.toAddress(),
|
|
607
|
+
price: 777,
|
|
608
|
+
inscription: { contentType: 'text/plain', content: 'for sale' }
|
|
609
|
+
})
|
|
610
|
+
var parsed = Ord.parseOrdLock(withInsc)
|
|
611
|
+
parsed.totalPrice.should.equal(777)
|
|
612
|
+
parsed.inscription.contentText.should.equal('for sale')
|
|
613
|
+
|
|
614
|
+
var multi = Ord.buildOrdLock({
|
|
615
|
+
seller: owner.toAddress(),
|
|
616
|
+
price: 1000,
|
|
617
|
+
royalties: [{ address: attacker.toAddress(), satoshis: 50 }]
|
|
618
|
+
})
|
|
619
|
+
Ord.parseOrdLock(multi).payOutputs.length.should.equal(2)
|
|
620
|
+
Ord.parseOrdLock(multi).totalPrice.should.equal(1050)
|
|
621
|
+
})
|
|
622
|
+
})
|
|
552
623
|
})
|
package/version.js
CHANGED