dot-bridge-contracts
Advanced tools
Comparing version 0.1.1 to 0.1.2
@@ -5,3 +5,3 @@ { | ||
"contract": "TxParserBTC", | ||
"md5": "df5e7345a69c117200284671dbccbcdb", | ||
"md5": "34f5255dc2b9a5dc6f232a9bd632ef2a", | ||
"structs": [ | ||
@@ -8,0 +8,0 @@ { |
@@ -17,2 +17,3 @@ import { SmartContractLib, ByteString, Sha256 } from 'scrypt-ts'; | ||
export declare class TxParserBTC extends SmartContractLib { | ||
static readonly BLOCK_HEIGHT_POS: bigint; | ||
buf: ByteString; | ||
@@ -36,2 +37,4 @@ pos: bigint; | ||
parse(maxInputCount: number, maxOutputCount: number, hash: Sha256): BTCResult; | ||
readBlockHeight(): bigint; | ||
isCoinbase(): boolean; | ||
} |
@@ -92,3 +92,3 @@ "use strict"; | ||
static writeInput(input) { | ||
let buf = (0, scrypt_ts_1.toByteString)(""); | ||
let buf = (0, scrypt_ts_1.toByteString)(''); | ||
buf += input.txId; | ||
@@ -117,3 +117,3 @@ buf += scrypt_ts_1.Utils.toLEUnsigned(input.vout, 4n); | ||
static writeOutput(output) { | ||
let buf = (0, scrypt_ts_1.toByteString)(""); | ||
let buf = (0, scrypt_ts_1.toByteString)(''); | ||
buf += scrypt_ts_1.Utils.toLEUnsigned(output.satoshis, 8n); | ||
@@ -153,3 +153,3 @@ const scriptLen = (0, scrypt_ts_1.len)(output.script); | ||
parse(maxInputCount, maxOutputCount, hash) { | ||
let txidBuf = (0, scrypt_ts_1.toByteString)(""); | ||
let txidBuf = (0, scrypt_ts_1.toByteString)(''); | ||
this.version = this.readUInt32(); | ||
@@ -187,7 +187,19 @@ txidBuf += scrypt_ts_1.Utils.toLEUnsigned(this.version, 4n); | ||
txId: (0, scrypt_ts_1.hash256)(txidBuf), | ||
amt: amt | ||
amt: amt, | ||
}; | ||
} | ||
// Parse block height from coinbase tx: BIP34 | ||
readBlockHeight() { | ||
// Block height is at the beginning of the unlocking script and encoded in varint. | ||
return scrypt_ts_1.Utils.fromLEUnsigned(scrypt_ts_1.Utils.readVarint((0, scrypt_ts_1.slice)(this.buf, TxParserBTC.BLOCK_HEIGHT_POS + (this.isWitness ? 2n : 0n)))); | ||
} | ||
isCoinbase() { | ||
return ((0, scrypt_ts_1.slice)(this.buf, this.isWitness ? 6n : 4n, this.isWitness ? 7n : 5n) == (0, scrypt_ts_1.toByteString)('01') && // only 1 input | ||
(0, scrypt_ts_1.slice)(this.buf, this.isWitness ? 7n : 5n, this.isWitness ? 39n : 37n) == | ||
(0, scrypt_ts_1.toByteString)('0000000000000000000000000000000000000000000000000000000000000000') && // null txid: all zeros | ||
(0, scrypt_ts_1.slice)(this.buf, this.isWitness ? 39n : 37n, this.isWitness ? 43n : 41n) == (0, scrypt_ts_1.toByteString)('ffffffff')); // null vout: all Fs | ||
} | ||
} | ||
exports.TxParserBTC = TxParserBTC; | ||
TxParserBTC.BLOCK_HEIGHT_POS = 42n; | ||
__decorate([ | ||
@@ -237,2 +249,11 @@ (0, scrypt_ts_1.prop)() | ||
(0, scrypt_ts_1.method)() | ||
], TxParserBTC.prototype, "readBlockHeight", null); | ||
__decorate([ | ||
(0, scrypt_ts_1.method)() | ||
], TxParserBTC.prototype, "isCoinbase", null); | ||
__decorate([ | ||
(0, scrypt_ts_1.prop)() | ||
], TxParserBTC, "BLOCK_HEIGHT_POS", void 0); | ||
__decorate([ | ||
(0, scrypt_ts_1.method)() | ||
], TxParserBTC, "writeVarint", null); | ||
@@ -239,0 +260,0 @@ __decorate([ |
@@ -19,9 +19,10 @@ import { BSV20V2 } from 'scrypt-ord'; | ||
mining_difficulty: bigint; | ||
constructor(sym: ByteString, max: bigint, dec: bigint, oraclePubKey: RabinPubKey, adminPubKey: PubKey, mining_difficulty: bigint); | ||
block_height: bigint; | ||
constructor(sym: ByteString, max: bigint, dec: bigint, oraclePubKey: RabinPubKey, adminPubKey: PubKey, mining_difficulty: bigint, block_height: bigint); | ||
mint(msg: ByteString, sig: RabinSig, merkleTreiTreePath: ByteString, merkleProof: MerkleProof, bh: BlockHeader): void; | ||
updateMiningDifficulty(sig: Sig, bh: BlockHeader): void; | ||
updateMiningDifficulty(sig: Sig, bh: BlockHeader, coinbaseTx: ByteString, merkleProof: MerkleProof): void; | ||
static parseMsg(msg: ByteString): OracleMsg; | ||
static mintTxBuilder(current: WrappedBRC20, options: MethodCallOptions<WrappedBRC20>, msg: ByteString): Promise<ContractTransaction>; | ||
static updateMiningDifficultyTxBuilder(current: WrappedBRC20, options: MethodCallOptions<WrappedBRC20>, sig: Sig, bh: BlockHeader): Promise<ContractTransaction>; | ||
static updateMiningDifficultyTxBuilder(current: WrappedBRC20, options: MethodCallOptions<WrappedBRC20>, sig: Sig, bh: BlockHeader, coinbaseTx: ByteString): Promise<ContractTransaction>; | ||
} | ||
export {}; |
@@ -15,4 +15,5 @@ "use strict"; | ||
const merkleTreiTree_1 = require("./merkleTreiTree"); | ||
const txParserBTC_1 = require("./txParserBTC"); | ||
class WrappedBRC20 extends scrypt_ord_1.BSV20V2 { | ||
constructor(sym, max, dec, oraclePubKey, adminPubKey, mining_difficulty) { | ||
constructor(sym, max, dec, oraclePubKey, adminPubKey, mining_difficulty, block_height) { | ||
super((0, scrypt_ts_1.toByteString)(''), sym, max, dec); | ||
@@ -24,2 +25,3 @@ this.tree = new btcTxidDataTree_1.TxidDataTree([]); | ||
this.mining_difficulty = mining_difficulty; | ||
this.block_height = block_height; | ||
this.oraclePubKey = oraclePubKey; | ||
@@ -50,6 +52,17 @@ this.txIdsRoot = (0, scrypt_ts_1.toByteString)('072d02306e9bd6a2afd32c04dbe136b72da3b941'); | ||
} | ||
updateMiningDifficulty(sig, bh) { | ||
updateMiningDifficulty(sig, bh, coinbaseTx, merkleProof) { | ||
(0, scrypt_ts_1.assert)(this.checkSig(sig, this.adminPubKey), 'invalid signature!'); | ||
(0, scrypt_ts_1.assert)(scrypt_ts_lib_1.Blockchain.verifyBlockHeader(bh), 'invalid BlockHeader!'); | ||
this.mining_difficulty = scrypt_ts_lib_1.Blockchain.bits2Target(bh.bits); | ||
const txParser = new txParserBTC_1.TxParserBTC(coinbaseTx); | ||
const result = txParser.parse(1, 5, (0, scrypt_ts_1.hash256)((0, scrypt_ts_1.toByteString)('00'))); | ||
(0, scrypt_ts_1.assert)(txParser.isCoinbase(), 'invalid coinbase transaction!'); | ||
const block_height = txParser.readBlockHeight(); | ||
(0, scrypt_ts_1.assert)(block_height > this.block_height, 'invalid block height!'); | ||
(0, scrypt_ts_1.assert)(scrypt_ts_lib_1.Blockchain.txInBlock((0, scrypt_ts_1.Sha256)(result.txId), bh, merkleProof, 32), 'coinbase Tx not in BlockHeader!'); | ||
const new_mining_difficulty = scrypt_ts_lib_1.Blockchain.bits2Target(bh.bits); | ||
// 40_000_000_000_000n | ||
const minimal_mining_difficulty = 673988382275282737328911908618099783400272468464354102n; | ||
(0, scrypt_ts_1.assert)(new_mining_difficulty < minimal_mining_difficulty, 'invalid mining difficulty!'); | ||
this.mining_difficulty = new_mining_difficulty; | ||
this.block_height = block_height; | ||
let outputs = this.buildStateOutputFT(this.supply); | ||
@@ -99,3 +112,3 @@ // Build change output. | ||
} | ||
static async updateMiningDifficultyTxBuilder(current, options, sig, bh) { | ||
static async updateMiningDifficultyTxBuilder(current, options, sig, bh, coinbaseTx) { | ||
const defaultAddress = await current.signer.getDefaultAddress(); | ||
@@ -111,2 +124,5 @@ const tx = new scrypt_ts_1.bsv.Transaction().addInput(current.buildContractInput()); | ||
next.mining_difficulty = scrypt_ts_lib_1.Blockchain.bits2Target(bh.bits); | ||
const txParser = new txParserBTC_1.TxParserBTC(coinbaseTx); | ||
txParser.parse(1, 5, (0, scrypt_ts_1.hash256)('00')); | ||
next.block_height = txParser.readBlockHeight(); | ||
tx.addOutput(new scrypt_ts_1.bsv.Transaction.Output({ | ||
@@ -142,2 +158,5 @@ satoshis: 1, | ||
__decorate([ | ||
(0, scrypt_ts_1.prop)(true) | ||
], WrappedBRC20.prototype, "block_height", void 0); | ||
__decorate([ | ||
(0, scrypt_ts_1.method)() | ||
@@ -144,0 +163,0 @@ ], WrappedBRC20.prototype, "mint", null); |
@@ -12,7 +12,8 @@ import { BSV20V2 } from 'scrypt-ord'; | ||
mining_difficulty: bigint; | ||
constructor(sym: ByteString, max: bigint, dec: bigint, hash: Sha256, adminPubKey: PubKey, current_mining_difficulty: bigint); | ||
block_height: bigint; | ||
constructor(sym: ByteString, max: bigint, dec: bigint, hash: Sha256, adminPubKey: PubKey, mining_difficulty: bigint, block_height: bigint); | ||
mint(rawTx: ByteString, recipient: Addr, merkleTreiTreePath: ByteString, merkleProof: MerkleProof, bh: BlockHeader): void; | ||
updateMiningDifficulty(sig: Sig, bh: BlockHeader): void; | ||
updateMiningDifficulty(sig: Sig, bh: BlockHeader, coinbaseTx: ByteString, merkleProof: MerkleProof): void; | ||
static mintTxBuilder(current: WrappedBTC, options: MethodCallOptions<WrappedBTC>, rawTx: ByteString, recipient: Addr): Promise<ContractTransaction>; | ||
static updateMiningDifficultyTxBuilder(current: WrappedBTC, options: MethodCallOptions<WrappedBTC>, sig: Sig, bh: BlockHeader): Promise<ContractTransaction>; | ||
static updateMiningDifficultyTxBuilder(current: WrappedBTC, options: MethodCallOptions<WrappedBTC>, sig: Sig, bh: BlockHeader, coinbaseTx: ByteString): Promise<ContractTransaction>; | ||
} |
@@ -17,3 +17,3 @@ "use strict"; | ||
class WrappedBTC extends scrypt_ord_1.BSV20V2 { | ||
constructor(sym, max, dec, hash, adminPubKey, current_mining_difficulty) { | ||
constructor(sym, max, dec, hash, adminPubKey, mining_difficulty, block_height) { | ||
super((0, scrypt_ts_1.toByteString)(''), sym, max, dec); | ||
@@ -25,3 +25,4 @@ this.tree = new btcTxidDataTree_1.TxidDataTree([]); | ||
this.adminPubKey = adminPubKey; | ||
this.mining_difficulty = current_mining_difficulty; | ||
this.mining_difficulty = mining_difficulty; | ||
this.block_height = block_height; | ||
this.txIdsRoot = (0, scrypt_ts_1.toByteString)('072d02306e9bd6a2afd32c04dbe136b72da3b941'); | ||
@@ -44,3 +45,3 @@ } | ||
// Build FT P2PKH output to dest paying specified amount of tokens. | ||
outputs += scrypt_ord_1.BSV20V2.buildTransferOutput(recipient, this.id, 1n); | ||
outputs += scrypt_ord_1.BSV20V2.buildTransferOutput(recipient, this.id, result.amt); | ||
// Build change output. | ||
@@ -51,6 +52,17 @@ outputs += this.buildChangeOutput(); | ||
} | ||
updateMiningDifficulty(sig, bh) { | ||
updateMiningDifficulty(sig, bh, coinbaseTx, merkleProof) { | ||
(0, scrypt_ts_1.assert)(this.checkSig(sig, this.adminPubKey), 'invalid signature!'); | ||
(0, scrypt_ts_1.assert)(scrypt_ts_lib_1.Blockchain.verifyBlockHeader(bh), 'invalid BlockHeader!'); | ||
this.mining_difficulty = scrypt_ts_lib_1.Blockchain.bits2Target(bh.bits); | ||
const txParser = new txParserBTC_1.TxParserBTC(coinbaseTx); | ||
const result = txParser.parse(1, 5, this.hash); | ||
(0, scrypt_ts_1.assert)(txParser.isCoinbase(), 'invalid coinbase transaction!'); | ||
const block_height = txParser.readBlockHeight(); | ||
(0, scrypt_ts_1.assert)(block_height > this.block_height, 'invalid block height!'); | ||
(0, scrypt_ts_1.assert)(scrypt_ts_lib_1.Blockchain.txInBlock((0, scrypt_ts_1.Sha256)(result.txId), bh, merkleProof, 32), 'coinbase Tx not in BlockHeader!'); | ||
const new_mining_difficulty = scrypt_ts_lib_1.Blockchain.bits2Target(bh.bits); | ||
// 40_000_000_000_000n | ||
const minimal_mining_difficulty = 673988382275282737328911908618099783400272468464354102n; | ||
(0, scrypt_ts_1.assert)(new_mining_difficulty < minimal_mining_difficulty, 'invalid mining difficulty!'); | ||
this.mining_difficulty = new_mining_difficulty; | ||
this.block_height = block_height; | ||
let outputs = this.buildStateOutputFT(this.supply); | ||
@@ -89,7 +101,7 @@ // Build change output. | ||
} | ||
tx.addOutput(scrypt_ts_1.bsv.Transaction.Output.fromBufferReader(new scrypt_ts_1.bsv.encoding.BufferReader(Buffer.from(scrypt_ord_1.BSV20V2.buildTransferOutput(recipient, (0, scrypt_ts_1.toByteString)(tokenId, true), 1n), 'hex')))); | ||
tx.addOutput(scrypt_ts_1.bsv.Transaction.Output.fromBufferReader(new scrypt_ts_1.bsv.encoding.BufferReader(Buffer.from(scrypt_ord_1.BSV20V2.buildTransferOutput(recipient, (0, scrypt_ts_1.toByteString)(tokenId, true), result.amt), 'hex')))); | ||
tx.change(options.changeAddress || defaultAddress); | ||
return { tx, atInputIndex: 0, nexts }; | ||
} | ||
static async updateMiningDifficultyTxBuilder(current, options, sig, bh) { | ||
static async updateMiningDifficultyTxBuilder(current, options, sig, bh, coinbaseTx) { | ||
const defaultAddress = await current.signer.getDefaultAddress(); | ||
@@ -105,2 +117,5 @@ const tx = new scrypt_ts_1.bsv.Transaction().addInput(current.buildContractInput()); | ||
next.mining_difficulty = scrypt_ts_lib_1.Blockchain.bits2Target(bh.bits); | ||
const txParser = new txParserBTC_1.TxParserBTC(coinbaseTx); | ||
txParser.parse(1, 5, next.hash); | ||
next.block_height = txParser.readBlockHeight(); | ||
tx.addOutput(new scrypt_ts_1.bsv.Transaction.Output({ | ||
@@ -136,2 +151,5 @@ satoshis: 1, | ||
__decorate([ | ||
(0, scrypt_ts_1.prop)(true) | ||
], WrappedBTC.prototype, "block_height", void 0); | ||
__decorate([ | ||
(0, scrypt_ts_1.method)() | ||
@@ -138,0 +156,0 @@ ], WrappedBTC.prototype, "mint", null); |
{ | ||
"name": "dot-bridge-contracts", | ||
"version": "0.1.1", | ||
"version": "0.1.2", | ||
"description": "A demo sCrypt smart contract.", | ||
@@ -5,0 +5,0 @@ "author": "", |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
491068
3304