smartledger-bsv 4.2.1 → 4.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 +50 -0
- package/bsv-covenant.min.js +4 -4
- package/bsv-gdaf.min.js +6 -6
- package/bsv-ltp.min.js +6 -6
- package/bsv-smartcontract.min.js +5 -5
- package/bsv.bundle.js +5 -5
- package/bsv.min.js +5 -5
- package/lib/script/interpreter.js +52 -2
- package/lib/smart_contract/covenant_helpers.js +3 -2
- package/lib/smart_contract/pels.js +1 -2
- package/lib/smart_contract/pushtx.js +25 -8
- package/lib/smart_contract/token.js +3 -5
- package/package.json +1 -1
|
@@ -701,7 +701,7 @@ Interpreter.prototype.step = function () {
|
|
|
701
701
|
return true
|
|
702
702
|
}
|
|
703
703
|
break
|
|
704
|
-
|
|
704
|
+
|
|
705
705
|
// Monolith opcodes are now enabled by default in SmartLedger BSV
|
|
706
706
|
// These were activated in May 2018 and are part of standard BSV consensus
|
|
707
707
|
case Opcode.OP_DIV:
|
|
@@ -715,7 +715,7 @@ Interpreter.prototype.step = function () {
|
|
|
715
715
|
case Opcode.OP_NUM2BIN:
|
|
716
716
|
// These opcodes are now always enabled - no flag required
|
|
717
717
|
return false
|
|
718
|
-
|
|
718
|
+
|
|
719
719
|
default:
|
|
720
720
|
break
|
|
721
721
|
}
|
|
@@ -1757,6 +1757,56 @@ Interpreter.prototype.step = function () {
|
|
|
1757
1757
|
this.stack[this.stack.length - 1] = n1.slice(position)
|
|
1758
1758
|
break
|
|
1759
1759
|
|
|
1760
|
+
case Opcode.OP_LEFT:
|
|
1761
|
+
case Opcode.OP_RIGHT:
|
|
1762
|
+
// (in size -- out) OP_LEFT keeps the first `size` bytes; OP_RIGHT the last.
|
|
1763
|
+
// Re-enabled string opcodes (BSV Chronicle). Original Satoshi semantics.
|
|
1764
|
+
if (this.stack.length < 2) {
|
|
1765
|
+
this.errstr = 'SCRIPT_ERR_INVALID_STACK_OPERATION'
|
|
1766
|
+
return false
|
|
1767
|
+
}
|
|
1768
|
+
buf1 = stacktop(-2)
|
|
1769
|
+
n = BN.fromScriptNumBuffer(stacktop(-1), fRequireMinimal).toNumber()
|
|
1770
|
+
if (n < 0) {
|
|
1771
|
+
this.errstr = 'SCRIPT_ERR_INVALID_NUMBER_RANGE'
|
|
1772
|
+
return false
|
|
1773
|
+
}
|
|
1774
|
+
if (n > buf1.length) {
|
|
1775
|
+
n = buf1.length
|
|
1776
|
+
}
|
|
1777
|
+
this.stack.pop()
|
|
1778
|
+
if (opcodenum === Opcode.OP_LEFT) {
|
|
1779
|
+
this.stack[this.stack.length - 1] = Buffer.from(buf1).slice(0, n)
|
|
1780
|
+
} else {
|
|
1781
|
+
this.stack[this.stack.length - 1] = Buffer.from(buf1).slice(buf1.length - n)
|
|
1782
|
+
}
|
|
1783
|
+
break
|
|
1784
|
+
|
|
1785
|
+
case Opcode.OP_SUBSTR:
|
|
1786
|
+
// (in begin size -- out) out = in[begin : begin + size]
|
|
1787
|
+
// Re-enabled string opcode (BSV Chronicle). Original Satoshi semantics.
|
|
1788
|
+
if (this.stack.length < 3) {
|
|
1789
|
+
this.errstr = 'SCRIPT_ERR_INVALID_STACK_OPERATION'
|
|
1790
|
+
return false
|
|
1791
|
+
}
|
|
1792
|
+
buf1 = stacktop(-3)
|
|
1793
|
+
var subSize = BN.fromScriptNumBuffer(stacktop(-1), fRequireMinimal).toNumber()
|
|
1794
|
+
var subBegin = BN.fromScriptNumBuffer(stacktop(-2), fRequireMinimal).toNumber()
|
|
1795
|
+
if (subBegin < 0 || subSize < 0) {
|
|
1796
|
+
this.errstr = 'SCRIPT_ERR_INVALID_NUMBER_RANGE'
|
|
1797
|
+
return false
|
|
1798
|
+
}
|
|
1799
|
+
if (subBegin > buf1.length) {
|
|
1800
|
+
subBegin = buf1.length
|
|
1801
|
+
}
|
|
1802
|
+
if (subBegin + subSize > buf1.length) {
|
|
1803
|
+
subSize = buf1.length - subBegin
|
|
1804
|
+
}
|
|
1805
|
+
this.stack.pop()
|
|
1806
|
+
this.stack.pop()
|
|
1807
|
+
this.stack[this.stack.length - 1] = Buffer.from(buf1).slice(subBegin, subBegin + subSize)
|
|
1808
|
+
break
|
|
1809
|
+
|
|
1760
1810
|
//
|
|
1761
1811
|
// Conversion operations
|
|
1762
1812
|
//
|
|
@@ -18,13 +18,14 @@ var Signature = require('../crypto/signature')
|
|
|
18
18
|
var SIGHASH = Signature.SIGHASH_ALL | Signature.SIGHASH_FORKID // 0x41
|
|
19
19
|
|
|
20
20
|
// Post-Genesis consensus flags (big numbers, OP_CAT/OP_SPLIT/OP_MUL, FORKID,
|
|
21
|
-
// CLTV/CSV). LOW_S is
|
|
22
|
-
// signature
|
|
21
|
+
// CLTV/CSV). LOW_S is enforced: the OP_PUSH_TX grind produces a canonical
|
|
22
|
+
// (low-S) in-script signature, so these covenants meet mainnet standardness.
|
|
23
23
|
function flags () {
|
|
24
24
|
var I = bsv.Script.Interpreter
|
|
25
25
|
return I.SCRIPT_VERIFY_P2SH |
|
|
26
26
|
I.SCRIPT_VERIFY_STRICTENC |
|
|
27
27
|
I.SCRIPT_VERIFY_DERSIG |
|
|
28
|
+
I.SCRIPT_VERIFY_LOW_S |
|
|
28
29
|
I.SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY |
|
|
29
30
|
I.SCRIPT_VERIFY_CHECKSEQUENCEVERIFY |
|
|
30
31
|
I.SCRIPT_ENABLE_SIGHASH_FORKID |
|
|
@@ -44,8 +44,7 @@ function pelsCovenant (fee) {
|
|
|
44
44
|
|
|
45
45
|
// 3. value (8B @ offsetFromEnd 52); newValue = value - fee, as 8-byte LE
|
|
46
46
|
s.add(Opcode.OP_OVER)
|
|
47
|
-
s.add(
|
|
48
|
-
s.add(n(8)).add(Opcode.OP_SPLIT).add(Opcode.OP_DROP)
|
|
47
|
+
s.add(n(52)).add(Opcode.OP_RIGHT).add(n(8)).add(Opcode.OP_LEFT) // last 52 bytes, first 8 = value
|
|
49
48
|
s.add(Opcode.OP_BIN2NUM).add(n(fee)).add(Opcode.OP_SUB)
|
|
50
49
|
s.add(n(8)).add(Opcode.OP_NUM2BIN)
|
|
51
50
|
|
|
@@ -59,10 +59,18 @@ function pushTxCore (script) {
|
|
|
59
59
|
script.add(gxLe).add(Opcode.OP_ADD) // e + Gx
|
|
60
60
|
script.add(N_LE).add(Opcode.OP_MOD) // s = (e + Gx) mod n
|
|
61
61
|
script.add(scriptNum(32)).add(Opcode.OP_NUM2BIN) // s -> 32-byte LE
|
|
62
|
-
reverseBytes(script, 32) // -> big-endian (DER INTEGER body)
|
|
63
|
-
|
|
62
|
+
reverseBytes(script, 32) // -> big-endian (DER INTEGER body) ; stack: [s_be]
|
|
63
|
+
// Build the DER signature and the pubkey from a SINGLE Gx push (Gx is both the
|
|
64
|
+
// r-value inside the DER prefix and the body of the 02||Gx pubkey). Sharing it
|
|
65
|
+
// via the altstack saves a 32-byte constant vs. embedding Gx twice.
|
|
66
|
+
script.add(Gx).add(Opcode.OP_DUP) // [s_be, Gx, Gx]
|
|
67
|
+
script.add(Buffer.from([0x02])).add(Opcode.OP_SWAP).add(Opcode.OP_CAT) // pubkey = 02||Gx
|
|
68
|
+
script.add(Opcode.OP_TOALTSTACK) // park pubkey ; [s_be, Gx]
|
|
69
|
+
script.add(Buffer.from([0x30, 0x44, 0x02, 0x20])).add(Opcode.OP_SWAP).add(Opcode.OP_CAT) // 30440220||Gx
|
|
70
|
+
script.add(Buffer.from([0x02, 0x20])).add(Opcode.OP_CAT) // ||0220 => DER prefix
|
|
71
|
+
script.add(Opcode.OP_SWAP).add(Opcode.OP_CAT) // DER prefix || s_be
|
|
64
72
|
script.add(SIGHASH_BYTE).add(Opcode.OP_CAT) // || sighash flag => full DER sig
|
|
65
|
-
script.add(
|
|
73
|
+
script.add(Opcode.OP_FROMALTSTACK).add(Opcode.OP_CHECKSIG) // pubkey ; verify against P = G
|
|
66
74
|
return script
|
|
67
75
|
}
|
|
68
76
|
|
|
@@ -73,9 +81,8 @@ function authenticator () {
|
|
|
73
81
|
|
|
74
82
|
/** Extract the committed hashOutputs (item 9, offsetFromEnd 40, len 32) from a preimage on-stack. */
|
|
75
83
|
function extractHashOutputs (script) {
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
.add(scriptNum(32)).add(Opcode.OP_SPLIT).add(Opcode.OP_DROP)
|
|
84
|
+
// last 40 bytes, then the first 32 of those = hashOutputs. (BSV string opcodes.)
|
|
85
|
+
script.add(scriptNum(40)).add(Opcode.OP_RIGHT).add(scriptNum(32)).add(Opcode.OP_LEFT)
|
|
79
86
|
return script
|
|
80
87
|
}
|
|
81
88
|
|
|
@@ -98,12 +105,22 @@ function valueCovenant (expectedHashOutputs) {
|
|
|
98
105
|
return script
|
|
99
106
|
}
|
|
100
107
|
|
|
101
|
-
|
|
108
|
+
// floor(n/2) — the canonical low-S boundary (matches Signature.hasLowS()).
|
|
109
|
+
var HALF_N = new BN('7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0', 'hex')
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Compute s = (HASH256(preimage)+Gx) mod n; return its 32-byte BE form, or null
|
|
113
|
+
* if the resulting signature would not be a clean, CANONICAL (low-S) DER.
|
|
114
|
+
* Requiring s <= n/2 makes the in-script signature non-malleable and standard,
|
|
115
|
+
* so it passes nodes enforcing SCRIPT_VERIFY_LOW_S — at zero script-size cost
|
|
116
|
+
* (the burden is on the spender's grind, not extra opcodes).
|
|
117
|
+
*/
|
|
102
118
|
function sFromPreimage (preimage) {
|
|
103
119
|
var z = Hash.sha256sha256(preimage)
|
|
104
120
|
var s = new BN(z).add(new BN(Gx)).mod(N)
|
|
121
|
+
if (s.gt(HALF_N)) return null // enforce low-S (canonical / non-malleable)
|
|
105
122
|
var sBE = s.toBuffer('be', 32)
|
|
106
|
-
return (sBE[0] >= 0x01
|
|
123
|
+
return (sBE[0] >= 0x01) ? sBE : null // s <= n/2 already guarantees sBE[0] <= 0x7f
|
|
107
124
|
}
|
|
108
125
|
|
|
109
126
|
/**
|
|
@@ -41,17 +41,15 @@ function ownershipToken (fee, ownerHash) {
|
|
|
41
41
|
|
|
42
42
|
// park value (8B @ offsetFromEnd 52) and hashOutputs (32B @ offsetFromEnd 40)
|
|
43
43
|
s.add(Opcode.OP_DUP)
|
|
44
|
-
.add(
|
|
45
|
-
.add(n(8)).add(Opcode.OP_SPLIT).add(Opcode.OP_DROP).add(Opcode.OP_TOALTSTACK) // alt:[value8]
|
|
44
|
+
.add(n(52)).add(Opcode.OP_RIGHT).add(n(8)).add(Opcode.OP_LEFT).add(Opcode.OP_TOALTSTACK) // alt:[value8]
|
|
46
45
|
s.add(Opcode.OP_DUP); P.extractHashOutputs(s); s.add(Opcode.OP_TOALTSTACK) // alt:[value8, hashOutputs]
|
|
47
46
|
|
|
48
47
|
// scriptChunk = preimage[104 : len-52] (consumes preimage)
|
|
49
48
|
s.add(n(104)).add(Opcode.OP_SPLIT).add(Opcode.OP_NIP)
|
|
50
49
|
.add(Opcode.OP_SIZE).add(n(52)).add(Opcode.OP_SUB).add(Opcode.OP_SPLIT).add(Opcode.OP_DROP)
|
|
51
50
|
|
|
52
|
-
// owner authorization: SHA256(ownerSecret) == ownerHash
|
|
53
|
-
s.add(Opcode.OP_DUP).add(n(4)).add(
|
|
54
|
-
.add(n(32)).add(Opcode.OP_SPLIT).add(Opcode.OP_DROP)
|
|
51
|
+
// owner authorization: SHA256(ownerSecret) == ownerHash = chunk[4:36] (OP_SUBSTR)
|
|
52
|
+
s.add(Opcode.OP_DUP).add(n(4)).add(n(32)).add(Opcode.OP_SUBSTR)
|
|
55
53
|
s.add(n(3)).add(Opcode.OP_ROLL)
|
|
56
54
|
s.add(Opcode.OP_SHA256).add(Opcode.OP_EQUALVERIFY) // [newOwnerHash, scriptChunk]
|
|
57
55
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "smartledger-bsv",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.4.0",
|
|
4
4
|
"description": "🚀 Complete Bitcoin SV development framework with legally-recognizable DID:web + W3C VC-JWT toolkit, Legal Token Protocol (LTP), Global Digital Attestation Framework (GDAF), StatusList2021 revocation, and 16 flexible loading options. Standards-based credentials with ES256/ES256K support, on-chain BSV anchoring, and comprehensive Bitcoin SV API. Perfect for legal tokens, verifiable credentials, DeFi, smart contracts, and secure Bitcoin applications.",
|
|
5
5
|
"author": "SmartLedger Technology <hello@smartledger.technology> (https://smartledger.technology)",
|
|
6
6
|
"homepage": "https://github.com/codenlighten/smartledger-bsv#readme",
|