@mit-dci/opencbdc
v0.0.2
Published
An javascript module for interacting with the opencbdc-tx atomizer and 2pc environments
Downloads
8
Readme
opencbdc-js
This is a pure JS node module which reads and writes the binary transaction packet formats used in opencbdc-tx. It also contains utilities to calculate UHS and transaction hashes from output data.
Getting Started
- Clone the code
$ git clone "https://github.com/mit-dci/opencbdc-js.git"
- Install the necessary dependencies
$ npm install
- Run the test suite
$ npm test
Contributing
Patches are welcome! Please see the OpenCBDC contribution guide for more information!
The following is a breakdown of sections and classes for this cbdc-module:
Crypto
Address
constructor(script_type, pubHex) -
a new Address Object
- script_type - {Number} representing the script type of the address
- pubHex - {String} represents valid 32 byte hexadecimal string
getAddress() - returns {String}
represented the bech32 encoding version of a publickey e.g.
decodeAddress() - returns {Object}
with fields script_type (string representing) and pubHex (hex string of public key)
static decodeFromAddressString(address) - returns
{Object} with fields script_type {Number} and pubHex {String} (hexdecimal string of public key)
Publickey
- constructor(secretKeyData) -
returns a new Publickey object
- secretKeyData -
{String} a valid 32 byte hexadecimal string
- secretKeyData -
- static fromPrivateKeyData(secretKeyData)
- secretKeyData -
{String} a valid 32 byte hexadecimal string
- secretKeyData -
- toBuffer() -
returns {Buffer} 32 byte buffer publickey
- constructor(secretKeyData) -
Secretkey
- contructor(randBytes) -
returns new SecretKey with randBytes provided as random seed (if provided), otherwise it creates random key from random secrety bytes
- randBytes - {Buffer} optional 32 bytes used to seed for privatekey, otherwise another random
- toString() -
returns {String} valid hexadecimal string of privatekey
- toBuffer() -
returns {Buffer} valid 32 byte Buffer for privatekey
- static fromHex(secretKeyHex)-
returns {SecretKey} from secretKeyHex
- secretKeyHex - valid 32 byte hexadecimal string for privateKey
- toHex() -
returns hexadecimal representation of privateKey
- contructor(randBytes) -
Networking
- Networking
- broadcastTx(port, host, signedTxHex) -
broadcast a signedTxBuf to a sentinel server at host {host} and port {port} number
- port - {number} port number of host
- host - {string} hostname url to send signedTx
- signedTxHex - {string} a valid hexadecimal encoded transaction that has been signed
- broadcastTx(port, host, signedTxHex) -
Transaction
- Input
- constructor(tx_hash, index, witnessProgramCommitment, value)
returns new Input Object Type
- tx_hash - {String} valid hexadecimal string for transaction hash this input references
- index - {number} index position of the input for tx
- witnessProgramCommitment {String} - witness commitment for this input
- value {number} - the number of dollar units this input is worth
- writeInputToBuffer() -
returns Buffer representation as buffer type
- getUHSHash() -
returns {Buffer} Universal Hash Set hash of the input e.g. concatentation of [txid, index, witnessProgramCommitment, value] into bytes
e.g. - toString() -
returns {String} representing valid input
- constructor(tx_hash, index, witnessProgramCommitment, value)
Utils
- Utility Methods CBDC module
- sign(secretKey, message) -
returns signature that signed message {message} with privateKey {privateKey}
- secretKey - {String} - 32 byte hexadecimal string
- message - {String} - message that is signed
- verify(publicKey, message, signature)
returns true or false whether the produced signature is validly signed publicKey
- publicKey - 32 byte hexadecimal string
- message - message to verify was signed
- signature - {String} signature to verify validly signed message against public key message pair
- sign(secretKey, message) -
N.B.: A hash is used to identify a specfic UTXO within the monetary supply (the UHS ID); it is a concatenation of a txid, a 64-bit index of the UTXO's position in previous tx's outputs, a witnessProgramCommitment, and the 64-bit encoded value of that output
Output
- constructor(witnessProgramCommitment, value)
returns new Output Object type
- witnessProgramCommitment - {String}
- value - {Number}
- writeOutputToBuffer() -
returns a Buffer representation of this output in raw bytes
- static fromOutputData(pubHex, value) -
returns a new {Output} from publicKey and value provided
- pubHex - {String}
- value - {Number}
- toString() -
returns {String} string representation of Output
- constructor(witnessProgramCommitment, value)
Transaction
- constructor(inputs, outputs, witnesses) -
returns new {Transaction} object
- inputs - Array{Input}
- outputs - Array{Output}
- witnesses - Array of witness object
- toHex() -
returns {String} hexadecimal string of the unsigned raw transaction
- getTxid() -
returns {String} returns hexadecimal string of transaction id (txid)
- sign(secretKey) -
returns {Buffer} signed tx in bytes
- static txFromHex(rawHex) -
returns {Transaction} object from the provided rawTx
- rawHex - valid hexadecimal string represents a valid tx
- constructor(inputs, outputs, witnesses) -
Special Notes
BigInt is used everywhere throughout this module, that may pose problems in using toJson() methods or serializing for output
Example Usage
The following are example code snippets.
Address
const addr = new Address('00', '3ad8f015f9212f8262248af4cf4cc39907d0215fdde14507f8bc09ad5836bbe9') console.log(addr.getAddress()); usd1qqad3uq4lysjlqnzyj90fn6vcwvs05pptlw7z3g8lz7qnt2cx6a7jty6gr5 console.log(addr.decodeAddress()); { script_type: 0, pubHex: '3ad8f015f9212f8262248af4cf4cc39907d0215fdde14507f8bc09ad5836bbe9' }
Publickey
const pub = new Publickey('e00b5c3d80899217a22fea87e7337907203df8a1efebd4d2a8773c8f629fff36') console.log(pub.toBuffer());
Secretkey
const secKey = new SecretKey(Buffer.from(parseInt(Math.round(Math.random() * 10)), 'hex')); secKey.toString(); secKey.toBuffer();
Networking
let network = require('./networking/broadcast'); const txBuf = new Transaction(); Networking.broadcastTx(5555, '127.0.0.1', Buffer.from(tx.toHex(), 'hex'))
Transaction
const input = new Input('9f981e64afc0fc56a0d7b355cd9eba36f3d19507088713b1f73afc5bf301a44e', 0, '70cd87ebaaa0d2d059dccaceeb7f9f823a5791d60b00aef9d9573f1fbf91ca29', 200) const output = new Output('81b095a242974d9f4e98ca18b468b8e644e4168380a035b3d66bc279b36c6510', 200) const tx = new Transaction([input], [output], []); tx.sign('e00b5c3d80899217a22fea87e7337907203df8a1efebd4d2a8773c8f629fff36') console.log(tx.getTxid()); 12e01dfa90358fd203da3acbbe105b1ed2d249cd8e601ed919f4b8b2a99cbb02 console.log(tx); 01000000000000009f981e64afc0fc56a0d7b355cd9eba36f3d19507088713b1f73afc5bf301a44e000000000000000070cd87ebaaa0d2d059dccaceeb7f9f823a5791d60b00aef9d9573f1fbf91ca29c800000000000000010000000000000081b095a242974d9f4e98ca18b468b8e644e4168380a035b3d66bc279b36c6510c80000000000000001000000000000006100000000000000003ad8f015f9212f8262248af4cf4cc39907d0215fdde14507f8bc09ad5836bbe901986cc97272bdb7624a824afcef76936b8f945e55d6e8479b95c81298e77b42d5a255e8529fc2f0d90743e7f9997a7159b6121105c7ec9b9252da992f34611f
Constructing, signing and broacasting tx to sentinel
const secretKey = 'e00b5c3d80899217a22fea87e7337907203df8a1efebd4d2a8773c8f629fff36'; const input = new Input('9f981e64afc0fc56a0d7b355cd9eba36f3d19507088713b1f73afc5bf301a44e', 0, '70cd87ebaaa0d2d059dccaceeb7f9f823a5791d60b00aef9d9573f1fbf91ca29', 200) const output = new Output('81b095a242974d9f4e98ca18b468b8e644e4168380a035b3d66bc279b36c6510', 200) const tx = new Transaction([input], [output], []); tx.sign(secretKey); Networking.broadcastTx(5555, '127.0.0.1', Buffer.from(tx.toHex(), 'hex'))
Signing and Verifying
const secretKey = "e00b5c3d80899217a22fea87e7337907203df8a1efebd4d2a8773c8f629fff36"; const publicKey = "3ad8f015f9212f8262248af4cf4cc39907d0215fdde14507f8bc09ad5836bbe9"; const sha256 = function () {...}; const message = 'onomatopoeia'; const sig = utils.sign(secretKey, message); utils.verify(publicKey, Buffer.from(sha256(message), 'hex'), sig);
Sample Data
Secret and Related Public Key
secret key: e00b5c3d80899217a22fea87e7337907203df8a1efebd4d2a8773c8f629fff36
public key: 3ad8f015f9212f8262248af4cf4cc39907d0215fdde14507f8bc09ad5836bbe9
Signed Transaction
01000000000000009f981e64afc0fc56a0d7b355cd9eba36f3d19507088713b1f73afc5bf301a44e000000000000000070cd87ebaaa0d2d059dccaceeb7f9f823a5791d60b00aef9d9573f1fbf91ca29c800000000000000010000000000000081b095a242974d9f4e98ca18b468b8e644e4168380a035b3d66bc279b36c6510c80000000000000001000000000000006100000000000000003ad8f015f9212f8262248af4cf4cc39907d0215fdde14507f8bc09ad5836bbe901986cc97272bdb7624a824afcef76936b8f945e55d6e8479b95c81298e77b42d5a255e8529fc2f0d90743e7f9997a7159b6121105c7ec9b9252da992f34611f
Signed Transaction Decoded
Tx {
inputs: [
{
tx_hash: '9f981e64afc0fc56a0d7b355cd9eba36f3d19507088713b1f73afc5bf301a44e',
index: 0n,
witness_program_commitment: '70cd87ebaaa0d2d059dccaceeb7f9f823a5791d60b00aef9d9573f1fbf91ca29',
value: 200n
}
],
outputs: [
{
witness_program_commitment: '81b095a242974d9f4e98ca18b468b8e644e4168380a035b3d66bc279b36c6510',
value: 200n
}
],
witnesses: [
{
witness_length: 97n,
script_type: 0,
pubkey: '3ad8f015f9212f8262248af4cf4cc39907d0215fdde14507f8bc09ad5836bbe9',
signature: '01986cc97272bdb7624a824afcef76936b8f945e55d6e8479b95c81298e77b42d5a255e8529fc2f0d90743e7f9997a7159b6121105c7ec9b9252da992f34611f'
}
]
}